1.1 --- a/callgraph/src/main/java/org/netbeans/lib/callgraph/Callgraph.java Mon Aug 29 13:00:53 2016 -0400
1.2 +++ b/callgraph/src/main/java/org/netbeans/lib/callgraph/Callgraph.java Sat Sep 03 02:41:36 2016 -0400
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 *
1.7 - * Copyright (C) 1997-2015 Oracle and/or its affiliates. All rights reserved.
1.8 + * Copyright (C) 1997-2016 Oracle and/or its affiliates. All rights reserved.
1.9 *
1.10 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
1.11 * Other names may be trademarks of their respective owners.
1.12 @@ -70,10 +70,8 @@
1.13 import java.util.LinkedList;
1.14 import java.util.List;
1.15 import java.util.Set;
1.16 -import java.util.TreeSet;
1.17 import java.util.concurrent.atomic.AtomicReference;
1.18 import java.util.function.Consumer;
1.19 -import org.netbeans.lib.callgraph.util.ComparableCharSequence;
1.20
1.21 /**
1.22 * Scans a source folder and runs javac against any Java sources present, and
1.23 @@ -134,7 +132,7 @@
1.24 * @throws IOException If i/o fails
1.25 */
1.26 static List<SourceElement> invoke(CallgraphControl arguments, Listener listener) throws IOException {
1.27 - SourcesInfo info = new SourcesInfo(arguments.isDisableEightBitStrings());
1.28 + SourcesInfo info = new SourcesInfo(arguments.isDisableEightBitStrings(), arguments.isAggressive());
1.29 // Build an iterable of all Java sources (without collecting them all ahead of time)
1.30 List<Iterable<File>> iterables = new LinkedList<>();
1.31 for (File folder : arguments) {
1.32 @@ -158,8 +156,15 @@
1.33 // duplicate avoidance
1.34 Set<CharSequence> emittedPackageLines = new HashSet<>();
1.35 Set<CharSequence> emittedClassLines = new HashSet<>();
1.36 + List<Object> clazz = new ArrayList<>(5);
1.37 + CharSequence lastClass = null;
1.38 +
1.39 + List<Object> pkg = new ArrayList<>(5);
1.40 + CharSequence lastPackage = null;
1.41 +
1.42 try {
1.43 // Iterate every method
1.44 + outer:
1.45 for (SourceElement sce : all) {
1.46 if (arguments.isExcluded(sce.qname().toString())) { // Ignore matches
1.47 continue;
1.48 @@ -167,7 +172,32 @@
1.49 List<SourceElement> outbounds = new ArrayList<>(arguments.isReverse() ? sce.getInboundReferences() : sce.getOutboundReferences());
1.50 Collections.sort(outbounds); // also sort connections
1.51 // Iterate the current method's connections
1.52 - Set<ComparableCharSequence> mth = new TreeSet<>();
1.53 + List<Object> mth = new ArrayList<>(5);
1.54 + CharSequence currClazz = arguments.isShortNames() ? sce.typeName() : info.strings.concat(sce.packageName(), info.strings.DOT, sce.typeName());
1.55 + if (!currClazz.equals(lastClass)) {
1.56 + if (classStream != null) {
1.57 + writeLine(clazz, info, emittedClassLines, classStream);
1.58 + }
1.59 + clazz.clear();
1.60 + lastClass = currClazz;
1.61 + }
1.62 + if (clazz.isEmpty()) {
1.63 + clazz.add(currClazz);
1.64 + if (arguments.isExtendedProperties()) {
1.65 + clazz.add(sce.isAbstract());
1.66 + }
1.67 + }
1.68 + CharSequence currPkg = sce.packageName();
1.69 + if (pkg.isEmpty()) {
1.70 + pkg.add(currPkg);
1.71 + }
1.72 + if (!currPkg.equals(lastPackage)) {
1.73 + if (packageStream != null) {
1.74 + writeLine(pkg, info, emittedPackageLines, packageStream);
1.75 + }
1.76 + lastPackage = currPkg;
1.77 + pkg.clear();
1.78 + }
1.79 for (SourceElement outbound : outbounds) {
1.80 if (arguments.isExcluded(outbound.qname().toString())) { // Ignore matches
1.81 continue;
1.82 @@ -181,24 +211,20 @@
1.83 if (!arguments.isSelfReferences() && sce.typeName().equals(outbound.typeName())) {
1.84 continue;
1.85 }
1.86 - if (outStream != null) {
1.87 + if (outStream != null || !arguments.isQuiet()) {
1.88 if (arguments.isShortNames()) {
1.89 mth.add(outbound.shortName());
1.90 } else {
1.91 mth.add(outbound.qname());
1.92 }
1.93 + if (arguments.isExtendedProperties()) {
1.94 + mth.add(outbound.isAbstract());
1.95 + }
1.96 }
1.97 // Build the package graph output if necessary
1.98 if (packageStream != null) {
1.99 - CharSequence pkg1 = sce.packageName();
1.100 - CharSequence pkg2 = outbound.packageName();
1.101 - if (!pkg1.equals(pkg2)) {
1.102 -// CharSequence pkgLine = '"' + pkg1.toString() + "\" \"" + pkg2.toString() + '"';
1.103 - CharSequence pkgLine = info.strings.concat(info.strings.QUOTE, pkg1, info.strings.CLOSE_OPEN_QUOTE, pkg2, info.strings.QUOTE);
1.104 - if (!emittedPackageLines.contains(pkgLine)) {
1.105 - emittedPackageLines.add(pkgLine);
1.106 - packageStream.println(pkgLine);
1.107 - }
1.108 + if (!outbound.packageName().equals(currPkg) || arguments.isSelfReferences()) {
1.109 + pkg.add(outbound.packageName());
1.110 }
1.111 }
1.112 // Build the class graph output if necessary
1.113 @@ -206,22 +232,24 @@
1.114 CharSequence type1 = sce.typeName();
1.115 CharSequence type2 = outbound.typeName();
1.116 if (!arguments.isShortNames()) {
1.117 - type1 = info.strings.concat(sce.packageName(), info.strings.DOT, type1);
1.118 +// type1 = info.strings.concat(sce.packageName(), info.strings.DOT, type1);
1.119 type2 = info.strings.concat(outbound.packageName(), info.strings.DOT, type2);
1.120 }
1.121 - if (!type1.equals(type2)) {
1.122 - CharSequence classLine = info.strings.concat(info.strings.QUOTE, type1, info.strings.CLOSE_OPEN_QUOTE, type2, info.strings.QUOTE);
1.123 - if (!emittedClassLines.contains(classLine)) {
1.124 - emittedClassLines.add(classLine);
1.125 - classStream.println(classLine);
1.126 + if (!type1.equals(type2) && !clazz.contains(type2)) {
1.127 + clazz.add(type2);
1.128 + if (arguments.isExtendedProperties()) {
1.129 + clazz.add(outbound.isAbstract());
1.130 }
1.131 }
1.132 }
1.133 }
1.134 - if ((!arguments.isQuiet() || outStream != null)) {
1.135 + if (!arguments.isQuiet() || outStream != null) {
1.136 if (!mth.isEmpty()) {
1.137 CharSequence nm = arguments.isShortNames() ? sce.shortName() : sce.qname();
1.138 - List<CharSequence> l = new ArrayList<>(mth);
1.139 + List<Object> l = mth;
1.140 + if (arguments.isExtendedProperties()) {
1.141 + mth.add(0, sce.isAbstract());
1.142 + }
1.143 l.add(0, nm);
1.144 CharSequence line = info.strings.concatQuoted(l);
1.145 if (!arguments.isQuiet()) {
1.146 @@ -233,6 +261,12 @@
1.147 }
1.148 }
1.149 }
1.150 + if (classStream != null && !clazz.isEmpty()) {
1.151 + writeLine(clazz, info, emittedClassLines, classStream);
1.152 + }
1.153 + if (packageStream != null && !pkg.isEmpty()) {
1.154 + writeLine(pkg, info, emittedPackageLines, packageStream);
1.155 + }
1.156 } finally {
1.157 for (PrintStream ps : new PrintStream[]{outStream, packageStream, classStream}) {
1.158 if (ps != null) {
1.159 @@ -243,6 +277,15 @@
1.160 }
1.161 return all;
1.162 }
1.163 + private static void writeLine(List<Object> clazz, SourcesInfo info, Set<CharSequence> emittedClassLines, PrintStream classStream) {
1.164 + if (!clazz.isEmpty()) {
1.165 + CharSequence cs = info.strings.concatQuoted(clazz);
1.166 + if (!emittedClassLines.contains(cs)) {
1.167 + classStream.println(cs);
1.168 + emittedClassLines.add(cs);
1.169 + }
1.170 + }
1.171 + }
1.172
1.173 private static PrintStream createPrintStreamIfNotNull(File outputFile) throws IOException {
1.174 PrintStream outStream = null;