langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
changeset 26267 4ebd9393b373
parent 25874 83c19f00452c
child 26663 f2d8845a9bb2
equal deleted inserted replaced
26266:2d24bda701dc 26267:4ebd9393b373
    40 import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph;
    40 import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph;
    41 import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
    41 import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
    42 import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
    42 import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
    43 import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
    43 import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
    44 
    44 
       
    45 import java.io.File;
       
    46 import java.io.FileWriter;
       
    47 import java.io.IOException;
    45 import java.util.ArrayList;
    48 import java.util.ArrayList;
    46 import java.util.Collection;
    49 import java.util.Collection;
    47 import java.util.Collections;
    50 import java.util.Collections;
    48 import java.util.EnumMap;
    51 import java.util.EnumMap;
    49 import java.util.EnumSet;
    52 import java.util.EnumSet;
    74     Log log;
    77     Log log;
    75 
    78 
    76     /** should the graph solver be used? */
    79     /** should the graph solver be used? */
    77     boolean allowGraphInference;
    80     boolean allowGraphInference;
    78 
    81 
       
    82     /**
       
    83      * folder in which the inference dependency graphs should be written.
       
    84      */
       
    85     final private String dependenciesFolder;
       
    86 
       
    87     /**
       
    88      * List of graphs awaiting to be dumped to a file.
       
    89      */
       
    90     private List<String> pendingGraphs;
       
    91 
    79     public static Infer instance(Context context) {
    92     public static Infer instance(Context context) {
    80         Infer instance = context.get(inferKey);
    93         Infer instance = context.get(inferKey);
    81         if (instance == null)
    94         if (instance == null)
    82             instance = new Infer(context);
    95             instance = new Infer(context);
    83         return instance;
    96         return instance;
    94         log = Log.instance(context);
   107         log = Log.instance(context);
    95         inferenceException = new InferenceException(diags);
   108         inferenceException = new InferenceException(diags);
    96         Options options = Options.instance(context);
   109         Options options = Options.instance(context);
    97         allowGraphInference = Source.instance(context).allowGraphInference()
   110         allowGraphInference = Source.instance(context).allowGraphInference()
    98                 && options.isUnset("useLegacyInference");
   111                 && options.isUnset("useLegacyInference");
       
   112         dependenciesFolder = options.get("dumpInferenceGraphsTo");
       
   113         pendingGraphs = List.nil();
    99     }
   114     }
   100 
   115 
   101     /** A value for prototypes that admit any type, including polymorphic ones. */
   116     /** A value for prototypes that admit any type, including polymorphic ones. */
   102     public static final Type anyPoly = new JCNoType();
   117     public static final Type anyPoly = new JCNoType();
   103 
   118 
   216                 /* if the is no result info then we can clear the capture types
   231                 /* if the is no result info then we can clear the capture types
   217                  * cache without affecting any result info check
   232                  * cache without affecting any result info check
   218                  */
   233                  */
   219                 inferenceContext.captureTypeCache.clear();
   234                 inferenceContext.captureTypeCache.clear();
   220             }
   235             }
       
   236             dumpGraphsIfNeeded(env.tree, msym, resolveContext);
       
   237         }
       
   238     }
       
   239 
       
   240     private void dumpGraphsIfNeeded(DiagnosticPosition pos, Symbol msym, Resolve.MethodResolutionContext rsContext) {
       
   241         int round = 0;
       
   242         try {
       
   243             for (String graph : pendingGraphs.reverse()) {
       
   244                 Assert.checkNonNull(dependenciesFolder);
       
   245                 Name name = msym.name == msym.name.table.names.init ?
       
   246                         msym.owner.name : msym.name;
       
   247                 String filename = String.format("%s@%s[mode=%s,step=%s]_%d.dot",
       
   248                         name,
       
   249                         pos.getStartPosition(),
       
   250                         rsContext.attrMode(),
       
   251                         rsContext.step,
       
   252                         round);
       
   253                 File dotFile = new File(dependenciesFolder, filename);
       
   254                 try (FileWriter fw = new FileWriter(dotFile)) {
       
   255                     fw.append(graph);
       
   256                 }
       
   257                 round++;
       
   258             }
       
   259         } catch (IOException ex) {
       
   260             Assert.error("Error occurred when dumping inference graph: " + ex.getMessage());
       
   261         } finally {
       
   262             pendingGraphs = List.nil();
   221         }
   263         }
   222     }
   264     }
   223 
   265 
   224     /**
   266     /**
   225      * Generate constraints from the generic method's return type. If the method
   267      * Generate constraints from the generic method's return type. If the method
  1638          */
  1680          */
  1639         void solve(GraphStrategy sstrategy) {
  1681         void solve(GraphStrategy sstrategy) {
  1640             checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
  1682             checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
  1641             InferenceGraph inferenceGraph = new InferenceGraph(stuckDeps);
  1683             InferenceGraph inferenceGraph = new InferenceGraph(stuckDeps);
  1642             while (!sstrategy.done()) {
  1684             while (!sstrategy.done()) {
       
  1685                 if (dependenciesFolder != null) {
       
  1686                     //add this graph to the pending queue
       
  1687                     pendingGraphs = pendingGraphs.prepend(inferenceGraph.toDot());
       
  1688                 }
  1643                 InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
  1689                 InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
  1644                 List<Type> varsToSolve = List.from(nodeToSolve.data);
  1690                 List<Type> varsToSolve = List.from(nodeToSolve.data);
  1645                 List<Type> saved_undet = inferenceContext.save();
  1691                 List<Type> saved_undet = inferenceContext.save();
  1646                 try {
  1692                 try {
  1647                     //repeat until all variables are solved
  1693                     //repeat until all variables are solved
  1833                 }
  1879                 }
  1834 
  1880 
  1835                 @Override
  1881                 @Override
  1836                 public Properties nodeAttributes() {
  1882                 public Properties nodeAttributes() {
  1837                     Properties p = new Properties();
  1883                     Properties p = new Properties();
  1838                     p.put("label", toString());
  1884                     p.put("label", "\"" + toString() + "\"");
  1839                     return p;
  1885                     return p;
  1840                 }
  1886                 }
  1841 
  1887 
  1842                 @Override
  1888                 @Override
  1843                 public Properties dependencyAttributes(Node sink, GraphUtils.DependencyKind dk) {
  1889                 public Properties dependencyAttributes(Node sink, GraphUtils.DependencyKind dk) {
  1855                                     buf.append(bound);
  1901                                     buf.append(bound);
  1856                                     sep = ",";
  1902                                     sep = ",";
  1857                                 }
  1903                                 }
  1858                             }
  1904                             }
  1859                         }
  1905                         }
  1860                         p.put("label", buf.toString());
  1906                         p.put("label", "\"" + buf.toString() + "\"");
  1861                     }
  1907                     }
  1862                     return p;
  1908                     return p;
  1863                 }
  1909                 }
  1864             }
  1910             }
  1865 
  1911