langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
changeset 10816 ce8a7e9d8882
parent 10812 7341374e12e8
child 10950 e87b50888909
equal deleted inserted replaced
10815:a719aa5f1631 10816:ce8a7e9d8882
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.javac.comp;
    26 package com.sun.tools.javac.comp;
    27 
    27 
    28 import com.sun.tools.javac.util.*;
    28 import com.sun.tools.javac.api.Formattable.LocalizedString;
    29 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
       
    30 import com.sun.tools.javac.code.*;
    29 import com.sun.tools.javac.code.*;
       
    30 import com.sun.tools.javac.code.Type.*;
       
    31 import com.sun.tools.javac.code.Symbol.*;
    31 import com.sun.tools.javac.jvm.*;
    32 import com.sun.tools.javac.jvm.*;
    32 import com.sun.tools.javac.tree.*;
    33 import com.sun.tools.javac.tree.*;
    33 import com.sun.tools.javac.api.Formattable.LocalizedString;
       
    34 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
       
    35 
       
    36 import com.sun.tools.javac.code.Type.*;
       
    37 import com.sun.tools.javac.code.Symbol.*;
       
    38 import com.sun.tools.javac.tree.JCTree.*;
    34 import com.sun.tools.javac.tree.JCTree.*;
       
    35 import com.sun.tools.javac.util.*;
       
    36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
       
    37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
       
    38 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
       
    39 
       
    40 import java.util.Arrays;
       
    41 import java.util.Collection;
       
    42 import java.util.EnumSet;
       
    43 import java.util.HashMap;
       
    44 import java.util.HashSet;
       
    45 import java.util.LinkedHashMap;
       
    46 import java.util.Map;
       
    47 import java.util.Set;
       
    48 
       
    49 import javax.lang.model.element.ElementVisitor;
    39 
    50 
    40 import static com.sun.tools.javac.code.Flags.*;
    51 import static com.sun.tools.javac.code.Flags.*;
    41 import static com.sun.tools.javac.code.Kinds.*;
    52 import static com.sun.tools.javac.code.Kinds.*;
    42 import static com.sun.tools.javac.code.TypeTags.*;
    53 import static com.sun.tools.javac.code.TypeTags.*;
    43 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
    54 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
    44 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
       
    45 import javax.lang.model.element.ElementVisitor;
       
    46 
       
    47 import java.util.Map;
       
    48 import java.util.Set;
       
    49 import java.util.HashMap;
       
    50 import java.util.HashSet;
       
    51 
    55 
    52 /** Helper class for name resolution, used mostly by the attribution phase.
    56 /** Helper class for name resolution, used mostly by the attribution phase.
    53  *
    57  *
    54  *  <p><b>This is NOT part of any supported API.
    58  *  <p><b>This is NOT part of any supported API.
    55  *  If you write code that depends on this, you do so at your own risk.
    59  *  If you write code that depends on this, you do so at your own risk.
    71     JCDiagnostic.Factory diags;
    75     JCDiagnostic.Factory diags;
    72     public final boolean boxingEnabled; // = source.allowBoxing();
    76     public final boolean boxingEnabled; // = source.allowBoxing();
    73     public final boolean varargsEnabled; // = source.allowVarargs();
    77     public final boolean varargsEnabled; // = source.allowVarargs();
    74     public final boolean allowMethodHandles;
    78     public final boolean allowMethodHandles;
    75     private final boolean debugResolve;
    79     private final boolean debugResolve;
       
    80     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
    76 
    81 
    77     Scope polymorphicSignatureScope;
    82     Scope polymorphicSignatureScope;
       
    83 
       
    84     enum VerboseResolutionMode {
       
    85         SUCCESS("success"),
       
    86         FAILURE("failure"),
       
    87         APPLICABLE("applicable"),
       
    88         INAPPLICABLE("inapplicable"),
       
    89         DEFERRED_INST("deferred-inference"),
       
    90         PREDEF("predef"),
       
    91         OBJECT_INIT("object-init"),
       
    92         INTERNAL("internal");
       
    93 
       
    94         String opt;
       
    95 
       
    96         private VerboseResolutionMode(String opt) {
       
    97             this.opt = opt;
       
    98         }
       
    99 
       
   100         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
       
   101             String s = opts.get("verboseResolution");
       
   102             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
       
   103             if (s == null) return res;
       
   104             if (s.contains("all")) {
       
   105                 res = EnumSet.allOf(VerboseResolutionMode.class);
       
   106             }
       
   107             Collection<String> args = Arrays.asList(s.split(","));
       
   108             for (VerboseResolutionMode mode : values()) {
       
   109                 if (args.contains(mode.opt)) {
       
   110                     res.add(mode);
       
   111                 } else if (args.contains("-" + mode.opt)) {
       
   112                     res.remove(mode);
       
   113                 }
       
   114             }
       
   115             return res;
       
   116         }
       
   117     }
    78 
   118 
    79     public static Resolve instance(Context context) {
   119     public static Resolve instance(Context context) {
    80         Resolve instance = context.get(resolveKey);
   120         Resolve instance = context.get(resolveKey);
    81         if (instance == null)
   121         if (instance == null)
    82             instance = new Resolve(context);
   122             instance = new Resolve(context);
   109         Source source = Source.instance(context);
   149         Source source = Source.instance(context);
   110         boxingEnabled = source.allowBoxing();
   150         boxingEnabled = source.allowBoxing();
   111         varargsEnabled = source.allowVarargs();
   151         varargsEnabled = source.allowVarargs();
   112         Options options = Options.instance(context);
   152         Options options = Options.instance(context);
   113         debugResolve = options.isSet("debugresolve");
   153         debugResolve = options.isSet("debugresolve");
       
   154         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
   114         Target target = Target.instance(context);
   155         Target target = Target.instance(context);
   115         allowMethodHandles = target.hasMethodHandles();
   156         allowMethodHandles = target.hasMethodHandles();
   116         polymorphicSignatureScope = new Scope(syms.noSymbol);
   157         polymorphicSignatureScope = new Scope(syms.noSymbol);
   117 
   158 
   118         inapplicableMethodException = new InapplicableMethodException(diags);
   159         inapplicableMethodException = new InapplicableMethodException(diags);
   682                       boolean operator) {
   723                       boolean operator) {
   683         if (sym.kind == ERR) return bestSoFar;
   724         if (sym.kind == ERR) return bestSoFar;
   684         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
   725         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
   685         Assert.check(sym.kind < AMBIGUOUS);
   726         Assert.check(sym.kind < AMBIGUOUS);
   686         try {
   727         try {
   687             rawInstantiate(env, site, sym, argtypes, typeargtypes,
   728             Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
   688                                allowBoxing, useVarargs, Warner.noWarnings);
   729                                allowBoxing, useVarargs, Warner.noWarnings);
       
   730             if (!operator) addVerboseApplicableCandidateDiag(sym ,mt);
   689         } catch (InapplicableMethodException ex) {
   731         } catch (InapplicableMethodException ex) {
       
   732             if (!operator) addVerboseInapplicableCandidateDiag(sym, ex.getDiagnostic());
   690             switch (bestSoFar.kind) {
   733             switch (bestSoFar.kind) {
   691             case ABSENT_MTH:
   734             case ABSENT_MTH:
   692                 return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
   735                 return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
   693             case WRONG_MTH:
   736             case WRONG_MTH:
   694                 if (operator) return bestSoFar;
   737                 if (operator) return bestSoFar;
   707         return (bestSoFar.kind > AMBIGUOUS)
   750         return (bestSoFar.kind > AMBIGUOUS)
   708             ? sym
   751             ? sym
   709             : mostSpecific(sym, bestSoFar, env, site,
   752             : mostSpecific(sym, bestSoFar, env, site,
   710                            allowBoxing && operator, useVarargs);
   753                            allowBoxing && operator, useVarargs);
   711     }
   754     }
       
   755     //where
       
   756         void addVerboseApplicableCandidateDiag(Symbol sym, Type inst) {
       
   757             if (!verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE))
       
   758                 return;
       
   759 
       
   760             JCDiagnostic subDiag = null;
       
   761             if (inst.getReturnType().tag == FORALL) {
       
   762                 Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
       
   763                                                                 ((ForAll)inst.getReturnType()).qtype);
       
   764                 subDiag = diags.fragment("partial.inst.sig", diagType);
       
   765             } else if (sym.type.tag == FORALL) {
       
   766                 subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
       
   767             }
       
   768 
       
   769             String key = subDiag == null ?
       
   770                     "applicable.method.found" :
       
   771                     "applicable.method.found.1";
       
   772 
       
   773             verboseResolutionCandidateDiags.put(sym,
       
   774                     diags.fragment(key, verboseResolutionCandidateDiags.size(), sym, subDiag));
       
   775         }
       
   776 
       
   777         void addVerboseInapplicableCandidateDiag(Symbol sym, JCDiagnostic subDiag) {
       
   778             if (!verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))
       
   779                 return;
       
   780             verboseResolutionCandidateDiags.put(sym,
       
   781                     diags.fragment("not.applicable.method.found", verboseResolutionCandidateDiags.size(), sym, subDiag));
       
   782         }
   712 
   783 
   713     /* Return the most specific of the two methods for a call,
   784     /* Return the most specific of the two methods for a call,
   714      *  given that both are accessible and applicable.
   785      *  given that both are accessible and applicable.
   715      *  @param m1               A new candidate for most specific.
   786      *  @param m1               A new candidate for most specific.
   716      *  @param m2               The previous most specific candidate.
   787      *  @param m2               The previous most specific candidate.
   904                       List<Type> argtypes,
   975                       List<Type> argtypes,
   905                       List<Type> typeargtypes,
   976                       List<Type> typeargtypes,
   906                       boolean allowBoxing,
   977                       boolean allowBoxing,
   907                       boolean useVarargs,
   978                       boolean useVarargs,
   908                       boolean operator) {
   979                       boolean operator) {
       
   980         verboseResolutionCandidateDiags.clear();
   909         Symbol bestSoFar = methodNotFound;
   981         Symbol bestSoFar = methodNotFound;
   910         return findMethod(env,
   982         bestSoFar = findMethod(env,
   911                           site,
   983                           site,
   912                           name,
   984                           name,
   913                           argtypes,
   985                           argtypes,
   914                           typeargtypes,
   986                           typeargtypes,
   915                           site.tsym.type,
   987                           site.tsym.type,
   917                           bestSoFar,
   989                           bestSoFar,
   918                           allowBoxing,
   990                           allowBoxing,
   919                           useVarargs,
   991                           useVarargs,
   920                           operator,
   992                           operator,
   921                           new HashSet<TypeSymbol>());
   993                           new HashSet<TypeSymbol>());
       
   994         reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
       
   995         return bestSoFar;
   922     }
   996     }
   923     // where
   997     // where
   924     private Symbol findMethod(Env<AttrContext> env,
   998     private Symbol findMethod(Env<AttrContext> env,
   925                               Type site,
   999                               Type site,
   926                               Name name,
  1000                               Name name,
   974                     bestSoFar = concrete;
  1048                     bestSoFar = concrete;
   975             }
  1049             }
   976         }
  1050         }
   977         return bestSoFar;
  1051         return bestSoFar;
   978     }
  1052     }
       
  1053     //where
       
  1054         void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
       
  1055             boolean success = bestSoFar.kind < ERRONEOUS;
       
  1056 
       
  1057             if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
       
  1058                 return;
       
  1059             } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
       
  1060                 return;
       
  1061             }
       
  1062 
       
  1063             if (bestSoFar.name == names.init &&
       
  1064                     bestSoFar.owner == syms.objectType.tsym &&
       
  1065                     !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
       
  1066                 return; //skip diags for Object constructor resolution
       
  1067             } else if (site == syms.predefClass.type && !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
       
  1068                 return; //skip spurious diags for predef symbols (i.e. operators)
       
  1069             } else if (internalResolution && !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
       
  1070                 return;
       
  1071             }
       
  1072 
       
  1073             int pos = 0;
       
  1074             for (Symbol s : verboseResolutionCandidateDiags.keySet()) {
       
  1075                 if (s == bestSoFar) break;
       
  1076                 pos++;
       
  1077             }
       
  1078             String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
       
  1079             JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, pos, currentStep,
       
  1080                     methodArguments(argtypes), methodArguments(typeargtypes));
       
  1081             JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, List.from(verboseResolutionCandidateDiags.values().toArray(new JCDiagnostic[verboseResolutionCandidateDiags.size()])));
       
  1082             log.report(d);
       
  1083         }
   979 
  1084 
   980     /** Find unqualified method matching given name, type and value arguments.
  1085     /** Find unqualified method matching given name, type and value arguments.
   981      *  @param env       The current environment.
  1086      *  @param env       The current environment.
   982      *  @param name      The method's name.
  1087      *  @param name      The method's name.
   983      *  @param argtypes  The method's value arguments.
  1088      *  @param argtypes  The method's value arguments.
  1542      */
  1647      */
  1543     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
  1648     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
  1544                                         Type site, Name name,
  1649                                         Type site, Name name,
  1545                                         List<Type> argtypes,
  1650                                         List<Type> argtypes,
  1546                                         List<Type> typeargtypes) {
  1651                                         List<Type> typeargtypes) {
  1547         Symbol sym = resolveQualifiedMethod(
  1652         boolean prevInternal = internalResolution;
  1548             pos, env, site.tsym, site, name, argtypes, typeargtypes);
  1653         try {
  1549         if (sym.kind == MTH) return (MethodSymbol)sym;
  1654             internalResolution = true;
  1550         else throw new FatalError(
  1655             Symbol sym = resolveQualifiedMethod(
  1551                  diags.fragment("fatal.err.cant.locate.meth",
  1656                 pos, env, site.tsym, site, name, argtypes, typeargtypes);
  1552                                 name));
  1657             if (sym.kind == MTH) return (MethodSymbol)sym;
       
  1658             else throw new FatalError(
       
  1659                      diags.fragment("fatal.err.cant.locate.meth",
       
  1660                                     name));
       
  1661         }
       
  1662         finally {
       
  1663             internalResolution = prevInternal;
       
  1664         }
  1553     }
  1665     }
  1554 
  1666 
  1555     /** Resolve constructor.
  1667     /** Resolve constructor.
  1556      *  @param pos       The position to use for error reporting.
  1668      *  @param pos       The position to use for error reporting.
  1557      *  @param env       The environment current at the constructor invocation.
  1669      *  @param env       The environment current at the constructor invocation.
  1828     }
  1940     }
  1829 
  1941 
  1830     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
  1942     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
  1831 
  1943 
  1832     public Object methodArguments(List<Type> argtypes) {
  1944     public Object methodArguments(List<Type> argtypes) {
  1833         return argtypes.isEmpty() ? noArgs : argtypes;
  1945         return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
  1834     }
  1946     }
  1835 
  1947 
  1836     /**
  1948     /**
  1837      * Root class for resolution errors. Subclass of ResolveError
  1949      * Root class for resolution errors. Subclass of ResolveError
  1838      * represent a different kinds of resolution error - as such they must
  1950      * represent a different kinds of resolution error - as such they must
  2375     }
  2487     }
  2376 
  2488 
  2377     private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
  2489     private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
  2378         new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
  2490         new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
  2379 
  2491 
       
  2492     private Map<Symbol, JCDiagnostic> verboseResolutionCandidateDiags =
       
  2493         new LinkedHashMap<Symbol, JCDiagnostic>();
       
  2494 
  2380     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
  2495     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
  2381 
  2496 
  2382     private MethodResolutionPhase currentStep = null;
  2497     private MethodResolutionPhase currentStep = null;
       
  2498 
       
  2499     private boolean internalResolution = false;
  2383 
  2500 
  2384     private MethodResolutionPhase firstErroneousResolutionPhase() {
  2501     private MethodResolutionPhase firstErroneousResolutionPhase() {
  2385         MethodResolutionPhase bestSoFar = BASIC;
  2502         MethodResolutionPhase bestSoFar = BASIC;
  2386         Symbol sym = methodNotFound;
  2503         Symbol sym = methodNotFound;
  2387         List<MethodResolutionPhase> steps = methodResolutionSteps;
  2504         List<MethodResolutionPhase> steps = methodResolutionSteps;