callgraph/src/main/java/org/netbeans/lib/callgraph/Callgraph.java
changeset 18374 04a79821e760
parent 18373 3527a32a19f0
child 18400 c87c223efe6a
     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;