Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2012 Martin Skurla
   *
   * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
   * the License. You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
 package org.crazyjavahacking.astvisualizer.impl.javac;
 
 
 import java.io.File;
 import java.io.Reader;
 import java.util.List;
 
 
 import  org.jgrapht.DirectedGraph;
 
Javac JDK 7 implementation of ASTParser.

Author(s):
Martin
 
 public final class Javac7ASTParser implements ASTParser {
 
     //-----------------------------------------------------------------------------------------------------------------
     // Public Methods.
     //-----------------------------------------------------------------------------------------------------------------
     
 
     @Override
     public DirectedGraph<NodeModelEdgeModelparse(File javaSourceFile) {
         String simpleClassName = FileUtils.extractNameWithoutExtension(javaSourceFile);
 
         try {
             return parse(new FileReader(javaSourceFile), simpleClassName);
         }
         catch (FileNotFoundException e) {
             throw new ASTParsingException(e);
         }
     }

    
 
     @Override
     public DirectedGraph<NodeModelEdgeModelparse(Reader javaSourceFileReaderString simpleClassName) {
         try {
             JavaFileObject javaFileObjectContainingSyntacticSugar =
                     JavaFileObjectUtils.fromReader(javaSourceFileReader,
                                                    simpleClassName);
 
             JavacTreePathScanner javacTreePathScanner = new JavacTreePathScanner();
 
             JavaCompiler.CompilationTask compilationTask =
                     JavaCompilerUtils.getCompilationTaskFromJavaFileObject(javaFileObjectContainingSyntacticSugar);
 
             CompilationUnitTree compilationUnitTree = JavaCompilerUtils.compile(compilationTask);
 
             return javacTreePathScanner.doScanning(compilationTaskcompilationUnitTree);
        }
        catch (Exception e) {
            throw new ASTParsingException(e);
        }
    }

    
    @Override
    public String compilerName() {
        return "javac";
    }

    
    @Override
    public String compilerVersion() {
        return "1.7";
    }
    //-----------------------------------------------------------------------------------------------------------------
    // Inner classes.
    //-----------------------------------------------------------------------------------------------------------------
    
Javac tree path scanner.
    private static final class JavacTreePathScanner extends TreePathScanner<IntegerVoid> {
        //-------------------------------------------------------------------------------------------------------------
        // Constants.
        //-------------------------------------------------------------------------------------------------------------
        private static final String CONSTRUCTOR_METHOD_NAME = "<init>";
        //-------------------------------------------------------------------------------------------------------------
        // Members.
        //-------------------------------------------------------------------------------------------------------------
        private final LinkedList<NodeModelnodeModelStack = new LinkedList<NodeModel>();
        private final LinkedList<IEdgeDataedgeDataStack  = new LinkedList<IEdgeData>();
        private final CustomizedAST customizedAST = new CustomizedAST();
        private SourcePositionHelper sourcePositionHelper = null;
        private String lastSimpleClassName = null;
        //-------------------------------------------------------------------------------------------------------------
        // Private Helpers.
        //-------------------------------------------------------------------------------------------------------------
        
Starts scanning of given compilation unit tree as part of given compilation task.

Parameters:
compilationTask compilation task
compilationUnitTree compilation unit tree
Returns:
customized AST
Throws:
IllegalStateException if either of nodeModelStack or edgeDataStack are empty
        private DirectedGraph<NodeModelEdgeModeldoScanning(JavaCompiler.CompilationTask compilationTask,
                CompilationUnitTree compilationUnitTree) {
            Trees trees = Trees.instance(compilationTask);
             = new SourcePositionHelper(treescompilationUnitTree);
            scan(compilationUnitTree, (Voidnull);
            connectRemainingNodes();
            if (!.isEmpty()) {
                throw new IllegalStateException("Node model stack is not empty ! : " + );
            }
            if (!.isEmpty()) {
                throw new IllegalStateException("Edge data stack is not empty ! : " + );
            }
            return .toDirectedGraph();
        }

        
        @Override
        public Integer scan(Tree treeVoid p) {
            if (tree != null) {
                if (tree.getKind() == ..) {
                     = ((ClassTreetree).getSimpleName().toString();
                }
                processTreeAndAddToCustomizedAST(tree);
            }
            return super.scan(treep);
        }

        
Processes given Tree instance and adds it to customized AST.

Parameters:
treeNode tree node
        private void processTreeAndAddToCustomizedAST(Tree treeNode) {
            if (treeNode.getKind() != ..) {
                processSpecialElements();
            }
            // !!! special treatment of empty ModifiersTree (without flags and annotations)
            // -> this tree will not be added even if it is part of the AST produced by javac
            if (treeNode.getKind() == ..) {
                ModifiersTree modifiersTree = (ModifiersTreetreeNode;
                if (!ModifiersTreeHelper.hasFlagsOrAnnotations(modifiersTree)) {
                    return;
                }
            }
            addNodeAndEdgeToCustomizedAST(treeNode);
        }

        
Processes special elements:
  • javax.lang.model.element.Name
  • javax.lang.model.element.Modifier
  • javax.lang.model.type.TypeKind
        private void processSpecialElements() {
            IEdgeData topEdgeIdentity = .peek();
            if (topEdgeIdentity == null) {
                // no more data to process
                return;
            }
            if (topEdgeIdentity instanceof IComSunSourceTreeTreeEdgeData) {
                // com.sun.source.tree.Tree is not special element
                return;
            }
            NodeModel nodeModel = nodeModelFromSpecialElement(topEdgeIdentity);
            .addNode(nodeModel);
            String transitionName = .pop().getTransitionName();
            EdgeModel edge = EdgeModelFactory.fromTransitionName(transitionName);
            .addEdge(.pop(), // edge source
                                  nodeModel,            // edge target
                                  edge);
            processSpecialElements(); // recursion...
        }

        
Creates NodeModel from special element.

Parameters:
iEdgeData IEdgeData
Returns:
NodeModel
See also:
org.crazyjavahacking.astvisualizer.impl.javac.Javac7ASTParser.JavacTreePathScanner.processSpecialElements() processSpecialElements()
        private NodeModel nodeModelFromSpecialElement(IEdgeData iEdgeData) {
            int currentDepth = .peek().getDepth() + 1;
            int nodeCounter = .getNumberOfNodes() + 1;
            NodeModel nodeModel;
            if (iEdgeData instanceof IJavaxLangModelElementNameEdgeData) {
                Name name = ((IJavaxLangModelElementNameEdgeDataiEdgeData).getName();
                String textRepresentation = name.toString();
                if (textRepresentation.equals()) {
                    textRepresentation = ;
                }
                nodeModel = NodeModelFactory.fromJavaxLangModelElementName(
                                                        currentDepth,
                                                        nodeCounter,
                                                        name,
                                                        .determinePositionFromText(textRepresentation));
            }
            else if (iEdgeData instanceof IJavaxLangModelElementModifierEdgeData) {
                Modifier modifier = ((IJavaxLangModelElementModifierEdgeDataiEdgeData).getModifier();
                nodeModel = NodeModelFactory.fromJavaxLangModelElementModifier(
                                                    currentDepth,
                                                    nodeCounter,
                                                    modifier,
                                                    .determinePositionFromText(modifier.toString()));
            }
            else if (iEdgeData instanceof IJavaxLangModelTypeTypeKindEdgeData) {
                TypeKind typeKind = ((IJavaxLangModelTypeTypeKindEdgeDataiEdgeData).getTypeKind();
                nodeModel = NodeModelFactory.fromJavaxLangModelTypeTypeKind(
                                                    currentDepth,
                                                    nodeCounter,
                                                    typeKind,
                                                    .determinePositionFromText(typeKind.toString()
                                                                                                       .toLowerCase()));
            }
            else {
                throw new IllegalArgumentException(
                        "Given IEdgeData implementation is not special element! : " + iEdgeData.getClass());
            }
            return nodeModel;
        }

        
Adds node and edge to customzed AST.

Parameters:
treeNode tree node
        private void addNodeAndEdgeToCustomizedAST(Tree treeNode) {
            int currentDepth =
                    (treeNode.getKind() == ..) ? 0
                                                                         : .peek().getDepth() + 1;
            int nodeCounter = .getNumberOfNodes() + 1;
            PositionWithinSourceCode positionWithinSourceCode =
                    .determinePositionFromTree(treeNode);
            String textRepresentation = .determineTextFromPosition(positionWithinSourceCode);
            Element element = .determineElementFromTree(treeNode);
            NodeModel nodeModel = NodeModelFactory.fromComSourceSunTreeTree(currentDepth,
                                                                            nodeCounter,
                                                                            textRepresentation,
                                                                            treeNode,
                                                                            element,
                                                                            positionWithinSourceCode);
            .addNode(nodeModel);
            if (treeNode.getKind() != ..) {
                if (!.isEmpty()) {
                    String transitionName = .pop().getTransitionName();
                    EdgeModel edge = EdgeModelFactory.fromTransitionName(transitionName);
                    .addEdge(.pop(), // edge source
                                          nodeModel,            // edge target
                                          edge);
                }
            }
            fillNodeModelAndEdgeDataStacks(treeNodenodeModel);
        }

        
Fills node model and edge data stacks.

Parameters:
treeNode tree node
nodeModel node model
        private void fillNodeModelAndEdgeDataStacks(Tree treeNodeNodeModel nodeModel) {
            @SuppressWarnings("unchecked")
            Class<? extends JCTreetreeNodeType = (Class<? extends JCTree>) (Class<?>) treeNode.getClass();
            TreeTypeEnum treeType = TreeTypeEnum.getByClass(treeNodeType);
            List<IEdgeDataedgeDatas = treeType.getEdgeData(treeNode);
            for (int count = 0; count < edgeDatas.size(); count++) {
                .push(nodeModel); // order does not matter, all objects are in fact the same
            }
            List<IEdgeDataedgeDataReversedList = CollectionUtils.reverseListOrder(edgeDatas);
            for (IEdgeData edgeData : edgeDataReversedList) {
                .push(edgeData); // order matter, it is stack, so first collection was reversed
            }
        }

        
Connects remaining nodes.
        private void connectRemainingNodes() {
            if (.isEmpty() && .isEmpty()) {
                // nothing to connect
                return;
            }
            processSpecialElements();
            if (.isEmpty() && .isEmpty()) {
                // nothing to connect - all remaning nodes + edges were connected as part of processSpecialElemenets()
                // method call
                return;
            }
            IEdgeData topEdgeIdentity = .peek();
            if (topEdgeIdentity == null) {
                // no more data to process
                return;
            }
            if (topEdgeIdentity instanceof IComSunSourceTreeTreeEdgeData) {
                throw new AssertionError();
            }
            NodeModel nodeModel = nodeModelFromSpecialElement(topEdgeIdentity);
            .addNode(nodeModel);
            if (!.isEmpty()) {
                String transitionName = .pop().getTransitionName();
                EdgeModel upperEdge = EdgeModelFactory.fromTransitionName(transitionName);
                .addEdge(.pop(), // edge source
                                      nodeModel,            // edge target
                                      upperEdge);
            }
            if (!.isEmpty() && !.isEmpty()) {
                connectRemainingNodes(); // recursion
            }
        }
    }

    
Source positions helper.
    private static final class SourcePositionHelper {
        //-------------------------------------------------------------------------------------------------------------
        // Members.
        //-------------------------------------------------------------------------------------------------------------
        private final Trees trees;
        private final CompilationUnitTree compilationUnitTree;
        private final SourcePositions sourcePositions;
        private final CustomizedAST customizedAST;
        private final String wholeSourceText;
//        boolean fake = false;
        //-------------------------------------------------------------------------------------------------------------
        // Costructors.
        //-------------------------------------------------------------------------------------------------------------
        private SourcePositionHelper(Trees treesCompilationUnitTree compilationUnitTree,
                CustomizedAST customizedAST) {
            this. = trees;
            this. = compilationUnitTree;
            this. = trees.getSourcePositions();
            this. = customizedAST;
            this. = compilationUnitTree.toString();
        }
        //-------------------------------------------------------------------------------------------------------------
        // Private Helpers.
        //-------------------------------------------------------------------------------------------------------------
        
Determines source position from given tree.

Parameters:
tree source tree
Returns:
tree source position
        private PositionWithinSourceCode determinePositionFromTree(Tree treeString lastSimpleClassName) {
//TODO reimplement
//            long startSourcePosition = sourcePositions.getStartPosition(compilationUnitTree, tree);
//            long endSourcePosition = -100;
//
//            if (tree.getKind() == Tree.Kind.METHOD) {
//                if (((MethodTree) tree).getName().toString().equals("<init>")) {
////                    int classNameLength = lastSimpleClassName.length() - 6; // 6 for <init>
//
//                    startSourcePosition = 0;
//                    endSourcePosition = 0;//startSourcePosition + lastSimpleClassName.length();
//
//                    fake = true;
//                }
//            }
//            else {
//                endSourcePosition = sourcePositions.getEndPosition(compilationUnitTree, tree);
//            }
//
//            if (fake) {
                return new PositionWithinSourceCode(0L, 0L);
//            }
//
//            return new PositionWithinSourceCode(startSourcePosition, // inclusive
//                                                endSourcePosition);  // exclusive
        }

        
Determines source position from given text according to last added node to Customized AST.

Parameters:
text text
Returns:
text source position
            int fromIndexIncluding;
            NodeModel previousNodeModel = .getLastAddedNode();
            if (previousNodeModel.isLeaf()) {
                // |+1| is needed because there could be special case of parsing "private e" and e must not be found as
                //      part of the "private"
                fromIndexIncluding = (intpreviousNodeModel.getPositionWithinSourceCode().getEnd() + 1;
            }
            else {
                fromIndexIncluding = (intpreviousNodeModel.getPositionWithinSourceCode().getStart();
            }
            long startPosition = .indexOf(text,
                                                         fromIndexIncluding); // inclusive
            long endPosition = startPosition + text.length();                 // exclusive
            return new PositionWithinSourceCode(startPositionendPosition);
        }
        private String determineTextFromPosition(PositionWithinSourceCode sourcePosition) {
            return .substring((intsourcePosition.getStart(),
                                             (intsourcePosition.getEnd());
        }
        private Element determineElementFromTree(Tree tree) {
            TreePath treePath = .getPath(tree);
            return treePath == null ? null
                                    : .getElement(treePath);
        }
    }
New to GrepCode? Check out our FAQ X