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