langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
changeset 28331 43ed6b2e0e3b
parent 27849 df6cd9799fcd
child 28336 9a6ae3c3efb5
equal deleted inserted replaced
28330:d4bcdcac1211 28331:43ed6b2e0e3b
    37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
    37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
    38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
    38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
    39 import com.sun.tools.javac.comp.Infer.InferenceContext;
    39 import com.sun.tools.javac.comp.Infer.InferenceContext;
    40 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
    40 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
    41 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
    41 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
    42 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.DiagnosticRewriter;
       
    43 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
    42 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
    44 import com.sun.tools.javac.jvm.*;
    43 import com.sun.tools.javac.jvm.*;
    45 import com.sun.tools.javac.main.Option;
    44 import com.sun.tools.javac.main.Option;
    46 import com.sun.tools.javac.tree.*;
    45 import com.sun.tools.javac.tree.*;
    47 import com.sun.tools.javac.tree.JCTree.*;
    46 import com.sun.tools.javac.tree.JCTree.*;
    53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    52 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
    55 
    54 
    56 import java.util.Arrays;
    55 import java.util.Arrays;
    57 import java.util.Collection;
    56 import java.util.Collection;
    58 import java.util.EnumMap;
       
    59 import java.util.EnumSet;
    57 import java.util.EnumSet;
    60 import java.util.Iterator;
    58 import java.util.Iterator;
    61 import java.util.LinkedHashMap;
    59 import java.util.LinkedHashMap;
    62 import java.util.Map;
    60 import java.util.Map;
       
    61 import java.util.function.BiPredicate;
       
    62 import java.util.stream.Stream;
    63 
    63 
    64 import javax.lang.model.element.ElementVisitor;
    64 import javax.lang.model.element.ElementVisitor;
    65 
    65 
    66 import static com.sun.tools.javac.code.Flags.*;
    66 import static com.sun.tools.javac.code.Flags.*;
    67 import static com.sun.tools.javac.code.Flags.BLOCK;
    67 import static com.sun.tools.javac.code.Flags.BLOCK;
  2544                                 sym = super.access(env, pos, location, sym);
  2544                                 sym = super.access(env, pos, location, sym);
  2545                             } else {
  2545                             } else {
  2546                                 final JCDiagnostic details = sym.kind == WRONG_MTH ?
  2546                                 final JCDiagnostic details = sym.kind == WRONG_MTH ?
  2547                                                 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
  2547                                                 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
  2548                                                 null;
  2548                                                 null;
  2549                                 sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
  2549                                 sym = new DiamondError(sym, currentResolutionContext);
  2550                                     @Override
       
  2551                                     JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
       
  2552                                             Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
       
  2553                                         String key = details == null ?
       
  2554                                             "cant.apply.diamond" :
       
  2555                                             "cant.apply.diamond.1";
       
  2556                                         return diags.create(dkind, log.currentSource(), pos, key,
       
  2557                                                 diags.fragment("diamond", site.tsym), details);
       
  2558                                     }
       
  2559                                 };
       
  2560                                 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
  2550                                 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
  2561                                 env.info.pendingResolutionPhase = currentResolutionContext.step;
  2551                                 env.info.pendingResolutionPhase = currentResolutionContext.step;
  2562                             }
  2552                             }
  2563                         }
  2553                         }
  2564                         return sym;
  2554                         return sym;
  3722                         key, name, first, second);
  3712                         key, name, first, second);
  3723             }
  3713             }
  3724             else {
  3714             else {
  3725                 Pair<Symbol, JCDiagnostic> c = errCandidate();
  3715                 Pair<Symbol, JCDiagnostic> c = errCandidate();
  3726                 if (compactMethodDiags) {
  3716                 if (compactMethodDiags) {
  3727                     for (Map.Entry<Template, DiagnosticRewriter> _entry :
  3717                     JCDiagnostic simpleDiag =
  3728                             MethodResolutionDiagHelper.rewriters.entrySet()) {
  3718                         MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd);
  3729                         if (_entry.getKey().matches(c.snd)) {
  3719                     if (simpleDiag != null) {
  3730                             JCDiagnostic simpleDiag =
  3720                         return simpleDiag;
  3731                                     _entry.getValue().rewriteDiagnostic(diags, pos,
       
  3732                                         log.currentSource(), dkind, c.snd);
       
  3733                             simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
       
  3734                             return simpleDiag;
       
  3735                         }
       
  3736                     }
  3721                     }
  3737                 }
  3722                 }
  3738                 Symbol ws = c.fst.asMemberOf(site, types);
  3723                 Symbol ws = c.fst.asMemberOf(site, types);
  3739                 return diags.create(dkind, log.currentSource(), pos,
  3724                 return diags.create(dkind, log.currentSource(), pos,
  3740                           "cant.apply.symbol",
  3725                           "cant.apply.symbol",
  3763             return new Pair<>(bestSoFar.sym, bestSoFar.details);
  3748             return new Pair<>(bestSoFar.sym, bestSoFar.details);
  3764         }
  3749         }
  3765     }
  3750     }
  3766 
  3751 
  3767     /**
  3752     /**
  3768      * ResolveError error class indicating that a set of symbols
  3753      * ResolveError error class indicating that a symbol (either methods, constructors or operand)
  3769      * (either methods, constructors or operands) is not applicable
  3754      * is not applicable given an actual arguments/type argument list.
  3770      * given an actual arguments/type argument list.
       
  3771      */
  3755      */
  3772     class InapplicableSymbolsError extends InapplicableSymbolError {
  3756     class InapplicableSymbolsError extends InapplicableSymbolError {
  3773 
  3757 
  3774         InapplicableSymbolsError(MethodResolutionContext context) {
  3758         InapplicableSymbolsError(MethodResolutionContext context) {
  3775             super(WRONG_MTHS, "inapplicable symbols", context);
  3759             super(WRONG_MTHS, "inapplicable symbols", context);
  3862                 return details;
  3846                 return details;
  3863             }
  3847             }
  3864     }
  3848     }
  3865 
  3849 
  3866     /**
  3850     /**
       
  3851      * DiamondError error class indicating that a constructor symbol is not applicable
       
  3852      * given an actual arguments/type argument list using diamond inference.
       
  3853      */
       
  3854     class DiamondError extends InapplicableSymbolError {
       
  3855 
       
  3856         Symbol sym;
       
  3857 
       
  3858         public DiamondError(Symbol sym, MethodResolutionContext context) {
       
  3859             super(sym.kind, "diamondError", context);
       
  3860             this.sym = sym;
       
  3861         }
       
  3862 
       
  3863         JCDiagnostic getDetails() {
       
  3864             return (sym.kind == WRONG_MTH) ?
       
  3865                     ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
       
  3866                     null;
       
  3867         }
       
  3868 
       
  3869         @Override
       
  3870         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
       
  3871                 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
       
  3872             JCDiagnostic details = getDetails();
       
  3873             if (details != null && compactMethodDiags) {
       
  3874                 JCDiagnostic simpleDiag =
       
  3875                         MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
       
  3876                 if (simpleDiag != null) {
       
  3877                     return simpleDiag;
       
  3878                 }
       
  3879             }
       
  3880             String key = details == null ?
       
  3881                 "cant.apply.diamond" :
       
  3882                 "cant.apply.diamond.1";
       
  3883             return diags.create(dkind, log.currentSource(), pos, key,
       
  3884                     diags.fragment("diamond", site.tsym), details);
       
  3885         }
       
  3886     }
       
  3887 
       
  3888     /**
  3867      * An InvalidSymbolError error class indicating that a symbol is not
  3889      * An InvalidSymbolError error class indicating that a symbol is not
  3868      * accessible from a given site
  3890      * accessible from a given site
  3869      */
  3891      */
  3870     class AccessError extends InvalidSymbolError {
  3892     class AccessError extends InvalidSymbolError {
  3871 
  3893 
  4144                 }
  4166                 }
  4145                 return true;
  4167                 return true;
  4146             }
  4168             }
  4147         }
  4169         }
  4148 
  4170 
       
  4171         /**
       
  4172          * Common rewriter for all argument mismatch simplifications.
       
  4173          */
       
  4174         static class ArgMismatchRewriter implements DiagnosticRewriter {
       
  4175 
       
  4176             /** the index of the subdiagnostic to be used as primary. */
       
  4177             int causeIndex;
       
  4178 
       
  4179             public ArgMismatchRewriter(int causeIndex) {
       
  4180                 this.causeIndex = causeIndex;
       
  4181             }
       
  4182 
       
  4183             @Override
       
  4184             public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
       
  4185                     DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
       
  4186                     DiagnosticType preferredKind, JCDiagnostic d) {
       
  4187                 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
       
  4188                 return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
       
  4189                         "prob.found.req", cause);
       
  4190             }
       
  4191         }
       
  4192 
  4149         /** a dummy template that match any diagnostic argument */
  4193         /** a dummy template that match any diagnostic argument */
  4150         static final Template skip = new Template("") {
  4194         static final Template skip = new Template("") {
  4151             @Override
  4195             @Override
  4152             boolean matches(Object d) {
  4196             boolean matches(Object d) {
  4153                 return true;
  4197                 return true;
  4154             }
  4198             }
  4155         };
  4199         };
  4156 
  4200 
       
  4201         /** template for matching inference-free arguments mismatch failures */
       
  4202         static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
       
  4203 
       
  4204         /** template for matching inference related arguments mismatch failures */
       
  4205         static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
       
  4206             @Override
       
  4207             boolean matches(Object o) {
       
  4208                 if (!super.matches(o)) {
       
  4209                     return false;
       
  4210                 }
       
  4211                 JCDiagnostic d = (JCDiagnostic)o;
       
  4212                 @SuppressWarnings("unchecked")
       
  4213                 List<Type> tvars = (List<Type>)d.getArgs()[0];
       
  4214                 return !containsAny(d, tvars);
       
  4215             }
       
  4216 
       
  4217             BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
       
  4218                 if (o instanceof Type) {
       
  4219                     return ((Type)o).containsAny(ts);
       
  4220                 } else if (o instanceof JCDiagnostic) {
       
  4221                     return containsAny((JCDiagnostic)o, ts);
       
  4222                 } else {
       
  4223                     return false;
       
  4224                 }
       
  4225             };
       
  4226 
       
  4227             boolean containsAny(JCDiagnostic d, List<Type> ts) {
       
  4228                 return Stream.of(d.getArgs())
       
  4229                         .anyMatch(o -> containsPredicate.test(o, ts));
       
  4230             }
       
  4231         };
       
  4232 
  4157         /** rewriter map used for method resolution simplification */
  4233         /** rewriter map used for method resolution simplification */
  4158         static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
  4234         static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
  4159 
  4235 
  4160         static {
  4236         static {
  4161             String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex();
  4237             rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
  4162             rewriters.put(new Template(argMismatchRegex, skip),
  4238             rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
  4163                     new DiagnosticRewriter() {
  4239         }
  4164                 @Override
  4240 
  4165                 public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
  4241         /**
  4166                         DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
  4242          * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
  4167                         DiagnosticType preferredKind, JCDiagnostic d) {
  4243          * and rewrite it accordingly.
  4168                     JCDiagnostic cause = (JCDiagnostic)d.getArgs()[0];
  4244          */
  4169                     return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
  4245         static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
  4170                             "prob.found.req", cause);
  4246                                     DiagnosticType dkind, JCDiagnostic d) {
  4171                 }
  4247             for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
  4172             });
  4248                 if (_entry.getKey().matches(d)) {
       
  4249                     JCDiagnostic simpleDiag =
       
  4250                             _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
       
  4251                     simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
       
  4252                     return simpleDiag;
       
  4253                 }
       
  4254             }
       
  4255             return null;
  4173         }
  4256         }
  4174     }
  4257     }
  4175 
  4258 
  4176     enum MethodResolutionPhase {
  4259     enum MethodResolutionPhase {
  4177         BASIC(false, false),
  4260         BASIC(false, false),