callgraph/src/main/java/org/netbeans/lib/callgraph/javac/SourcesInfo.java
author Tim Boudreau <tboudreau@netbeans.org>
Sat, 03 Sep 2016 02:41:36 -0400
changeset 18374 04a79821e760
parent 18301 17413f763c78
child 18400 c87c223efe6a
permissions -rw-r--r--
Eliminate duplicates in graph files
     1 /* 
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright (C) 1997-2015 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     9  * The contents of this file are subject to the terms of either the GNU
    10  * General Public License Version 2 only ("GPL") or the Common
    11  * Development and Distribution License("CDDL") (collectively, the
    12  * "License"). You may not use this file except in compliance with the
    13  * License. You can obtain a copy of the License at
    14  * http://www.netbeans.org/cddl-gplv2.html
    15  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    16  * specific language governing permissions and limitations under the
    17  * License.  When distributing the software, include this License Header
    18  * Notice in each file and include the License file at
    19  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    20  * particular file as subject to the "Classpath" exception as provided
    21  * by Oracle in the GPL Version 2 section of the License file that
    22  * accompanied this code. If applicable, add the following below the
    23  * License Header, with the fields enclosed by brackets [] replaced by
    24  * your own identifying information:
    25  * "Portions Copyrighted [year] [name of copyright owner]"
    26  *
    27  * Contributor(s):
    28  *
    29  * The Original Software is NetBeans. The Initial Developer of the Original
    30  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
    31  * Microsystems, Inc. All Rights Reserved.
    32  *
    33  * If you wish your version of this file to be governed by only the CDDL
    34  * or only the GPL Version 2, indicate your decision by adding
    35  * "[Contributor] elects to include this software in this distribution
    36  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    37  * single choice of license, a recipient has the option to distribute
    38  * your version of this file under either the CDDL, the GPL Version 2 or
    39  * to extend the choice of license to its licensees as provided above.
    40  * However, if you add GPL Version 2 code and therefore, elected the GPL
    41  * Version 2 license, then the option applies only if the new code is
    42  * made subject to such option by the copyright holder.
    43  */
    44 
    45 package org.netbeans.lib.callgraph.javac;
    46 
    47 import static org.netbeans.lib.callgraph.javac.UsageFinder.CLASS_TREE_KINDS;
    48 import org.netbeans.lib.callgraph.util.EightBitStrings;
    49 import com.sun.source.tree.ClassTree;
    50 import com.sun.source.tree.ExpressionTree;
    51 import com.sun.source.tree.MethodTree;
    52 import com.sun.source.tree.VariableTree;
    53 import com.sun.source.util.TreePath;
    54 import java.util.ArrayList;
    55 import java.util.HashMap;
    56 import java.util.HashSet;
    57 import java.util.Iterator;
    58 import java.util.List;
    59 import java.util.Map;
    60 import java.util.Set;
    61 import javax.lang.model.element.Element;
    62 
    63 /**
    64  * Container for shared state that is gathered during the parse and discarded
    65  * after.
    66  *
    67  * @author Tim Boudreau
    68  */
    69 public final class SourcesInfo implements AutoCloseable {
    70 
    71     public final Set<SourceElement> allElements = new HashSet<>();
    72     public final Map<Element, SourceElement> elements = new HashMap<>();
    73 
    74     private final Map<ClassTree, List<ClassTree>> inners = new HashMap<>();
    75 
    76     public final EightBitStrings strings;
    77 
    78     public SourcesInfo(boolean eightBitStringsDisabled, boolean aggressive) {
    79         this.strings = new EightBitStrings(eightBitStringsDisabled, aggressive);
    80     }
    81 
    82     // XXX rewrite to not hold references to ClassTree, just names,
    83     // to reduce memory consumption - and verify that that actually
    84     // makes a difference (not sure how much of javac's compile tree
    85     // can be gc'd while the compile is ongoing).  Use something similar
    86     // to NetBeans' ElementHandle.  That might also make it possible to
    87     // restart the compile if memory consumption gets too large, if we
    88     // retain enough bookkeeping here.
    89     TreePath containingClassOf(TreePath path) {
    90         do {
    91             path = path.getParentPath();
    92         } while (path != null && !CLASS_TREE_KINDS.contains(path.getLeaf().getKind()));
    93         return path;
    94     }
    95 
    96     String parametersOf(TreePath path) {
    97         if (path.getLeaf() instanceof MethodTree) {
    98             MethodTree method = (MethodTree) path.getLeaf();
    99             StringBuilder paramsString = new StringBuilder("(");
   100             for (Iterator<? extends VariableTree> it = method.getParameters().iterator(); it.hasNext();) {
   101                 VariableTree variable = it.next();
   102                 paramsString.append(variable.getType().toString());
   103                 if (it.hasNext()) {
   104                     paramsString.append(',');
   105                 }
   106             }
   107             return paramsString.append(")").toString();
   108         } else {
   109             return "";
   110         }
   111     }
   112 
   113     String packageNameOf(TreePath path) {
   114         ExpressionTree pkgName = path.getCompilationUnit().getPackageName();
   115         return pkgName == null ? "<defaultPackage>" : pkgName.toString();
   116     }
   117 
   118     String nameOf(TreePath tree) {
   119         TreePath containingClass = containingClassOf(tree);
   120         ClassTree clazz = (ClassTree) containingClass.getLeaf();
   121         String name = clazz.getSimpleName().toString();
   122         if (name.isEmpty()) {
   123             // Recursively generate $1, $2 names, handling the case of
   124             // mutiple nesting
   125             name = nameOf(containingClass);
   126             TreePath nestedIn = containingClassOf(containingClass);
   127             ClassTree nestingParent = (ClassTree) nestedIn.getLeaf();
   128             List<ClassTree> innerClasses = inners.get(nestingParent);
   129             if (innerClasses == null) {
   130                 innerClasses = new ArrayList<>(3);
   131                 inners.put(nestingParent, innerClasses);
   132             }
   133             innerClasses.add(clazz);
   134             name = name + ".$" + innerClasses.size();
   135         }
   136         return name;
   137     }
   138 
   139     @Override
   140     public void close() {
   141         // Clear references to objects from the parse
   142         inners.clear();
   143         elements.clear();
   144         strings.clear();
   145     }
   146 }