1 /* 2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.comp; 27 28 import com.sun.tools.javac.api.Formattable.LocalizedString; 29 import com.sun.tools.javac.code.*; 30 import com.sun.tools.javac.code.Scope.WriteableScope; 31 import com.sun.tools.javac.code.Source.Feature; 32 import com.sun.tools.javac.code.Symbol.*; 33 import com.sun.tools.javac.code.Type.*; 34 import com.sun.tools.javac.comp.Attr.ResultInfo; 35 import com.sun.tools.javac.comp.Check.CheckContext; 36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode; 37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; 38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType; 39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; 40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template; 41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind; 42 import com.sun.tools.javac.jvm.*; 43 import com.sun.tools.javac.main.Option; 44 import com.sun.tools.javac.resources.CompilerProperties.Errors; 45 import com.sun.tools.javac.resources.CompilerProperties.Fragments; 46 import com.sun.tools.javac.resources.CompilerProperties.Warnings; 47 import com.sun.tools.javac.tree.*; 48 import com.sun.tools.javac.tree.JCTree.*; 49 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; 50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; 51 import com.sun.tools.javac.util.*; 52 import com.sun.tools.javac.util.DefinedBy.Api; 53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 56 import com.sun.tools.javac.util.JCDiagnostic.Warning; 57 58 import java.util.Arrays; 59 import java.util.Collection; 60 import java.util.EnumSet; 61 import java.util.HashSet; 62 import java.util.Iterator; 63 import java.util.LinkedHashMap; 64 import java.util.Map; 65 import java.util.Set; 66 import java.util.function.BiFunction; 67 import java.util.function.BiPredicate; 68 import java.util.function.Consumer; 69 import java.util.function.Function; 70 import java.util.function.Predicate; 71 import java.util.stream.Stream; 72 73 import javax.lang.model.element.ElementVisitor; 74 75 import static com.sun.tools.javac.code.Flags.*; 76 import static com.sun.tools.javac.code.Flags.BLOCK; 77 import static com.sun.tools.javac.code.Flags.STATIC; 78 import static com.sun.tools.javac.code.Kinds.*; 79 import static com.sun.tools.javac.code.Kinds.Kind.*; 80 import static com.sun.tools.javac.code.TypeTag.*; 81 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; 82 import static com.sun.tools.javac.tree.JCTree.Tag.*; 83 import static com.sun.tools.javac.util.Iterators.createCompoundIterator; 84 85 /** Helper class for name resolution, used mostly by the attribution phase. 86 * 87 * <p><b>This is NOT part of any supported API. 88 * If you write code that depends on this, you do so at your own risk. 89 * This code and its internal interfaces are subject to change or 90 * deletion without notice.</b> 91 */ 92 public class Resolve { 93 protected static final Context.Key<Resolve> resolveKey = new Context.Key<>(); 94 95 Names names; 96 Log log; 97 Symtab syms; 98 Attr attr; 99 DeferredAttr deferredAttr; 100 Check chk; 101 Infer infer; 102 ClassFinder finder; 103 ModuleFinder moduleFinder; 104 Types types; 105 JCDiagnostic.Factory diags; 106 public final boolean allowFunctionalInterfaceMostSpecific; 107 public final boolean allowModules; 108 public final boolean checkVarargsAccessAfterResolution; 109 private final boolean compactMethodDiags; 110 private final boolean allowLocalVariableTypeInference; 111 private final boolean allowYieldStatement; 112 final EnumSet<VerboseResolutionMode> verboseResolutionMode; 113 114 WriteableScope polymorphicSignatureScope; 115 116 protected Resolve(Context context) { 117 context.put(resolveKey, this); 118 syms = Symtab.instance(context); 119 120 varNotFound = new SymbolNotFoundError(ABSENT_VAR); 121 methodNotFound = new SymbolNotFoundError(ABSENT_MTH); 122 typeNotFound = new SymbolNotFoundError(ABSENT_TYP); 123 referenceNotFound = ReferenceLookupResult.error(methodNotFound); 124 125 names = Names.instance(context); 126 log = Log.instance(context); 127 attr = Attr.instance(context); 128 deferredAttr = DeferredAttr.instance(context); 129 chk = Check.instance(context); 130 infer = Infer.instance(context); 131 finder = ClassFinder.instance(context); 132 moduleFinder = ModuleFinder.instance(context); 133 types = Types.instance(context); 134 diags = JCDiagnostic.Factory.instance(context); 135 Preview preview = Preview.instance(context); 136 Source source = Source.instance(context); 137 Options options = Options.instance(context); 138 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") || 139 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics"); 140 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); 141 Target target = Target.instance(context); 142 allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source); 143 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source); 144 allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) && 145 Feature.SWITCH_EXPRESSION.allowedInSource(source); 146 checkVarargsAccessAfterResolution = 147 Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source); 148 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol); 149 allowModules = Feature.MODULES.allowedInSource(source); 150 } 151 152 /** error symbols, which are returned when resolution fails 153 */ 154 private final SymbolNotFoundError varNotFound; 155 private final SymbolNotFoundError methodNotFound; 156 private final SymbolNotFoundError typeNotFound; 157 158 /** empty reference lookup result */ 159 private final ReferenceLookupResult referenceNotFound; 160 161 public static Resolve instance(Context context) { 162 Resolve instance = context.get(resolveKey); 163 if (instance == null) 164 instance = new Resolve(context); 165 return instance; 166 } 167 168 private static Symbol bestOf(Symbol s1, 169 Symbol s2) { 170 return s1.kind.betterThan(s2.kind) ? s1 : s2; 171 } 172 173 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support"> 174 enum VerboseResolutionMode { 175 SUCCESS("success"), 176 FAILURE("failure"), 177 APPLICABLE("applicable"), 178 INAPPLICABLE("inapplicable"), 179 DEFERRED_INST("deferred-inference"), 180 PREDEF("predef"), 181 OBJECT_INIT("object-init"), 182 INTERNAL("internal"); 183 184 final String opt; 185 186 private VerboseResolutionMode(String opt) { 187 this.opt = opt; 188 } 189 190 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) { 191 String s = opts.get("debug.verboseResolution"); 192 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class); 193 if (s == null) return res; 194 if (s.contains("all")) { 195 res = EnumSet.allOf(VerboseResolutionMode.class); 196 } 197 Collection<String> args = Arrays.asList(s.split(",")); 198 for (VerboseResolutionMode mode : values()) { 199 if (args.contains(mode.opt)) { 200 res.add(mode); 201 } else if (args.contains("-" + mode.opt)) { 202 res.remove(mode); 203 } 204 } 205 return res; 206 } 207 } 208 209 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, 210 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) { 211 boolean success = !bestSoFar.kind.isResolutionError(); 212 213 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { 214 return; 215 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { 216 return; 217 } 218 219 if (bestSoFar.name == names.init && 220 bestSoFar.owner == syms.objectType.tsym && 221 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { 222 return; //skip diags for Object constructor resolution 223 } else if (site == syms.predefClass.type && 224 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { 225 return; //skip spurious diags for predef symbols (i.e. operators) 226 } else if (currentResolutionContext.internalResolution && 227 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { 228 return; 229 } 230 231 int pos = 0; 232 int mostSpecificPos = -1; 233 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>(); 234 for (Candidate c : currentResolutionContext.candidates) { 235 if (currentResolutionContext.step != c.step || 236 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || 237 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) { 238 continue; 239 } else { 240 subDiags.append(c.isApplicable() ? 241 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) : 242 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details)); 243 if (c.sym == bestSoFar) 244 mostSpecificPos = pos; 245 pos++; 246 } 247 } 248 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; 249 List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step)); 250 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, 251 site.tsym, mostSpecificPos, currentResolutionContext.step, 252 methodArguments(argtypes2), 253 methodArguments(typeargtypes)); 254 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); 255 log.report(d); 256 } 257 258 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) { 259 JCDiagnostic subDiag = null; 260 if (sym.type.hasTag(FORALL)) { 261 subDiag = diags.fragment(Fragments.PartialInstSig(inst)); 262 } 263 264 String key = subDiag == null ? 265 "applicable.method.found" : 266 "applicable.method.found.1"; 267 268 return diags.fragment(key, pos, sym, subDiag); 269 } 270 271 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) { 272 return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag)); 273 } 274 // </editor-fold> 275 276 /* ************************************************************************ 277 * Identifier resolution 278 *************************************************************************/ 279 280 /** An environment is "static" if its static level is greater than 281 * the one of its outer environment 282 */ 283 protected static boolean isStatic(Env<AttrContext> env) { 284 return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel; 285 } 286 287 /** An environment is an "initializer" if it is a constructor or 288 * an instance initializer. 289 */ 290 static boolean isInitializer(Env<AttrContext> env) { 291 Symbol owner = env.info.scope.owner; 292 return owner.isConstructor() || 293 owner.owner.kind == TYP && 294 (owner.kind == VAR || 295 owner.kind == MTH && (owner.flags() & BLOCK) != 0) && 296 (owner.flags() & STATIC) == 0; 297 } 298 299 /** Is class accessible in given environment? 300 * @param env The current environment. 301 * @param c The class whose accessibility is checked. 302 */ 303 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) { 304 return isAccessible(env, c, false); 305 } 306 307 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) { 308 309 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor 310 to refer to an inaccessible type 311 */ 312 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0) 313 return true; 314 315 if (env.info.visitingServiceImplementation && 316 env.toplevel.modle == c.packge().modle) { 317 return true; 318 } 319 320 boolean isAccessible = false; 321 switch ((short)(c.flags() & AccessFlags)) { 322 case PRIVATE: 323 isAccessible = 324 env.enclClass.sym.outermostClass() == 325 c.owner.outermostClass(); 326 break; 327 case 0: 328 isAccessible = 329 env.toplevel.packge == c.owner // fast special case 330 || 331 env.toplevel.packge == c.packge(); 332 break; 333 default: // error recovery 334 isAccessible = true; 335 break; 336 case PUBLIC: 337 if (allowModules) { 338 ModuleSymbol currModule = env.toplevel.modle; 339 currModule.complete(); 340 PackageSymbol p = c.packge(); 341 isAccessible = 342 currModule == p.modle || 343 currModule.visiblePackages.get(p.fullname) == p || 344 p == syms.rootPackage || 345 (p.modle == syms.unnamedModule && currModule.readModules.contains(p.modle)); 346 } else { 347 isAccessible = true; 348 } 349 break; 350 case PROTECTED: 351 isAccessible = 352 env.toplevel.packge == c.owner // fast special case 353 || 354 env.toplevel.packge == c.packge() 355 || 356 isInnerSubClass(env.enclClass.sym, c.owner); 357 break; 358 } 359 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ? 360 isAccessible : 361 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner); 362 } 363 //where 364 /** Is given class a subclass of given base class, or an inner class 365 * of a subclass? 366 * Return null if no such class exists. 367 * @param c The class which is the subclass or is contained in it. 368 * @param base The base class 369 */ 370 private boolean isInnerSubClass(ClassSymbol c, Symbol base) { 371 while (c != null && !c.isSubClass(base, types)) { 372 c = c.owner.enclClass(); 373 } 374 return c != null; 375 } 376 377 boolean isAccessible(Env<AttrContext> env, Type t) { 378 return isAccessible(env, t, false); 379 } 380 381 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { 382 return (t.hasTag(ARRAY)) 383 ? isAccessible(env, types.cvarUpperBound(types.elemtype(t))) 384 : isAccessible(env, t.tsym, checkInner); 385 } 386 387 /** Is symbol accessible as a member of given type in given environment? 388 * @param env The current environment. 389 * @param site The type of which the tested symbol is regarded 390 * as a member. 391 * @param sym The symbol. 392 */ 393 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) { 394 return isAccessible(env, site, sym, false); 395 } 396 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) { 397 if (sym.name == names.init && sym.owner != site.tsym) return false; 398 399 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor 400 to refer to an inaccessible type 401 */ 402 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0) 403 return true; 404 405 if (env.info.visitingServiceImplementation && 406 env.toplevel.modle == sym.packge().modle) { 407 return true; 408 } 409 410 switch ((short)(sym.flags() & AccessFlags)) { 411 case PRIVATE: 412 return 413 (env.enclClass.sym == sym.owner // fast special case 414 || 415 env.enclClass.sym.outermostClass() == 416 sym.owner.outermostClass()) 417 && 418 sym.isInheritedIn(site.tsym, types); 419 case 0: 420 return 421 (env.toplevel.packge == sym.owner.owner // fast special case 422 || 423 env.toplevel.packge == sym.packge()) 424 && 425 isAccessible(env, site, checkInner) 426 && 427 sym.isInheritedIn(site.tsym, types) 428 && 429 notOverriddenIn(site, sym); 430 case PROTECTED: 431 return 432 (env.toplevel.packge == sym.owner.owner // fast special case 433 || 434 env.toplevel.packge == sym.packge() 435 || 436 isProtectedAccessible(sym, env.enclClass.sym, site) 437 || 438 // OK to select instance method or field from 'super' or type name 439 // (but type names should be disallowed elsewhere!) 440 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) 441 && 442 isAccessible(env, site, checkInner) 443 && 444 notOverriddenIn(site, sym); 445 default: // this case includes erroneous combinations as well 446 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym); 447 } 448 } 449 //where 450 /* `sym' is accessible only if not overridden by 451 * another symbol which is a member of `site' 452 * (because, if it is overridden, `sym' is not strictly 453 * speaking a member of `site'). A polymorphic signature method 454 * cannot be overridden (e.g. MH.invokeExact(Object[])). 455 */ 456 private boolean notOverriddenIn(Type site, Symbol sym) { 457 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) 458 return true; 459 else { 460 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 461 return (s2 == null || s2 == sym || sym.owner == s2.owner || 462 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); 463 } 464 } 465 //where 466 /** Is given protected symbol accessible if it is selected from given site 467 * and the selection takes place in given class? 468 * @param sym The symbol with protected access 469 * @param c The class where the access takes place 470 * @site The type of the qualifier 471 */ 472 private 473 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { 474 Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site; 475 while (c != null && 476 !(c.isSubClass(sym.owner, types) && 477 (c.flags() & INTERFACE) == 0 && 478 // In JLS 2e 6.6.2.1, the subclass restriction applies 479 // only to instance fields and methods -- types are excluded 480 // regardless of whether they are declared 'static' or not. 481 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types)))) 482 c = c.owner.enclClass(); 483 return c != null; 484 } 485 486 /** 487 * Performs a recursive scan of a type looking for accessibility problems 488 * from current attribution environment 489 */ 490 void checkAccessibleType(Env<AttrContext> env, Type t) { 491 accessibilityChecker.visit(t, env); 492 } 493 494 /** 495 * Accessibility type-visitor 496 */ 497 Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker = 498 new Types.SimpleVisitor<Void, Env<AttrContext>>() { 499 500 void visit(List<Type> ts, Env<AttrContext> env) { 501 for (Type t : ts) { 502 visit(t, env); 503 } 504 } 505 506 public Void visitType(Type t, Env<AttrContext> env) { 507 return null; 508 } 509 510 @Override 511 public Void visitArrayType(ArrayType t, Env<AttrContext> env) { 512 visit(t.elemtype, env); 513 return null; 514 } 515 516 @Override 517 public Void visitClassType(ClassType t, Env<AttrContext> env) { 518 visit(t.getTypeArguments(), env); 519 if (!isAccessible(env, t, true)) { 520 accessBase(new AccessError(env, null, t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true); 521 } 522 return null; 523 } 524 525 @Override 526 public Void visitWildcardType(WildcardType t, Env<AttrContext> env) { 527 visit(t.type, env); 528 return null; 529 } 530 531 @Override 532 public Void visitMethodType(MethodType t, Env<AttrContext> env) { 533 visit(t.getParameterTypes(), env); 534 visit(t.getReturnType(), env); 535 visit(t.getThrownTypes(), env); 536 return null; 537 } 538 }; 539 540 /** Try to instantiate the type of a method so that it fits 541 * given type arguments and argument types. If successful, return 542 * the method's instantiated type, else return null. 543 * The instantiation will take into account an additional leading 544 * formal parameter if the method is an instance method seen as a member 545 * of an under determined site. In this case, we treat site as an additional 546 * parameter and the parameters of the class containing the method as 547 * additional type variables that get instantiated. 548 * 549 * @param env The current environment 550 * @param site The type of which the method is a member. 551 * @param m The method symbol. 552 * @param argtypes The invocation's given value arguments. 553 * @param typeargtypes The invocation's given type arguments. 554 * @param allowBoxing Allow boxing conversions of arguments. 555 * @param useVarargs Box trailing arguments into an array for varargs. 556 */ 557 Type rawInstantiate(Env<AttrContext> env, 558 Type site, 559 Symbol m, 560 ResultInfo resultInfo, 561 List<Type> argtypes, 562 List<Type> typeargtypes, 563 boolean allowBoxing, 564 boolean useVarargs, 565 Warner warn) throws Infer.InferenceException { 566 Type mt = types.memberType(site, m); 567 // tvars is the list of formal type variables for which type arguments 568 // need to inferred. 569 List<Type> tvars = List.nil(); 570 if (typeargtypes == null) typeargtypes = List.nil(); 571 if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) { 572 // This is not a polymorphic method, but typeargs are supplied 573 // which is fine, see JLS 15.12.2.1 574 } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) { 575 ForAll pmt = (ForAll) mt; 576 if (typeargtypes.length() != pmt.tvars.length()) 577 // not enough args 578 throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length())))); 579 // Check type arguments are within bounds 580 List<Type> formals = pmt.tvars; 581 List<Type> actuals = typeargtypes; 582 while (formals.nonEmpty() && actuals.nonEmpty()) { 583 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head), 584 pmt.tvars, typeargtypes); 585 for (; bounds.nonEmpty(); bounds = bounds.tail) { 586 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) { 587 throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds))); 588 } 589 } 590 formals = formals.tail; 591 actuals = actuals.tail; 592 } 593 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes); 594 } else if (mt.hasTag(FORALL)) { 595 ForAll pmt = (ForAll) mt; 596 List<Type> tvars1 = types.newInstances(pmt.tvars); 597 tvars = tvars.appendList(tvars1); 598 mt = types.subst(pmt.qtype, pmt.tvars, tvars1); 599 } 600 601 // find out whether we need to go the slow route via infer 602 boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/ 603 for (List<Type> l = argtypes; 604 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded; 605 l = l.tail) { 606 if (l.head.hasTag(FORALL)) instNeeded = true; 607 } 608 609 if (instNeeded) { 610 return infer.instantiateMethod(env, 611 tvars, 612 (MethodType)mt, 613 resultInfo, 614 (MethodSymbol)m, 615 argtypes, 616 allowBoxing, 617 useVarargs, 618 currentResolutionContext, 619 warn); 620 } 621 622 DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn); 623 currentResolutionContext.methodCheck.argumentsAcceptable(env, dc, 624 argtypes, mt.getParameterTypes(), warn); 625 dc.complete(); 626 return mt; 627 } 628 629 Type checkMethod(Env<AttrContext> env, 630 Type site, 631 Symbol m, 632 ResultInfo resultInfo, 633 List<Type> argtypes, 634 List<Type> typeargtypes, 635 Warner warn) { 636 MethodResolutionContext prevContext = currentResolutionContext; 637 try { 638 currentResolutionContext = new MethodResolutionContext(); 639 currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ? 640 AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK; 641 if (env.tree.hasTag(JCTree.Tag.REFERENCE)) { 642 //method/constructor references need special check class 643 //to handle inference variables in 'argtypes' (might happen 644 //during an unsticking round) 645 currentResolutionContext.methodCheck = 646 new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); 647 } 648 MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase; 649 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, 650 step.isBoxingRequired(), step.isVarargsRequired(), warn); 651 } 652 finally { 653 currentResolutionContext = prevContext; 654 } 655 } 656 657 /** Same but returns null instead throwing a NoInstanceException 658 */ 659 Type instantiate(Env<AttrContext> env, 660 Type site, 661 Symbol m, 662 ResultInfo resultInfo, 663 List<Type> argtypes, 664 List<Type> typeargtypes, 665 boolean allowBoxing, 666 boolean useVarargs, 667 Warner warn) { 668 try { 669 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, 670 allowBoxing, useVarargs, warn); 671 } catch (InapplicableMethodException ex) { 672 return null; 673 } 674 } 675 676 /** 677 * This interface defines an entry point that should be used to perform a 678 * method check. A method check usually consist in determining as to whether 679 * a set of types (actuals) is compatible with another set of types (formals). 680 * Since the notion of compatibility can vary depending on the circumstances, 681 * this interfaces allows to easily add new pluggable method check routines. 682 */ 683 interface MethodCheck { 684 /** 685 * Main method check routine. A method check usually consist in determining 686 * as to whether a set of types (actuals) is compatible with another set of 687 * types (formals). If an incompatibility is found, an unchecked exception 688 * is assumed to be thrown. 689 */ 690 void argumentsAcceptable(Env<AttrContext> env, 691 DeferredAttrContext deferredAttrContext, 692 List<Type> argtypes, 693 List<Type> formals, 694 Warner warn); 695 696 /** 697 * Retrieve the method check object that will be used during a 698 * most specific check. 699 */ 700 MethodCheck mostSpecificCheck(List<Type> actuals); 701 } 702 703 /** 704 * Helper enum defining all method check diagnostics (used by resolveMethodCheck). 705 */ 706 enum MethodCheckDiag { 707 /** 708 * Actuals and formals differs in length. 709 */ 710 ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"), 711 /** 712 * An actual is incompatible with a formal. 713 */ 714 ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"), 715 /** 716 * An actual is incompatible with the varargs element type. 717 */ 718 VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"), 719 /** 720 * The varargs element type is inaccessible. 721 */ 722 INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type"); 723 724 final String basicKey; 725 final String inferKey; 726 727 MethodCheckDiag(String basicKey, String inferKey) { 728 this.basicKey = basicKey; 729 this.inferKey = inferKey; 730 } 731 732 String regex() { 733 return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey); 734 } 735 } 736 737 /** 738 * Dummy method check object. All methods are deemed applicable, regardless 739 * of their formal parameter types. 740 */ 741 MethodCheck nilMethodCheck = new MethodCheck() { 742 public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) { 743 //do nothing - method always applicable regardless of actuals 744 } 745 746 public MethodCheck mostSpecificCheck(List<Type> actuals) { 747 return this; 748 } 749 }; 750 751 /** 752 * Base class for 'real' method checks. The class defines the logic for 753 * iterating through formals and actuals and provides and entry point 754 * that can be used by subclasses in order to define the actual check logic. 755 */ 756 abstract class AbstractMethodCheck implements MethodCheck { 757 @Override 758 public void argumentsAcceptable(final Env<AttrContext> env, 759 DeferredAttrContext deferredAttrContext, 760 List<Type> argtypes, 761 List<Type> formals, 762 Warner warn) { 763 //should we expand formals? 764 boolean useVarargs = deferredAttrContext.phase.isVarargsRequired(); 765 JCTree callTree = treeForDiagnostics(env); 766 List<JCExpression> trees = TreeInfo.args(callTree); 767 768 //inference context used during this method check 769 InferenceContext inferenceContext = deferredAttrContext.inferenceContext; 770 771 Type varargsFormal = useVarargs ? formals.last() : null; 772 773 if (varargsFormal == null && 774 argtypes.size() != formals.size()) { 775 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 776 } 777 778 while (argtypes.nonEmpty() && formals.head != varargsFormal) { 779 DiagnosticPosition pos = trees != null ? trees.head : null; 780 checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn); 781 argtypes = argtypes.tail; 782 formals = formals.tail; 783 trees = trees != null ? trees.tail : trees; 784 } 785 786 if (formals.head != varargsFormal) { 787 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 788 } 789 790 if (useVarargs) { 791 //note: if applicability check is triggered by most specific test, 792 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) 793 final Type elt = types.elemtype(varargsFormal); 794 while (argtypes.nonEmpty()) { 795 DiagnosticPosition pos = trees != null ? trees.head : null; 796 checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn); 797 argtypes = argtypes.tail; 798 trees = trees != null ? trees.tail : trees; 799 } 800 } 801 } 802 803 // where 804 private JCTree treeForDiagnostics(Env<AttrContext> env) { 805 return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree; 806 } 807 808 /** 809 * Does the actual argument conforms to the corresponding formal? 810 */ 811 abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn); 812 813 protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { 814 boolean inferDiag = inferenceContext != infer.emptyContext; 815 if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) { 816 Object[] args2 = new Object[args.length + 1]; 817 System.arraycopy(args, 0, args2, 1, args.length); 818 args2[0] = inferenceContext.inferenceVars(); 819 args = args2; 820 } 821 String key = inferDiag ? diag.inferKey : diag.basicKey; 822 throw inferDiag ? 823 infer.error(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)) : 824 methodCheckFailure.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)); 825 } 826 827 /** 828 * To eliminate the overhead associated with allocating an exception object in such an 829 * hot execution path, we use flyweight pattern - and share the same exception instance 830 * across multiple method check failures. 831 */ 832 class SharedInapplicableMethodException extends InapplicableMethodException { 833 private static final long serialVersionUID = 0; 834 835 SharedInapplicableMethodException() { 836 super(null); 837 } 838 839 SharedInapplicableMethodException setMessage(JCDiagnostic details) { 840 this.diagnostic = details; 841 return this; 842 } 843 } 844 845 SharedInapplicableMethodException methodCheckFailure = new SharedInapplicableMethodException(); 846 847 public MethodCheck mostSpecificCheck(List<Type> actuals) { 848 return nilMethodCheck; 849 } 850 851 } 852 853 /** 854 * Arity-based method check. A method is applicable if the number of actuals 855 * supplied conforms to the method signature. 856 */ 857 MethodCheck arityMethodCheck = new AbstractMethodCheck() { 858 @Override 859 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 860 //do nothing - actual always compatible to formals 861 } 862 863 @Override 864 public String toString() { 865 return "arityMethodCheck"; 866 } 867 }; 868 869 /** 870 * Main method applicability routine. Given a list of actual types A, 871 * a list of formal types F, determines whether the types in A are 872 * compatible (by method invocation conversion) with the types in F. 873 * 874 * Since this routine is shared between overload resolution and method 875 * type-inference, a (possibly empty) inference context is used to convert 876 * formal types to the corresponding 'undet' form ahead of a compatibility 877 * check so that constraints can be propagated and collected. 878 * 879 * Moreover, if one or more types in A is a deferred type, this routine uses 880 * DeferredAttr in order to perform deferred attribution. If one or more actual 881 * deferred types are stuck, they are placed in a queue and revisited later 882 * after the remainder of the arguments have been seen. If this is not sufficient 883 * to 'unstuck' the argument, a cyclic inference error is called out. 884 * 885 * A method check handler (see above) is used in order to report errors. 886 */ 887 MethodCheck resolveMethodCheck = new AbstractMethodCheck() { 888 889 @Override 890 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 891 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); 892 mresult.check(pos, actual); 893 } 894 895 @Override 896 public void argumentsAcceptable(final Env<AttrContext> env, 897 DeferredAttrContext deferredAttrContext, 898 List<Type> argtypes, 899 List<Type> formals, 900 Warner warn) { 901 super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn); 902 // should we check varargs element type accessibility? 903 if (deferredAttrContext.phase.isVarargsRequired()) { 904 if (deferredAttrContext.mode == AttrMode.CHECK || !checkVarargsAccessAfterResolution) { 905 varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext); 906 } 907 } 908 } 909 910 /** 911 * Test that the runtime array element type corresponding to 't' is accessible. 't' should be the 912 * varargs element type of either the method invocation type signature (after inference completes) 913 * or the method declaration signature (before inference completes). 914 */ 915 private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) { 916 if (inferenceContext.free(t)) { 917 inferenceContext.addFreeTypeListener(List.of(t), 918 solvedContext -> varargsAccessible(env, solvedContext.asInstType(t), solvedContext)); 919 } else { 920 if (!isAccessible(env, types.erasure(t))) { 921 Symbol location = env.enclClass.sym; 922 reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); 923 } 924 } 925 } 926 927 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, 928 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { 929 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { 930 MethodCheckDiag methodDiag = varargsCheck ? 931 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; 932 933 @Override 934 public void report(DiagnosticPosition pos, JCDiagnostic details) { 935 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); 936 } 937 }; 938 return new MethodResultInfo(to, checkContext); 939 } 940 941 @Override 942 public MethodCheck mostSpecificCheck(List<Type> actuals) { 943 return new MostSpecificCheck(actuals); 944 } 945 946 @Override 947 public String toString() { 948 return "resolveMethodCheck"; 949 } 950 }; 951 952 /** 953 * This class handles method reference applicability checks; since during 954 * these checks it's sometime possible to have inference variables on 955 * the actual argument types list, the method applicability check must be 956 * extended so that inference variables are 'opened' as needed. 957 */ 958 class MethodReferenceCheck extends AbstractMethodCheck { 959 960 InferenceContext pendingInferenceContext; 961 962 MethodReferenceCheck(InferenceContext pendingInferenceContext) { 963 this.pendingInferenceContext = pendingInferenceContext; 964 } 965 966 @Override 967 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { 968 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); 969 mresult.check(pos, actual); 970 } 971 972 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to, 973 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) { 974 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) { 975 MethodCheckDiag methodDiag = varargsCheck ? 976 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH; 977 978 @Override 979 public boolean compatible(Type found, Type req, Warner warn) { 980 found = pendingInferenceContext.asUndetVar(found); 981 if (found.hasTag(UNDETVAR) && req.isPrimitive()) { 982 req = types.boxedClass(req).type; 983 } 984 return super.compatible(found, req, warn); 985 } 986 987 @Override 988 public void report(DiagnosticPosition pos, JCDiagnostic details) { 989 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); 990 } 991 }; 992 return new MethodResultInfo(to, checkContext); 993 } 994 995 @Override 996 public MethodCheck mostSpecificCheck(List<Type> actuals) { 997 return new MostSpecificCheck(actuals); 998 } 999 1000 @Override 1001 public String toString() { 1002 return "MethodReferenceCheck"; 1003 } 1004 } 1005 1006 /** 1007 * Check context to be used during method applicability checks. A method check 1008 * context might contain inference variables. 1009 */ 1010 abstract class MethodCheckContext implements CheckContext { 1011 1012 boolean strict; 1013 DeferredAttrContext deferredAttrContext; 1014 Warner rsWarner; 1015 1016 public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) { 1017 this.strict = strict; 1018 this.deferredAttrContext = deferredAttrContext; 1019 this.rsWarner = rsWarner; 1020 } 1021 1022 public boolean compatible(Type found, Type req, Warner warn) { 1023 InferenceContext inferenceContext = deferredAttrContext.inferenceContext; 1024 return strict ? 1025 types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) : 1026 types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn); 1027 } 1028 1029 public void report(DiagnosticPosition pos, JCDiagnostic details) { 1030 throw new InapplicableMethodException(details); 1031 } 1032 1033 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) { 1034 return rsWarner; 1035 } 1036 1037 public InferenceContext inferenceContext() { 1038 return deferredAttrContext.inferenceContext; 1039 } 1040 1041 public DeferredAttrContext deferredAttrContext() { 1042 return deferredAttrContext; 1043 } 1044 1045 @Override 1046 public String toString() { 1047 return "MethodCheckContext"; 1048 } 1049 } 1050 1051 /** 1052 * ResultInfo class to be used during method applicability checks. Check 1053 * for deferred types goes through special path. 1054 */ 1055 class MethodResultInfo extends ResultInfo { 1056 1057 public MethodResultInfo(Type pt, CheckContext checkContext) { 1058 attr.super(KindSelector.VAL, pt, checkContext); 1059 } 1060 1061 @Override 1062 protected Type check(DiagnosticPosition pos, Type found) { 1063 if (found.hasTag(DEFERRED)) { 1064 DeferredType dt = (DeferredType)found; 1065 return dt.check(this); 1066 } else { 1067 Type uResult = U(found); 1068 Type capturedType = pos == null || pos.getTree() == null ? 1069 types.capture(uResult) : 1070 checkContext.inferenceContext() 1071 .cachedCapture(pos.getTree(), uResult, true); 1072 return super.check(pos, chk.checkNonVoid(pos, capturedType)); 1073 } 1074 } 1075 1076 /** 1077 * javac has a long-standing 'simplification' (see 6391995): 1078 * given an actual argument type, the method check is performed 1079 * on its upper bound. This leads to inconsistencies when an 1080 * argument type is checked against itself. For example, given 1081 * a type-variable T, it is not true that {@code U(T) <: T}, 1082 * so we need to guard against that. 1083 */ 1084 private Type U(Type found) { 1085 return found == pt ? 1086 found : types.cvarUpperBound(found); 1087 } 1088 1089 @Override 1090 protected MethodResultInfo dup(Type newPt) { 1091 return new MethodResultInfo(newPt, checkContext); 1092 } 1093 1094 @Override 1095 protected ResultInfo dup(CheckContext newContext) { 1096 return new MethodResultInfo(pt, newContext); 1097 } 1098 1099 @Override 1100 protected ResultInfo dup(Type newPt, CheckContext newContext) { 1101 return new MethodResultInfo(newPt, newContext); 1102 } 1103 } 1104 1105 /** 1106 * Most specific method applicability routine. Given a list of actual types A, 1107 * a list of formal types F1, and a list of formal types F2, the routine determines 1108 * as to whether the types in F1 can be considered more specific than those in F2 w.r.t. 1109 * argument types A. 1110 */ 1111 class MostSpecificCheck implements MethodCheck { 1112 1113 List<Type> actuals; 1114 1115 MostSpecificCheck(List<Type> actuals) { 1116 this.actuals = actuals; 1117 } 1118 1119 @Override 1120 public void argumentsAcceptable(final Env<AttrContext> env, 1121 DeferredAttrContext deferredAttrContext, 1122 List<Type> formals1, 1123 List<Type> formals2, 1124 Warner warn) { 1125 formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired()); 1126 while (formals2.nonEmpty()) { 1127 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head); 1128 mresult.check(null, formals1.head); 1129 formals1 = formals1.tail; 1130 formals2 = formals2.tail; 1131 actuals = actuals.isEmpty() ? actuals : actuals.tail; 1132 } 1133 } 1134 1135 /** 1136 * Create a method check context to be used during the most specific applicability check 1137 */ 1138 ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext, 1139 Warner rsWarner, Type actual) { 1140 return attr.new ResultInfo(KindSelector.VAL, to, 1141 new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual)); 1142 } 1143 1144 /** 1145 * Subclass of method check context class that implements most specific 1146 * method conversion. If the actual type under analysis is a deferred type 1147 * a full blown structural analysis is carried out. 1148 */ 1149 class MostSpecificCheckContext extends MethodCheckContext { 1150 1151 Type actual; 1152 1153 public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) { 1154 super(true, deferredAttrContext, rsWarner); 1155 this.actual = actual; 1156 } 1157 1158 public boolean compatible(Type found, Type req, Warner warn) { 1159 if (allowFunctionalInterfaceMostSpecific && 1160 unrelatedFunctionalInterfaces(found, req) && 1161 (actual != null && actual.getTag() == DEFERRED)) { 1162 DeferredType dt = (DeferredType) actual; 1163 JCTree speculativeTree = dt.speculativeTree(deferredAttrContext); 1164 if (speculativeTree != deferredAttr.stuckTree) { 1165 return functionalInterfaceMostSpecific(found, req, speculativeTree); 1166 } 1167 } 1168 return compatibleBySubtyping(found, req); 1169 } 1170 1171 private boolean compatibleBySubtyping(Type found, Type req) { 1172 if (!strict && found.isPrimitive() != req.isPrimitive()) { 1173 found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found); 1174 } 1175 return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req)); 1176 } 1177 1178 /** Whether {@code t} and {@code s} are unrelated functional interface types. */ 1179 private boolean unrelatedFunctionalInterfaces(Type t, Type s) { 1180 return types.isFunctionalInterface(t.tsym) && 1181 types.isFunctionalInterface(s.tsym) && 1182 unrelatedInterfaces(t, s); 1183 } 1184 1185 /** Whether {@code t} and {@code s} are unrelated interface types; recurs on intersections. **/ 1186 private boolean unrelatedInterfaces(Type t, Type s) { 1187 if (t.isCompound()) { 1188 for (Type ti : types.interfaces(t)) { 1189 if (!unrelatedInterfaces(ti, s)) { 1190 return false; 1191 } 1192 } 1193 return true; 1194 } else if (s.isCompound()) { 1195 for (Type si : types.interfaces(s)) { 1196 if (!unrelatedInterfaces(t, si)) { 1197 return false; 1198 } 1199 } 1200 return true; 1201 } else { 1202 return types.asSuper(t, s.tsym) == null && types.asSuper(s, t.tsym) == null; 1203 } 1204 } 1205 1206 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */ 1207 private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) { 1208 Type tDesc = types.findDescriptorType(types.capture(t)); 1209 Type tDescNoCapture = types.findDescriptorType(t); 1210 Type sDesc = types.findDescriptorType(s); 1211 final List<Type> tTypeParams = tDesc.getTypeArguments(); 1212 final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments(); 1213 final List<Type> sTypeParams = sDesc.getTypeArguments(); 1214 1215 // compare type parameters 1216 if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) { 1217 return false; 1218 } 1219 // can't use Types.hasSameBounds on sDesc because bounds may have ivars 1220 List<Type> tIter = tTypeParams; 1221 List<Type> sIter = sTypeParams; 1222 while (tIter.nonEmpty() && sIter.nonEmpty()) { 1223 Type tBound = tIter.head.getUpperBound(); 1224 Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams); 1225 if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) { 1226 return false; 1227 } 1228 if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) { 1229 return false; 1230 } 1231 tIter = tIter.tail; 1232 sIter = sIter.tail; 1233 } 1234 if (!tIter.isEmpty() || !sIter.isEmpty()) { 1235 return false; 1236 } 1237 1238 // compare parameters 1239 List<Type> tParams = tDesc.getParameterTypes(); 1240 List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes(); 1241 List<Type> sParams = sDesc.getParameterTypes(); 1242 while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) { 1243 Type tParam = tParams.head; 1244 Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams); 1245 Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams); 1246 if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) { 1247 return false; 1248 } 1249 if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) { 1250 return false; 1251 } 1252 if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) { 1253 return false; 1254 } 1255 tParams = tParams.tail; 1256 tParamsNoCapture = tParamsNoCapture.tail; 1257 sParams = sParams.tail; 1258 } 1259 if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) { 1260 return false; 1261 } 1262 1263 // compare returns 1264 Type tRet = tDesc.getReturnType(); 1265 Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams); 1266 if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) { 1267 return false; 1268 } 1269 MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet); 1270 msc.scan(tree); 1271 return msc.result; 1272 } 1273 1274 /** 1275 * Tests whether one functional interface type can be considered more specific 1276 * than another unrelated functional interface type for the scanned expression. 1277 */ 1278 class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner { 1279 1280 final Type tRet; 1281 final Type sRet; 1282 boolean result; 1283 1284 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */ 1285 MostSpecificFunctionReturnChecker(Type tRet, Type sRet) { 1286 this.tRet = tRet; 1287 this.sRet = sRet; 1288 result = true; 1289 } 1290 1291 @Override 1292 void skip(JCTree tree) { 1293 result &= false; 1294 } 1295 1296 @Override 1297 public void visitConditional(JCConditional tree) { 1298 scan(asExpr(tree.truepart)); 1299 scan(asExpr(tree.falsepart)); 1300 } 1301 1302 @Override 1303 public void visitReference(JCMemberReference tree) { 1304 if (sRet.hasTag(VOID)) { 1305 result &= true; 1306 } else if (tRet.hasTag(VOID)) { 1307 result &= false; 1308 } else if (tRet.isPrimitive() != sRet.isPrimitive()) { 1309 boolean retValIsPrimitive = 1310 tree.refPolyKind == PolyKind.STANDALONE && 1311 tree.sym.type.getReturnType().isPrimitive(); 1312 result &= (retValIsPrimitive == tRet.isPrimitive()) && 1313 (retValIsPrimitive != sRet.isPrimitive()); 1314 } else { 1315 result &= compatibleBySubtyping(tRet, sRet); 1316 } 1317 } 1318 1319 @Override 1320 public void visitParens(JCParens tree) { 1321 scan(asExpr(tree.expr)); 1322 } 1323 1324 @Override 1325 public void visitLambda(JCLambda tree) { 1326 if (sRet.hasTag(VOID)) { 1327 result &= true; 1328 } else if (tRet.hasTag(VOID)) { 1329 result &= false; 1330 } else { 1331 List<JCExpression> lambdaResults = lambdaResults(tree); 1332 if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) { 1333 for (JCExpression expr : lambdaResults) { 1334 result &= functionalInterfaceMostSpecific(tRet, sRet, expr); 1335 } 1336 } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) { 1337 for (JCExpression expr : lambdaResults) { 1338 boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive(); 1339 result &= (retValIsPrimitive == tRet.isPrimitive()) && 1340 (retValIsPrimitive != sRet.isPrimitive()); 1341 } 1342 } else { 1343 result &= compatibleBySubtyping(tRet, sRet); 1344 } 1345 } 1346 } 1347 //where 1348 1349 private List<JCExpression> lambdaResults(JCLambda lambda) { 1350 if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) { 1351 return List.of(asExpr((JCExpression) lambda.body)); 1352 } else { 1353 final ListBuffer<JCExpression> buffer = new ListBuffer<>(); 1354 DeferredAttr.LambdaReturnScanner lambdaScanner = 1355 new DeferredAttr.LambdaReturnScanner() { 1356 @Override 1357 public void visitReturn(JCReturn tree) { 1358 if (tree.expr != null) { 1359 buffer.append(asExpr(tree.expr)); 1360 } 1361 } 1362 }; 1363 lambdaScanner.scan(lambda.body); 1364 return buffer.toList(); 1365 } 1366 } 1367 1368 private JCExpression asExpr(JCExpression expr) { 1369 if (expr.type.hasTag(DEFERRED)) { 1370 JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext); 1371 if (speculativeTree != deferredAttr.stuckTree) { 1372 expr = (JCExpression)speculativeTree; 1373 } 1374 } 1375 return expr; 1376 } 1377 } 1378 1379 } 1380 1381 public MethodCheck mostSpecificCheck(List<Type> actuals) { 1382 Assert.error("Cannot get here!"); 1383 return null; 1384 } 1385 } 1386 1387 public static class InapplicableMethodException extends RuntimeException { 1388 private static final long serialVersionUID = 0; 1389 1390 transient JCDiagnostic diagnostic; 1391 1392 InapplicableMethodException(JCDiagnostic diag) { 1393 this.diagnostic = diag; 1394 } 1395 1396 public JCDiagnostic getDiagnostic() { 1397 return diagnostic; 1398 } 1399 } 1400 1401 /* *************************************************************************** 1402 * Symbol lookup 1403 * the following naming conventions for arguments are used 1404 * 1405 * env is the environment where the symbol was mentioned 1406 * site is the type of which the symbol is a member 1407 * name is the symbol's name 1408 * if no arguments are given 1409 * argtypes are the value arguments, if we search for a method 1410 * 1411 * If no symbol was found, a ResolveError detailing the problem is returned. 1412 ****************************************************************************/ 1413 1414 /** Find field. Synthetic fields are always skipped. 1415 * @param env The current environment. 1416 * @param site The original type from where the selection takes place. 1417 * @param name The name of the field. 1418 * @param c The class to search for the field. This is always 1419 * a superclass or implemented interface of site's class. 1420 */ 1421 Symbol findField(Env<AttrContext> env, 1422 Type site, 1423 Name name, 1424 TypeSymbol c) { 1425 while (c.type.hasTag(TYPEVAR)) 1426 c = c.type.getUpperBound().tsym; 1427 Symbol bestSoFar = varNotFound; 1428 Symbol sym; 1429 for (Symbol s : c.members().getSymbolsByName(name)) { 1430 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) { 1431 return isAccessible(env, site, s) 1432 ? s : new AccessError(env, site, s); 1433 } 1434 } 1435 Type st = types.supertype(c.type); 1436 if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) { 1437 sym = findField(env, site, name, st.tsym); 1438 bestSoFar = bestOf(bestSoFar, sym); 1439 } 1440 for (List<Type> l = types.interfaces(c.type); 1441 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1442 l = l.tail) { 1443 sym = findField(env, site, name, l.head.tsym); 1444 if (bestSoFar.exists() && sym.exists() && 1445 sym.owner != bestSoFar.owner) 1446 bestSoFar = new AmbiguityError(bestSoFar, sym); 1447 else 1448 bestSoFar = bestOf(bestSoFar, sym); 1449 } 1450 return bestSoFar; 1451 } 1452 1453 /** Resolve a field identifier, throw a fatal error if not found. 1454 * @param pos The position to use for error reporting. 1455 * @param env The environment current at the method invocation. 1456 * @param site The type of the qualifying expression, in which 1457 * identifier is searched. 1458 * @param name The identifier's name. 1459 */ 1460 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env, 1461 Type site, Name name) { 1462 Symbol sym = findField(env, site, name, site.tsym); 1463 if (sym.kind == VAR) return (VarSymbol)sym; 1464 else throw new FatalError( 1465 diags.fragment(Fragments.FatalErrCantLocateField(name))); 1466 } 1467 1468 /** Find unqualified variable or field with given name. 1469 * Synthetic fields always skipped. 1470 * @param env The current environment. 1471 * @param name The name of the variable or field. 1472 */ 1473 Symbol findVar(Env<AttrContext> env, Name name) { 1474 Symbol bestSoFar = varNotFound; 1475 Env<AttrContext> env1 = env; 1476 boolean staticOnly = false; 1477 while (env1.outer != null) { 1478 Symbol sym = null; 1479 if (isStatic(env1)) staticOnly = true; 1480 for (Symbol s : env1.info.scope.getSymbolsByName(name)) { 1481 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) { 1482 sym = s; 1483 break; 1484 } 1485 } 1486 if (sym == null) { 1487 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym); 1488 } 1489 if (sym.exists()) { 1490 if (staticOnly && 1491 sym.kind == VAR && 1492 sym.owner.kind == TYP && 1493 (sym.flags() & STATIC) == 0) 1494 return new StaticError(sym); 1495 else 1496 return sym; 1497 } else { 1498 bestSoFar = bestOf(bestSoFar, sym); 1499 } 1500 1501 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1502 env1 = env1.outer; 1503 } 1504 1505 Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass); 1506 if (sym.exists()) 1507 return sym; 1508 if (bestSoFar.exists()) 1509 return bestSoFar; 1510 1511 Symbol origin = null; 1512 for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) { 1513 for (Symbol currentSymbol : sc.getSymbolsByName(name)) { 1514 if (currentSymbol.kind != VAR) 1515 continue; 1516 // invariant: sym.kind == Symbol.Kind.VAR 1517 if (!bestSoFar.kind.isResolutionError() && 1518 currentSymbol.owner != bestSoFar.owner) 1519 return new AmbiguityError(bestSoFar, currentSymbol); 1520 else if (!bestSoFar.kind.betterThan(VAR)) { 1521 origin = sc.getOrigin(currentSymbol).owner; 1522 bestSoFar = isAccessible(env, origin.type, currentSymbol) 1523 ? currentSymbol : new AccessError(env, origin.type, currentSymbol); 1524 } 1525 } 1526 if (bestSoFar.exists()) break; 1527 } 1528 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type) 1529 return bestSoFar.clone(origin); 1530 else 1531 return bestSoFar; 1532 } 1533 1534 Warner noteWarner = new Warner(); 1535 1536 /** Select the best method for a call site among two choices. 1537 * @param env The current environment. 1538 * @param site The original type from where the 1539 * selection takes place. 1540 * @param argtypes The invocation's value arguments, 1541 * @param typeargtypes The invocation's type arguments, 1542 * @param sym Proposed new best match. 1543 * @param bestSoFar Previously found best match. 1544 * @param allowBoxing Allow boxing conversions of arguments. 1545 * @param useVarargs Box trailing arguments into an array for varargs. 1546 */ 1547 @SuppressWarnings("fallthrough") 1548 Symbol selectBest(Env<AttrContext> env, 1549 Type site, 1550 List<Type> argtypes, 1551 List<Type> typeargtypes, 1552 Symbol sym, 1553 Symbol bestSoFar, 1554 boolean allowBoxing, 1555 boolean useVarargs) { 1556 if (sym.kind == ERR || 1557 (site.tsym != sym.owner && !sym.isInheritedIn(site.tsym, types)) || 1558 !notOverriddenIn(site, sym)) { 1559 return bestSoFar; 1560 } else if (useVarargs && (sym.flags() & VARARGS) == 0) { 1561 return bestSoFar.kind.isResolutionError() ? 1562 new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) : 1563 bestSoFar; 1564 } 1565 Assert.check(!sym.kind.isResolutionError()); 1566 try { 1567 types.noWarnings.clear(); 1568 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, 1569 allowBoxing, useVarargs, types.noWarnings); 1570 currentResolutionContext.addApplicableCandidate(sym, mt); 1571 } catch (InapplicableMethodException ex) { 1572 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); 1573 switch (bestSoFar.kind) { 1574 case ABSENT_MTH: 1575 return new InapplicableSymbolError(currentResolutionContext); 1576 case WRONG_MTH: 1577 bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1578 default: 1579 return bestSoFar; 1580 } 1581 } 1582 if (!isAccessible(env, site, sym)) { 1583 return (bestSoFar.kind == ABSENT_MTH) 1584 ? new AccessError(env, site, sym) 1585 : bestSoFar; 1586 } 1587 return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS) 1588 ? sym 1589 : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs); 1590 } 1591 1592 /* Return the most specific of the two methods for a call, 1593 * given that both are accessible and applicable. 1594 * @param m1 A new candidate for most specific. 1595 * @param m2 The previous most specific candidate. 1596 * @param env The current environment. 1597 * @param site The original type from where the selection 1598 * takes place. 1599 * @param allowBoxing Allow boxing conversions of arguments. 1600 * @param useVarargs Box trailing arguments into an array for varargs. 1601 */ 1602 Symbol mostSpecific(List<Type> argtypes, Symbol m1, 1603 Symbol m2, 1604 Env<AttrContext> env, 1605 final Type site, 1606 boolean useVarargs) { 1607 switch (m2.kind) { 1608 case MTH: 1609 if (m1 == m2) return m1; 1610 boolean m1SignatureMoreSpecific = 1611 signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs); 1612 boolean m2SignatureMoreSpecific = 1613 signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs); 1614 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 1615 Type mt1 = types.memberType(site, m1); 1616 Type mt2 = types.memberType(site, m2); 1617 if (!types.overrideEquivalent(mt1, mt2)) 1618 return ambiguityError(m1, m2); 1619 1620 // same signature; select (a) the non-bridge method, or 1621 // (b) the one that overrides the other, or (c) the concrete 1622 // one, or (d) merge both abstract signatures 1623 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) 1624 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 1625 1626 if (m1.baseSymbol() == m2.baseSymbol()) { 1627 // this is the same imported symbol which has been cloned twice. 1628 // Return the first one (either will do). 1629 return m1; 1630 } 1631 1632 // if one overrides or hides the other, use it 1633 TypeSymbol m1Owner = (TypeSymbol)m1.owner; 1634 TypeSymbol m2Owner = (TypeSymbol)m2.owner; 1635 // the two owners can never be the same if the target methods are compiled from source, 1636 // but we need to protect against cases where the methods are defined in some classfile 1637 // and make sure we issue an ambiguity error accordingly (by skipping the logic below). 1638 if (m1Owner != m2Owner) { 1639 if (types.asSuper(m1Owner.type, m2Owner) != null && 1640 ((m1.owner.flags_field & INTERFACE) == 0 || 1641 (m2.owner.flags_field & INTERFACE) != 0) && 1642 m1.overrides(m2, m1Owner, types, false)) 1643 return m1; 1644 if (types.asSuper(m2Owner.type, m1Owner) != null && 1645 ((m2.owner.flags_field & INTERFACE) == 0 || 1646 (m1.owner.flags_field & INTERFACE) != 0) && 1647 m2.overrides(m1, m2Owner, types, false)) 1648 return m2; 1649 } 1650 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; 1651 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; 1652 if (m1Abstract && !m2Abstract) return m2; 1653 if (m2Abstract && !m1Abstract) return m1; 1654 // both abstract or both concrete 1655 return ambiguityError(m1, m2); 1656 } 1657 if (m1SignatureMoreSpecific) return m1; 1658 if (m2SignatureMoreSpecific) return m2; 1659 return ambiguityError(m1, m2); 1660 case AMBIGUOUS: 1661 //compare m1 to ambiguous methods in m2 1662 AmbiguityError e = (AmbiguityError)m2.baseSymbol(); 1663 boolean m1MoreSpecificThanAnyAmbiguous = true; 1664 boolean allAmbiguousMoreSpecificThanM1 = true; 1665 for (Symbol s : e.ambiguousSyms) { 1666 Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs); 1667 m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1; 1668 allAmbiguousMoreSpecificThanM1 &= moreSpecific == s; 1669 } 1670 if (m1MoreSpecificThanAnyAmbiguous) 1671 return m1; 1672 //if m1 is more specific than some ambiguous methods, but other ambiguous methods are 1673 //more specific than m1, add it as a new ambiguous method: 1674 if (!allAmbiguousMoreSpecificThanM1) 1675 e.addAmbiguousSymbol(m1); 1676 return e; 1677 default: 1678 throw new AssertionError(); 1679 } 1680 } 1681 //where 1682 private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) { 1683 noteWarner.clear(); 1684 int maxLength = Math.max( 1685 Math.max(m1.type.getParameterTypes().length(), actuals.length()), 1686 m2.type.getParameterTypes().length()); 1687 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1688 try { 1689 currentResolutionContext = new MethodResolutionContext(); 1690 currentResolutionContext.step = prevResolutionContext.step; 1691 currentResolutionContext.methodCheck = 1692 prevResolutionContext.methodCheck.mostSpecificCheck(actuals); 1693 Type mst = instantiate(env, site, m2, null, 1694 adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null, 1695 false, useVarargs, noteWarner); 1696 return mst != null && 1697 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); 1698 } finally { 1699 currentResolutionContext = prevResolutionContext; 1700 } 1701 } 1702 1703 List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) { 1704 if ((msym.flags() & VARARGS) != 0 && allowVarargs) { 1705 Type varargsElem = types.elemtype(args.last()); 1706 if (varargsElem == null) { 1707 Assert.error("Bad varargs = " + args.last() + " " + msym); 1708 } 1709 List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse(); 1710 while (newArgs.length() < length) { 1711 newArgs = newArgs.append(newArgs.last()); 1712 } 1713 return newArgs; 1714 } else { 1715 return args; 1716 } 1717 } 1718 //where 1719 Symbol ambiguityError(Symbol m1, Symbol m2) { 1720 if (((m1.flags() | m2.flags()) & CLASH) != 0) { 1721 return (m1.flags() & CLASH) == 0 ? m1 : m2; 1722 } else { 1723 return new AmbiguityError(m1, m2); 1724 } 1725 } 1726 1727 Symbol findMethodInScope(Env<AttrContext> env, 1728 Type site, 1729 Name name, 1730 List<Type> argtypes, 1731 List<Type> typeargtypes, 1732 Scope sc, 1733 Symbol bestSoFar, 1734 boolean allowBoxing, 1735 boolean useVarargs, 1736 boolean abstractok) { 1737 for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) { 1738 bestSoFar = selectBest(env, site, argtypes, typeargtypes, s, 1739 bestSoFar, allowBoxing, useVarargs); 1740 } 1741 return bestSoFar; 1742 } 1743 //where 1744 class LookupFilter implements Filter<Symbol> { 1745 1746 boolean abstractOk; 1747 1748 LookupFilter(boolean abstractOk) { 1749 this.abstractOk = abstractOk; 1750 } 1751 1752 public boolean accepts(Symbol s) { 1753 long flags = s.flags(); 1754 return s.kind == MTH && 1755 (flags & SYNTHETIC) == 0 && 1756 (abstractOk || 1757 (flags & DEFAULT) != 0 || 1758 (flags & ABSTRACT) == 0); 1759 } 1760 } 1761 1762 /** Find best qualified method matching given name, type and value 1763 * arguments. 1764 * @param env The current environment. 1765 * @param site The original type from where the selection 1766 * takes place. 1767 * @param name The method's name. 1768 * @param argtypes The method's value arguments. 1769 * @param typeargtypes The method's type arguments 1770 * @param allowBoxing Allow boxing conversions of arguments. 1771 * @param useVarargs Box trailing arguments into an array for varargs. 1772 */ 1773 Symbol findMethod(Env<AttrContext> env, 1774 Type site, 1775 Name name, 1776 List<Type> argtypes, 1777 List<Type> typeargtypes, 1778 boolean allowBoxing, 1779 boolean useVarargs) { 1780 Symbol bestSoFar = methodNotFound; 1781 bestSoFar = findMethod(env, 1782 site, 1783 name, 1784 argtypes, 1785 typeargtypes, 1786 site.tsym.type, 1787 bestSoFar, 1788 allowBoxing, 1789 useVarargs); 1790 return bestSoFar; 1791 } 1792 // where 1793 private Symbol findMethod(Env<AttrContext> env, 1794 Type site, 1795 Name name, 1796 List<Type> argtypes, 1797 List<Type> typeargtypes, 1798 Type intype, 1799 Symbol bestSoFar, 1800 boolean allowBoxing, 1801 boolean useVarargs) { 1802 @SuppressWarnings({"unchecked","rawtypes"}) 1803 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() }; 1804 1805 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK; 1806 for (TypeSymbol s : superclasses(intype)) { 1807 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1808 s.members(), bestSoFar, allowBoxing, useVarargs, true); 1809 if (name == names.init) return bestSoFar; 1810 iphase = (iphase == null) ? null : iphase.update(s, this); 1811 if (iphase != null) { 1812 for (Type itype : types.interfaces(s.type)) { 1813 itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]); 1814 } 1815 } 1816 } 1817 1818 Symbol concrete = bestSoFar.kind.isValid() && 1819 (bestSoFar.flags() & ABSTRACT) == 0 ? 1820 bestSoFar : methodNotFound; 1821 1822 for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) { 1823 //keep searching for abstract methods 1824 for (Type itype : itypes[iphase2.ordinal()]) { 1825 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure()) 1826 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && 1827 (itype.tsym.flags() & DEFAULT) == 0) continue; 1828 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1829 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true); 1830 if (concrete != bestSoFar && 1831 concrete.kind.isValid() && 1832 bestSoFar.kind.isValid() && 1833 types.isSubSignature(concrete.type, bestSoFar.type)) { 1834 //this is an hack - as javac does not do full membership checks 1835 //most specific ends up comparing abstract methods that might have 1836 //been implemented by some concrete method in a subclass and, 1837 //because of raw override, it is possible for an abstract method 1838 //to be more specific than the concrete method - so we need 1839 //to explicitly call that out (see CR 6178365) 1840 bestSoFar = concrete; 1841 } 1842 } 1843 } 1844 return bestSoFar; 1845 } 1846 1847 enum InterfaceLookupPhase { 1848 ABSTRACT_OK() { 1849 @Override 1850 InterfaceLookupPhase update(Symbol s, Resolve rs) { 1851 //We should not look for abstract methods if receiver is a concrete class 1852 //(as concrete classes are expected to implement all abstracts coming 1853 //from superinterfaces) 1854 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) { 1855 return this; 1856 } else { 1857 return DEFAULT_OK; 1858 } 1859 } 1860 }, 1861 DEFAULT_OK() { 1862 @Override 1863 InterfaceLookupPhase update(Symbol s, Resolve rs) { 1864 return this; 1865 } 1866 }; 1867 1868 abstract InterfaceLookupPhase update(Symbol s, Resolve rs); 1869 } 1870 1871 /** 1872 * Return an Iterable object to scan the superclasses of a given type. 1873 * It's crucial that the scan is done lazily, as we don't want to accidentally 1874 * access more supertypes than strictly needed (as this could trigger completion 1875 * errors if some of the not-needed supertypes are missing/ill-formed). 1876 */ 1877 Iterable<TypeSymbol> superclasses(final Type intype) { 1878 return () -> new Iterator<TypeSymbol>() { 1879 1880 List<TypeSymbol> seen = List.nil(); 1881 TypeSymbol currentSym = symbolFor(intype); 1882 TypeSymbol prevSym = null; 1883 1884 public boolean hasNext() { 1885 if (currentSym == syms.noSymbol) { 1886 currentSym = symbolFor(types.supertype(prevSym.type)); 1887 } 1888 return currentSym != null; 1889 } 1890 1891 public TypeSymbol next() { 1892 prevSym = currentSym; 1893 currentSym = syms.noSymbol; 1894 Assert.check(prevSym != null || prevSym != syms.noSymbol); 1895 return prevSym; 1896 } 1897 1898 public void remove() { 1899 throw new UnsupportedOperationException(); 1900 } 1901 1902 TypeSymbol symbolFor(Type t) { 1903 if (!t.hasTag(CLASS) && 1904 !t.hasTag(TYPEVAR)) { 1905 return null; 1906 } 1907 t = types.skipTypeVars(t, false); 1908 if (seen.contains(t.tsym)) { 1909 //degenerate case in which we have a circular 1910 //class hierarchy - because of ill-formed classfiles 1911 return null; 1912 } 1913 seen = seen.prepend(t.tsym); 1914 return t.tsym; 1915 } 1916 }; 1917 } 1918 1919 /** Find unqualified method matching given name, type and value arguments. 1920 * @param env The current environment. 1921 * @param name The method's name. 1922 * @param argtypes The method's value arguments. 1923 * @param typeargtypes The method's type arguments. 1924 * @param allowBoxing Allow boxing conversions of arguments. 1925 * @param useVarargs Box trailing arguments into an array for varargs. 1926 */ 1927 Symbol findFun(Env<AttrContext> env, Name name, 1928 List<Type> argtypes, List<Type> typeargtypes, 1929 boolean allowBoxing, boolean useVarargs) { 1930 Symbol bestSoFar = methodNotFound; 1931 Env<AttrContext> env1 = env; 1932 boolean staticOnly = false; 1933 while (env1.outer != null) { 1934 if (isStatic(env1)) staticOnly = true; 1935 Assert.check(env1.info.preferredTreeForDiagnostics == null); 1936 env1.info.preferredTreeForDiagnostics = env.tree; 1937 try { 1938 Symbol sym = findMethod( 1939 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 1940 allowBoxing, useVarargs); 1941 if (sym.exists()) { 1942 if (staticOnly && 1943 sym.kind == MTH && 1944 sym.owner.kind == TYP && 1945 (sym.flags() & STATIC) == 0) return new StaticError(sym); 1946 else return sym; 1947 } else { 1948 bestSoFar = bestOf(bestSoFar, sym); 1949 } 1950 } finally { 1951 env1.info.preferredTreeForDiagnostics = null; 1952 } 1953 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1954 env1 = env1.outer; 1955 } 1956 1957 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 1958 typeargtypes, allowBoxing, useVarargs); 1959 if (sym.exists()) 1960 return sym; 1961 1962 for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) { 1963 Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner; 1964 if (currentSym.kind == MTH) { 1965 if (currentSym.owner.type != origin.type) 1966 currentSym = currentSym.clone(origin); 1967 if (!isAccessible(env, origin.type, currentSym)) 1968 currentSym = new AccessError(env, origin.type, currentSym); 1969 bestSoFar = selectBest(env, origin.type, 1970 argtypes, typeargtypes, 1971 currentSym, bestSoFar, 1972 allowBoxing, useVarargs); 1973 } 1974 } 1975 if (bestSoFar.exists()) 1976 return bestSoFar; 1977 1978 for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) { 1979 Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner; 1980 if (currentSym.kind == MTH) { 1981 if (currentSym.owner.type != origin.type) 1982 currentSym = currentSym.clone(origin); 1983 if (!isAccessible(env, origin.type, currentSym)) 1984 currentSym = new AccessError(env, origin.type, currentSym); 1985 bestSoFar = selectBest(env, origin.type, 1986 argtypes, typeargtypes, 1987 currentSym, bestSoFar, 1988 allowBoxing, useVarargs); 1989 } 1990 } 1991 return bestSoFar; 1992 } 1993 1994 /** Load toplevel or member class with given fully qualified name and 1995 * verify that it is accessible. 1996 * @param env The current environment. 1997 * @param name The fully qualified name of the class to be loaded. 1998 */ 1999 Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) { 2000 try { 2001 ClassSymbol c = finder.loadClass(env.toplevel.modle, name); 2002 return isAccessible(env, c) ? c : new AccessError(env, null, c); 2003 } catch (ClassFinder.BadClassFile err) { 2004 return new BadClassFileError(err); 2005 } catch (CompletionFailure ex) { 2006 Symbol candidate = recoveryLoadClass.loadClass(env, name); 2007 2008 if (candidate != null) { 2009 return candidate; 2010 } 2011 2012 return typeNotFound; 2013 } 2014 } 2015 2016 public interface RecoveryLoadClass { 2017 Symbol loadClass(Env<AttrContext> env, Name name); 2018 } 2019 2020 private final RecoveryLoadClass noRecovery = (env, name) -> null; 2021 2022 private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() { 2023 @Override public Symbol loadClass(Env<AttrContext> env, Name name) { 2024 List<Name> candidates = Convert.classCandidates(name); 2025 return lookupInvisibleSymbol(env, name, 2026 n -> () -> createCompoundIterator(candidates, 2027 c -> syms.getClassesForName(c) 2028 .iterator()), 2029 (ms, n) -> { 2030 for (Name candidate : candidates) { 2031 try { 2032 return finder.loadClass(ms, candidate); 2033 } catch (CompletionFailure cf) { 2034 //ignore 2035 } 2036 } 2037 return null; 2038 }, sym -> sym.kind == Kind.TYP, typeNotFound); 2039 } 2040 }; 2041 2042 private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> { 2043 Scope importScope = env.toplevel.namedImportScope; 2044 Symbol existing = importScope.findFirst(Convert.shortName(name), 2045 sym -> sym.kind == TYP && sym.flatName() == name); 2046 2047 if (existing != null) { 2048 return new InvisibleSymbolError(env, true, existing); 2049 } 2050 return null; 2051 }; 2052 2053 private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> { 2054 Scope importScope = env.toplevel.starImportScope; 2055 Symbol existing = importScope.findFirst(Convert.shortName(name), 2056 sym -> sym.kind == TYP && sym.flatName() == name); 2057 2058 if (existing != null) { 2059 try { 2060 existing = finder.loadClass(existing.packge().modle, name); 2061 2062 return new InvisibleSymbolError(env, true, existing); 2063 } catch (CompletionFailure cf) { 2064 //ignore 2065 } 2066 } 2067 2068 return null; 2069 }; 2070 2071 Symbol lookupPackage(Env<AttrContext> env, Name name) { 2072 PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name); 2073 2074 if (allowModules && isImportOnDemand(env, name)) { 2075 if (pack.members().isEmpty()) { 2076 return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> { 2077 sym.complete(); 2078 return !sym.members().isEmpty(); 2079 }, pack); 2080 } 2081 } 2082 2083 return pack; 2084 } 2085 2086 private boolean isImportOnDemand(Env<AttrContext> env, Name name) { 2087 if (!env.tree.hasTag(IMPORT)) 2088 return false; 2089 2090 JCTree qualid = ((JCImport) env.tree).qualid; 2091 2092 if (!qualid.hasTag(SELECT)) 2093 return false; 2094 2095 if (TreeInfo.name(qualid) != names.asterisk) 2096 return false; 2097 2098 return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name; 2099 } 2100 2101 private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env, 2102 Name name, 2103 Function<Name, Iterable<S>> get, 2104 BiFunction<ModuleSymbol, Name, S> load, 2105 Predicate<S> validate, 2106 Symbol defaultResult) { 2107 //even if a class/package cannot be found in the current module and among packages in modules 2108 //it depends on that are exported for any or this module, the class/package may exist internally 2109 //in some of these modules, or may exist in a module on which this module does not depend. 2110 //Provide better diagnostic in such cases by looking for the class in any module: 2111 Iterable<? extends S> candidates = get.apply(name); 2112 2113 for (S sym : candidates) { 2114 if (validate.test(sym)) 2115 return createInvisibleSymbolError(env, sym); 2116 } 2117 2118 Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules()); 2119 2120 recoverableModules.add(syms.unnamedModule); 2121 recoverableModules.remove(env.toplevel.modle); 2122 2123 for (ModuleSymbol ms : recoverableModules) { 2124 //avoid overly eager completing classes from source-based modules, as those 2125 //may not be completable with the current compiler settings: 2126 if (ms.sourceLocation == null) { 2127 if (ms.classLocation == null) { 2128 ms = moduleFinder.findModule(ms); 2129 } 2130 2131 if (ms.kind != ERR) { 2132 S sym = load.apply(ms, name); 2133 2134 if (sym != null && validate.test(sym)) { 2135 return createInvisibleSymbolError(env, sym); 2136 } 2137 } 2138 } 2139 } 2140 2141 return defaultResult; 2142 } 2143 2144 private Symbol createInvisibleSymbolError(Env<AttrContext> env, Symbol sym) { 2145 if (symbolPackageVisible(env, sym)) { 2146 return new AccessError(env, null, sym); 2147 } else { 2148 return new InvisibleSymbolError(env, false, sym); 2149 } 2150 } 2151 2152 private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) { 2153 ModuleSymbol envMod = env.toplevel.modle; 2154 PackageSymbol symPack = sym.packge(); 2155 return envMod == symPack.modle || 2156 envMod.visiblePackages.containsKey(symPack.fullname); 2157 } 2158 2159 /** 2160 * Find a type declared in a scope (not inherited). Return null 2161 * if none is found. 2162 * @param env The current environment. 2163 * @param site The original type from where the selection takes 2164 * place. 2165 * @param name The type's name. 2166 * @param c The class to search for the member type. This is 2167 * always a superclass or implemented interface of 2168 * site's class. 2169 */ 2170 Symbol findImmediateMemberType(Env<AttrContext> env, 2171 Type site, 2172 Name name, 2173 TypeSymbol c) { 2174 for (Symbol sym : c.members().getSymbolsByName(name)) { 2175 if (sym.kind == TYP) { 2176 return isAccessible(env, site, sym) 2177 ? sym 2178 : new AccessError(env, site, sym); 2179 } 2180 } 2181 return typeNotFound; 2182 } 2183 2184 /** Find a member type inherited from a superclass or interface. 2185 * @param env The current environment. 2186 * @param site The original type from where the selection takes 2187 * place. 2188 * @param name The type's name. 2189 * @param c The class to search for the member type. This is 2190 * always a superclass or implemented interface of 2191 * site's class. 2192 */ 2193 Symbol findInheritedMemberType(Env<AttrContext> env, 2194 Type site, 2195 Name name, 2196 TypeSymbol c) { 2197 Symbol bestSoFar = typeNotFound; 2198 Symbol sym; 2199 Type st = types.supertype(c.type); 2200 if (st != null && st.hasTag(CLASS)) { 2201 sym = findMemberType(env, site, name, st.tsym); 2202 bestSoFar = bestOf(bestSoFar, sym); 2203 } 2204 for (List<Type> l = types.interfaces(c.type); 2205 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 2206 l = l.tail) { 2207 sym = findMemberType(env, site, name, l.head.tsym); 2208 if (!bestSoFar.kind.isResolutionError() && 2209 !sym.kind.isResolutionError() && 2210 sym.owner != bestSoFar.owner) 2211 bestSoFar = new AmbiguityError(bestSoFar, sym); 2212 else 2213 bestSoFar = bestOf(bestSoFar, sym); 2214 } 2215 return bestSoFar; 2216 } 2217 2218 /** Find qualified member type. 2219 * @param env The current environment. 2220 * @param site The original type from where the selection takes 2221 * place. 2222 * @param name The type's name. 2223 * @param c The class to search for the member type. This is 2224 * always a superclass or implemented interface of 2225 * site's class. 2226 */ 2227 Symbol findMemberType(Env<AttrContext> env, 2228 Type site, 2229 Name name, 2230 TypeSymbol c) { 2231 Symbol sym = findImmediateMemberType(env, site, name, c); 2232 2233 if (sym != typeNotFound) 2234 return sym; 2235 2236 return findInheritedMemberType(env, site, name, c); 2237 2238 } 2239 2240 /** Find a global type in given scope and load corresponding class. 2241 * @param env The current environment. 2242 * @param scope The scope in which to look for the type. 2243 * @param name The type's name. 2244 */ 2245 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) { 2246 Symbol bestSoFar = typeNotFound; 2247 for (Symbol s : scope.getSymbolsByName(name)) { 2248 Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass); 2249 if (bestSoFar.kind == TYP && sym.kind == TYP && 2250 bestSoFar != sym) 2251 return new AmbiguityError(bestSoFar, sym); 2252 else 2253 bestSoFar = bestOf(bestSoFar, sym); 2254 } 2255 return bestSoFar; 2256 } 2257 2258 Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) { 2259 for (Symbol sym : env.info.scope.getSymbolsByName(name)) { 2260 if (sym.kind == TYP) { 2261 if (staticOnly && 2262 sym.type.hasTag(TYPEVAR) && 2263 sym.owner.kind == TYP) 2264 return new StaticError(sym); 2265 return sym; 2266 } 2267 } 2268 return typeNotFound; 2269 } 2270 2271 /** Find an unqualified type symbol. 2272 * @param env The current environment. 2273 * @param name The type's name. 2274 */ 2275 Symbol findType(Env<AttrContext> env, Name name) { 2276 if (name == names.empty) 2277 return typeNotFound; // do not allow inadvertent "lookup" of anonymous types 2278 Symbol bestSoFar = typeNotFound; 2279 Symbol sym; 2280 boolean staticOnly = false; 2281 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) { 2282 if (isStatic(env1)) staticOnly = true; 2283 // First, look for a type variable and the first member type 2284 final Symbol tyvar = findTypeVar(env1, name, staticOnly); 2285 sym = findImmediateMemberType(env1, env1.enclClass.sym.type, 2286 name, env1.enclClass.sym); 2287 2288 // Return the type variable if we have it, and have no 2289 // immediate member, OR the type variable is for a method. 2290 if (tyvar != typeNotFound) { 2291 if (env.baseClause || sym == typeNotFound || 2292 (tyvar.kind == TYP && tyvar.exists() && 2293 tyvar.owner.kind == MTH)) { 2294 return tyvar; 2295 } 2296 } 2297 2298 // If the environment is a class def, finish up, 2299 // otherwise, do the entire findMemberType 2300 if (sym == typeNotFound) 2301 sym = findInheritedMemberType(env1, env1.enclClass.sym.type, 2302 name, env1.enclClass.sym); 2303 2304 if (staticOnly && sym.kind == TYP && 2305 sym.type.hasTag(CLASS) && 2306 sym.type.getEnclosingType().hasTag(CLASS) && 2307 env1.enclClass.sym.type.isParameterized() && 2308 sym.type.getEnclosingType().isParameterized()) 2309 return new StaticError(sym); 2310 else if (sym.exists()) return sym; 2311 else bestSoFar = bestOf(bestSoFar, sym); 2312 2313 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass; 2314 if ((encl.sym.flags() & STATIC) != 0) 2315 staticOnly = true; 2316 } 2317 2318 if (!env.tree.hasTag(IMPORT)) { 2319 sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery); 2320 if (sym.exists()) return sym; 2321 else bestSoFar = bestOf(bestSoFar, sym); 2322 2323 sym = findGlobalType(env, env.toplevel.toplevelScope, name, noRecovery); 2324 if (sym.exists()) return sym; 2325 else bestSoFar = bestOf(bestSoFar, sym); 2326 2327 sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery); 2328 if (sym.exists()) return sym; 2329 else bestSoFar = bestOf(bestSoFar, sym); 2330 2331 sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery); 2332 if (sym.exists()) return sym; 2333 else bestSoFar = bestOf(bestSoFar, sym); 2334 } 2335 2336 return bestSoFar; 2337 } 2338 2339 /** Find an unqualified identifier which matches a specified kind set. 2340 * @param pos position on which report warnings, if any; 2341 * null warnings should not be reported 2342 * @param env The current environment. 2343 * @param name The identifier's name. 2344 * @param kind Indicates the possible symbol kinds 2345 * (a subset of VAL, TYP, PCK). 2346 */ 2347 Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) { 2348 return checkRestrictedType(pos, findIdentInternal(env, name, kind), name); 2349 } 2350 2351 Symbol findIdentInternal(Env<AttrContext> env, Name name, KindSelector kind) { 2352 Symbol bestSoFar = typeNotFound; 2353 Symbol sym; 2354 2355 if (kind.contains(KindSelector.VAL)) { 2356 sym = findVar(env, name); 2357 if (sym.exists()) return sym; 2358 else bestSoFar = bestOf(bestSoFar, sym); 2359 } 2360 2361 if (kind.contains(KindSelector.TYP)) { 2362 sym = findType(env, name); 2363 2364 if (sym.exists()) return sym; 2365 else bestSoFar = bestOf(bestSoFar, sym); 2366 } 2367 2368 if (kind.contains(KindSelector.PCK)) 2369 return lookupPackage(env, name); 2370 else return bestSoFar; 2371 } 2372 2373 /** Find an identifier in a package which matches a specified kind set. 2374 * @param pos position on which report warnings, if any; 2375 * null warnings should not be reported 2376 * @param env The current environment. 2377 * @param name The identifier's name. 2378 * @param kind Indicates the possible symbol kinds 2379 * (a nonempty subset of TYP, PCK). 2380 */ 2381 Symbol findIdentInPackage(DiagnosticPosition pos, 2382 Env<AttrContext> env, TypeSymbol pck, 2383 Name name, KindSelector kind) { 2384 return checkRestrictedType(pos, findIdentInPackageInternal(env, pck, name, kind), name); 2385 } 2386 2387 Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck, 2388 Name name, KindSelector kind) { 2389 Name fullname = TypeSymbol.formFullName(name, pck); 2390 Symbol bestSoFar = typeNotFound; 2391 if (kind.contains(KindSelector.TYP)) { 2392 RecoveryLoadClass recoveryLoadClass = 2393 allowModules && !kind.contains(KindSelector.PCK) && 2394 !pck.exists() && !env.info.attributionMode.isSpeculative ? 2395 doRecoveryLoadClass : noRecovery; 2396 Symbol sym = loadClass(env, fullname, recoveryLoadClass); 2397 if (sym.exists()) { 2398 // don't allow programs to use flatnames 2399 if (name == sym.name) return sym; 2400 } 2401 else bestSoFar = bestOf(bestSoFar, sym); 2402 } 2403 if (kind.contains(KindSelector.PCK)) { 2404 return lookupPackage(env, fullname); 2405 } 2406 return bestSoFar; 2407 } 2408 2409 /** Find an identifier among the members of a given type `site'. 2410 * @param pos position on which report warnings, if any; 2411 * null warnings should not be reported 2412 * @param env The current environment. 2413 * @param site The type containing the symbol to be found. 2414 * @param name The identifier's name. 2415 * @param kind Indicates the possible symbol kinds 2416 * (a subset of VAL, TYP). 2417 */ 2418 Symbol findIdentInType(DiagnosticPosition pos, 2419 Env<AttrContext> env, Type site, 2420 Name name, KindSelector kind) { 2421 return checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name); 2422 } 2423 2424 Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site, 2425 Name name, KindSelector kind) { 2426 Symbol bestSoFar = typeNotFound; 2427 Symbol sym; 2428 if (kind.contains(KindSelector.VAL)) { 2429 sym = findField(env, site, name, site.tsym); 2430 if (sym.exists()) return sym; 2431 else bestSoFar = bestOf(bestSoFar, sym); 2432 } 2433 2434 if (kind.contains(KindSelector.TYP)) { 2435 sym = findMemberType(env, site, name, site.tsym); 2436 if (sym.exists()) return sym; 2437 else bestSoFar = bestOf(bestSoFar, sym); 2438 } 2439 return bestSoFar; 2440 } 2441 2442 private Symbol checkRestrictedType(DiagnosticPosition pos, Symbol bestSoFar, Name name) { 2443 if (bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP) { 2444 if (allowLocalVariableTypeInference && name.equals(names.var)) { 2445 bestSoFar = new BadRestrictedTypeError(names.var); 2446 } else if (name.equals(names.yield)) { 2447 if (allowYieldStatement) { 2448 bestSoFar = new BadRestrictedTypeError(names.yield); 2449 } else if (pos != null) { 2450 log.warning(pos, Warnings.IllegalRefToRestrictedType(names.yield)); 2451 } 2452 } 2453 } 2454 return bestSoFar; 2455 } 2456 2457 /* *************************************************************************** 2458 * Access checking 2459 * The following methods convert ResolveErrors to ErrorSymbols, issuing 2460 * an error message in the process 2461 ****************************************************************************/ 2462 2463 /** If `sym' is a bad symbol: report error and return errSymbol 2464 * else pass through unchanged, 2465 * additional arguments duplicate what has been used in trying to find the 2466 * symbol {@literal (--> flyweight pattern)}. This improves performance since we 2467 * expect misses to happen frequently. 2468 * 2469 * @param sym The symbol that was found, or a ResolveError. 2470 * @param pos The position to use for error reporting. 2471 * @param location The symbol the served as a context for this lookup 2472 * @param site The original type from where the selection took place. 2473 * @param name The symbol's name. 2474 * @param qualified Did we get here through a qualified expression resolution? 2475 * @param argtypes The invocation's value arguments, 2476 * if we looked for a method. 2477 * @param typeargtypes The invocation's type arguments, 2478 * if we looked for a method. 2479 * @param logResolveHelper helper class used to log resolve errors 2480 */ 2481 Symbol accessInternal(Symbol sym, 2482 DiagnosticPosition pos, 2483 Symbol location, 2484 Type site, 2485 Name name, 2486 boolean qualified, 2487 List<Type> argtypes, 2488 List<Type> typeargtypes, 2489 LogResolveHelper logResolveHelper) { 2490 if (sym.kind.isResolutionError()) { 2491 ResolveError errSym = (ResolveError)sym.baseSymbol(); 2492 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol); 2493 argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes); 2494 if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) { 2495 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes); 2496 } 2497 } 2498 return sym; 2499 } 2500 2501 /** 2502 * Variant of the generalized access routine, to be used for generating method 2503 * resolution diagnostics 2504 */ 2505 Symbol accessMethod(Symbol sym, 2506 DiagnosticPosition pos, 2507 Symbol location, 2508 Type site, 2509 Name name, 2510 boolean qualified, 2511 List<Type> argtypes, 2512 List<Type> typeargtypes) { 2513 return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper); 2514 } 2515 2516 /** Same as original accessMethod(), but without location. 2517 */ 2518 Symbol accessMethod(Symbol sym, 2519 DiagnosticPosition pos, 2520 Type site, 2521 Name name, 2522 boolean qualified, 2523 List<Type> argtypes, 2524 List<Type> typeargtypes) { 2525 return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes); 2526 } 2527 2528 /** 2529 * Variant of the generalized access routine, to be used for generating variable, 2530 * type resolution diagnostics 2531 */ 2532 Symbol accessBase(Symbol sym, 2533 DiagnosticPosition pos, 2534 Symbol location, 2535 Type site, 2536 Name name, 2537 boolean qualified) { 2538 return accessInternal(sym, pos, location, site, name, qualified, List.nil(), null, basicLogResolveHelper); 2539 } 2540 2541 /** Same as original accessBase(), but without location. 2542 */ 2543 Symbol accessBase(Symbol sym, 2544 DiagnosticPosition pos, 2545 Type site, 2546 Name name, 2547 boolean qualified) { 2548 return accessBase(sym, pos, site.tsym, site, name, qualified); 2549 } 2550 2551 interface LogResolveHelper { 2552 boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes); 2553 List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes); 2554 } 2555 2556 LogResolveHelper basicLogResolveHelper = new LogResolveHelper() { 2557 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2558 return !site.isErroneous(); 2559 } 2560 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2561 return argtypes; 2562 } 2563 }; 2564 2565 LogResolveHelper methodLogResolveHelper = new LogResolveHelper() { 2566 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) { 2567 return !site.isErroneous() && 2568 !Type.isErroneous(argtypes) && 2569 (typeargtypes == null || !Type.isErroneous(typeargtypes)); 2570 } 2571 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) { 2572 return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); 2573 } 2574 }; 2575 2576 class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap { 2577 2578 public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) { 2579 deferredAttr.super(mode, msym, step); 2580 } 2581 2582 @Override 2583 protected Type typeOf(DeferredType dt, Type pt) { 2584 Type res = super.typeOf(dt, pt); 2585 if (!res.isErroneous()) { 2586 switch (TreeInfo.skipParens(dt.tree).getTag()) { 2587 case LAMBDA: 2588 case REFERENCE: 2589 return dt; 2590 case CONDEXPR: 2591 return res == Type.recoveryType ? 2592 dt : res; 2593 } 2594 } 2595 return res; 2596 } 2597 } 2598 2599 /** Check that sym is not an abstract method. 2600 */ 2601 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { 2602 if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0) 2603 log.error(pos, 2604 Errors.AbstractCantBeAccessedDirectly(kindName(sym),sym, sym.location())); 2605 } 2606 2607 /* *************************************************************************** 2608 * Name resolution 2609 * Naming conventions are as for symbol lookup 2610 * Unlike the find... methods these methods will report access errors 2611 ****************************************************************************/ 2612 2613 /** Resolve an unqualified (non-method) identifier. 2614 * @param pos The position to use for error reporting. 2615 * @param env The environment current at the identifier use. 2616 * @param name The identifier's name. 2617 * @param kind The set of admissible symbol kinds for the identifier. 2618 */ 2619 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env, 2620 Name name, KindSelector kind) { 2621 return accessBase( 2622 findIdent(pos, env, name, kind), 2623 pos, env.enclClass.sym.type, name, false); 2624 } 2625 2626 /** Resolve an unqualified method identifier. 2627 * @param pos The position to use for error reporting. 2628 * @param env The environment current at the method invocation. 2629 * @param name The identifier's name. 2630 * @param argtypes The types of the invocation's value arguments. 2631 * @param typeargtypes The types of the invocation's type arguments. 2632 */ 2633 Symbol resolveMethod(DiagnosticPosition pos, 2634 Env<AttrContext> env, 2635 Name name, 2636 List<Type> argtypes, 2637 List<Type> typeargtypes) { 2638 return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck, 2639 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) { 2640 @Override 2641 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2642 return findFun(env, name, argtypes, typeargtypes, 2643 phase.isBoxingRequired(), 2644 phase.isVarargsRequired()); 2645 }}); 2646 } 2647 2648 /** Resolve a qualified method identifier 2649 * @param pos The position to use for error reporting. 2650 * @param env The environment current at the method invocation. 2651 * @param site The type of the qualifying expression, in which 2652 * identifier is searched. 2653 * @param name The identifier's name. 2654 * @param argtypes The types of the invocation's value arguments. 2655 * @param typeargtypes The types of the invocation's type arguments. 2656 */ 2657 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 2658 Type site, Name name, List<Type> argtypes, 2659 List<Type> typeargtypes) { 2660 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes); 2661 } 2662 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 2663 Symbol location, Type site, Name name, List<Type> argtypes, 2664 List<Type> typeargtypes) { 2665 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes); 2666 } 2667 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext, 2668 DiagnosticPosition pos, Env<AttrContext> env, 2669 Symbol location, Type site, Name name, List<Type> argtypes, 2670 List<Type> typeargtypes) { 2671 return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) { 2672 @Override 2673 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2674 return findMethod(env, site, name, argtypes, typeargtypes, 2675 phase.isBoxingRequired(), 2676 phase.isVarargsRequired()); 2677 } 2678 @Override 2679 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2680 if (sym.kind.isResolutionError()) { 2681 sym = super.access(env, pos, location, sym); 2682 } else { 2683 MethodSymbol msym = (MethodSymbol)sym; 2684 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) { 2685 env.info.pendingResolutionPhase = BASIC; 2686 return findPolymorphicSignatureInstance(env, sym, argtypes); 2687 } 2688 } 2689 return sym; 2690 } 2691 }); 2692 } 2693 2694 /** Find or create an implicit method of exactly the given type (after erasure). 2695 * Searches in a side table, not the main scope of the site. 2696 * This emulates the lookup process required by JSR 292 in JVM. 2697 * @param env Attribution environment 2698 * @param spMethod signature polymorphic method - i.e. MH.invokeExact 2699 * @param argtypes The required argument types 2700 */ 2701 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, 2702 final Symbol spMethod, 2703 List<Type> argtypes) { 2704 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, 2705 (MethodSymbol)spMethod, currentResolutionContext, argtypes); 2706 return findPolymorphicSignatureInstance(spMethod, mtype); 2707 } 2708 2709 Symbol findPolymorphicSignatureInstance(final Symbol spMethod, 2710 Type mtype) { 2711 for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) { 2712 // Check that there is already a method symbol for the method 2713 // type and owner 2714 if (types.isSameType(mtype, sym.type) && 2715 spMethod.owner == sym.owner) { 2716 return sym; 2717 } 2718 } 2719 2720 // Create the desired method 2721 // Retain static modifier is to support invocations to 2722 // MethodHandle.linkTo* methods 2723 long flags = ABSTRACT | HYPOTHETICAL | 2724 spMethod.flags() & (Flags.AccessFlags | Flags.STATIC); 2725 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) { 2726 @Override 2727 public Symbol baseSymbol() { 2728 return spMethod; 2729 } 2730 }; 2731 if (!mtype.isErroneous()) { // Cache only if kosher. 2732 polymorphicSignatureScope.enter(msym); 2733 } 2734 return msym; 2735 } 2736 2737 /** Resolve a qualified method identifier, throw a fatal error if not 2738 * found. 2739 * @param pos The position to use for error reporting. 2740 * @param env The environment current at the method invocation. 2741 * @param site The type of the qualifying expression, in which 2742 * identifier is searched. 2743 * @param name The identifier's name. 2744 * @param argtypes The types of the invocation's value arguments. 2745 * @param typeargtypes The types of the invocation's type arguments. 2746 */ 2747 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env, 2748 Type site, Name name, 2749 List<Type> argtypes, 2750 List<Type> typeargtypes) { 2751 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2752 resolveContext.internalResolution = true; 2753 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym, 2754 site, name, argtypes, typeargtypes); 2755 if (sym.kind == MTH) return (MethodSymbol)sym; 2756 else throw new FatalError( 2757 diags.fragment(Fragments.FatalErrCantLocateMeth(name))); 2758 } 2759 2760 /** Resolve constructor. 2761 * @param pos The position to use for error reporting. 2762 * @param env The environment current at the constructor invocation. 2763 * @param site The type of class for which a constructor is searched. 2764 * @param argtypes The types of the constructor invocation's value 2765 * arguments. 2766 * @param typeargtypes The types of the constructor invocation's type 2767 * arguments. 2768 */ 2769 Symbol resolveConstructor(DiagnosticPosition pos, 2770 Env<AttrContext> env, 2771 Type site, 2772 List<Type> argtypes, 2773 List<Type> typeargtypes) { 2774 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); 2775 } 2776 2777 private Symbol resolveConstructor(MethodResolutionContext resolveContext, 2778 final DiagnosticPosition pos, 2779 Env<AttrContext> env, 2780 Type site, 2781 List<Type> argtypes, 2782 List<Type> typeargtypes) { 2783 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 2784 @Override 2785 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2786 return findConstructor(pos, env, site, argtypes, typeargtypes, 2787 phase.isBoxingRequired(), 2788 phase.isVarargsRequired()); 2789 } 2790 }); 2791 } 2792 2793 /** Resolve a constructor, throw a fatal error if not found. 2794 * @param pos The position to use for error reporting. 2795 * @param env The environment current at the method invocation. 2796 * @param site The type to be constructed. 2797 * @param argtypes The types of the invocation's value arguments. 2798 * @param typeargtypes The types of the invocation's type arguments. 2799 */ 2800 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 2801 Type site, 2802 List<Type> argtypes, 2803 List<Type> typeargtypes) { 2804 MethodResolutionContext resolveContext = new MethodResolutionContext(); 2805 resolveContext.internalResolution = true; 2806 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 2807 if (sym.kind == MTH) return (MethodSymbol)sym; 2808 else throw new FatalError( 2809 diags.fragment(Fragments.FatalErrCantLocateCtor(site))); 2810 } 2811 2812 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 2813 Type site, List<Type> argtypes, 2814 List<Type> typeargtypes, 2815 boolean allowBoxing, 2816 boolean useVarargs) { 2817 Symbol sym = findMethod(env, site, 2818 names.init, argtypes, 2819 typeargtypes, allowBoxing, 2820 useVarargs); 2821 chk.checkDeprecated(pos, env.info.scope.owner, sym); 2822 chk.checkPreview(pos, sym); 2823 return sym; 2824 } 2825 2826 /** Resolve constructor using diamond inference. 2827 * @param pos The position to use for error reporting. 2828 * @param env The environment current at the constructor invocation. 2829 * @param site The type of class for which a constructor is searched. 2830 * The scope of this class has been touched in attribution. 2831 * @param argtypes The types of the constructor invocation's value 2832 * arguments. 2833 * @param typeargtypes The types of the constructor invocation's type 2834 * arguments. 2835 */ 2836 Symbol resolveDiamond(DiagnosticPosition pos, 2837 Env<AttrContext> env, 2838 Type site, 2839 List<Type> argtypes, 2840 List<Type> typeargtypes) { 2841 return lookupMethod(env, pos, site.tsym, resolveMethodCheck, 2842 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 2843 @Override 2844 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) { 2845 return findDiamond(env, site, argtypes, typeargtypes, 2846 phase.isBoxingRequired(), 2847 phase.isVarargsRequired()); 2848 } 2849 @Override 2850 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 2851 if (sym.kind.isResolutionError()) { 2852 if (sym.kind != WRONG_MTH && 2853 sym.kind != WRONG_MTHS) { 2854 sym = super.access(env, pos, location, sym); 2855 } else { 2856 final JCDiagnostic details = sym.kind == WRONG_MTH ? 2857 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd : 2858 null; 2859 sym = new DiamondError(sym, currentResolutionContext); 2860 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); 2861 env.info.pendingResolutionPhase = currentResolutionContext.step; 2862 } 2863 } 2864 return sym; 2865 }}); 2866 } 2867 2868 /** This method scans all the constructor symbol in a given class scope - 2869 * assuming that the original scope contains a constructor of the kind: 2870 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo, 2871 * a method check is executed against the modified constructor type: 2872 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond 2873 * inference. The inferred return type of the synthetic constructor IS 2874 * the inferred type for the diamond operator. 2875 */ 2876 private Symbol findDiamond(Env<AttrContext> env, 2877 Type site, 2878 List<Type> argtypes, 2879 List<Type> typeargtypes, 2880 boolean allowBoxing, 2881 boolean useVarargs) { 2882 Symbol bestSoFar = methodNotFound; 2883 TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym; 2884 for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) { 2885 //- System.out.println(" e " + e.sym); 2886 if (sym.kind == MTH && 2887 (sym.flags_field & SYNTHETIC) == 0) { 2888 List<Type> oldParams = sym.type.hasTag(FORALL) ? 2889 ((ForAll)sym.type).tvars : 2890 List.nil(); 2891 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), 2892 types.createMethodTypeWithReturn(sym.type.asMethodType(), site)); 2893 MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) { 2894 @Override 2895 public Symbol baseSymbol() { 2896 return sym; 2897 } 2898 }; 2899 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 2900 newConstr, 2901 bestSoFar, 2902 allowBoxing, 2903 useVarargs); 2904 } 2905 } 2906 return bestSoFar; 2907 } 2908 2909 Symbol getMemberReference(DiagnosticPosition pos, 2910 Env<AttrContext> env, 2911 JCMemberReference referenceTree, 2912 Type site, 2913 Name name) { 2914 2915 site = types.capture(site); 2916 2917 ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper( 2918 referenceTree, site, name, List.nil(), null, VARARITY); 2919 2920 Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup()); 2921 Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym, 2922 nilMethodCheck, lookupHelper); 2923 2924 env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase; 2925 2926 return sym; 2927 } 2928 2929 ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree, 2930 Type site, 2931 Name name, 2932 List<Type> argtypes, 2933 List<Type> typeargtypes, 2934 MethodResolutionPhase maxPhase) { 2935 if (!name.equals(names.init)) { 2936 //method reference 2937 return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); 2938 } else if (site.hasTag(ARRAY)) { 2939 //array constructor reference 2940 return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); 2941 } else { 2942 //class constructor reference 2943 return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); 2944 } 2945 } 2946 2947 /** 2948 * Resolution of member references is typically done as a single 2949 * overload resolution step, where the argument types A are inferred from 2950 * the target functional descriptor. 2951 * 2952 * If the member reference is a method reference with a type qualifier, 2953 * a two-step lookup process is performed. The first step uses the 2954 * expected argument list A, while the second step discards the first 2955 * type from A (which is treated as a receiver type). 2956 * 2957 * There are two cases in which inference is performed: (i) if the member 2958 * reference is a constructor reference and the qualifier type is raw - in 2959 * which case diamond inference is used to infer a parameterization for the 2960 * type qualifier; (ii) if the member reference is an unbound reference 2961 * where the type qualifier is raw - in that case, during the unbound lookup 2962 * the receiver argument type is used to infer an instantiation for the raw 2963 * qualifier type. 2964 * 2965 * When a multi-step resolution process is exploited, the process of picking 2966 * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}. 2967 * 2968 * This routine returns a pair (T,S), where S is the member reference symbol, 2969 * and T is the type of the class in which S is defined. This is necessary as 2970 * the type T might be dynamically inferred (i.e. if constructor reference 2971 * has a raw qualifier). 2972 */ 2973 Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env, 2974 JCMemberReference referenceTree, 2975 Type site, 2976 Name name, 2977 List<Type> argtypes, 2978 List<Type> typeargtypes, 2979 Type descriptor, 2980 MethodCheck methodCheck, 2981 InferenceContext inferenceContext, 2982 ReferenceChooser referenceChooser) { 2983 2984 //step 1 - bound lookup 2985 ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( 2986 referenceTree, site, name, argtypes, typeargtypes, VARARITY); 2987 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup()); 2988 MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext(); 2989 boundSearchResolveContext.methodCheck = methodCheck; 2990 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), 2991 site.tsym, boundSearchResolveContext, boundLookupHelper); 2992 ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext); 2993 2994 //step 2 - unbound lookup 2995 Symbol unboundSym = methodNotFound; 2996 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup()); 2997 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); 2998 ReferenceLookupResult unboundRes = referenceNotFound; 2999 if (unboundLookupHelper != null) { 3000 MethodResolutionContext unboundSearchResolveContext = 3001 new MethodResolutionContext(); 3002 unboundSearchResolveContext.methodCheck = methodCheck; 3003 unboundSym = lookupMethod(unboundEnv, env.tree.pos(), 3004 site.tsym, unboundSearchResolveContext, unboundLookupHelper); 3005 unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext); 3006 } 3007 3008 //merge results 3009 Pair<Symbol, ReferenceLookupHelper> res; 3010 ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes); 3011 res = new Pair<>(bestRes.sym, 3012 bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper); 3013 env.info.pendingResolutionPhase = bestRes == unboundRes ? 3014 unboundEnv.info.pendingResolutionPhase : 3015 boundEnv.info.pendingResolutionPhase; 3016 3017 if (!res.fst.kind.isResolutionError()) { 3018 //handle sigpoly method references 3019 MethodSymbol msym = (MethodSymbol)res.fst; 3020 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) { 3021 env.info.pendingResolutionPhase = BASIC; 3022 res = new Pair<>(findPolymorphicSignatureInstance(msym, descriptor), res.snd); 3023 } 3024 } 3025 3026 return res; 3027 } 3028 3029 /** 3030 * This class is used to represent a method reference lookup result. It keeps track of two 3031 * things: (i) the symbol found during a method reference lookup and (ii) the static kind 3032 * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}). 3033 */ 3034 static class ReferenceLookupResult { 3035 3036 /** 3037 * Static kind associated with a method reference lookup. Erroneous lookups end up with 3038 * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC, 3039 * depending on whether all applicable candidates are static or non-static methods, 3040 * respectively. If a successful lookup has both static and non-static applicable methods, 3041 * its kind is set to BOTH. 3042 */ 3043 enum StaticKind { 3044 STATIC, 3045 NON_STATIC, 3046 BOTH, 3047 UNDEFINED; 3048 3049 /** 3050 * Retrieve the static kind associated with a given (method) symbol. 3051 */ 3052 static StaticKind from(Symbol s) { 3053 return s.isStatic() ? 3054 STATIC : NON_STATIC; 3055 } 3056 3057 /** 3058 * Merge two static kinds together. 3059 */ 3060 static StaticKind reduce(StaticKind sk1, StaticKind sk2) { 3061 if (sk1 == UNDEFINED) { 3062 return sk2; 3063 } else if (sk2 == UNDEFINED) { 3064 return sk1; 3065 } else { 3066 return sk1 == sk2 ? sk1 : BOTH; 3067 } 3068 } 3069 } 3070 3071 /** The static kind. */ 3072 StaticKind staticKind; 3073 3074 /** The lookup result. */ 3075 Symbol sym; 3076 3077 ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) { 3078 this(sym, staticKind(sym, resolutionContext)); 3079 } 3080 3081 private ReferenceLookupResult(Symbol sym, StaticKind staticKind) { 3082 this.staticKind = staticKind; 3083 this.sym = sym; 3084 } 3085 3086 private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) { 3087 switch (sym.kind) { 3088 case MTH: 3089 case AMBIGUOUS: 3090 return resolutionContext.candidates.stream() 3091 .filter(c -> c.isApplicable() && c.step == resolutionContext.step) 3092 .map(c -> StaticKind.from(c.sym)) 3093 .reduce(StaticKind::reduce) 3094 .orElse(StaticKind.UNDEFINED); 3095 default: 3096 return StaticKind.UNDEFINED; 3097 } 3098 } 3099 3100 /** 3101 * Does this result corresponds to a successful lookup (i.e. one where a method has been found?) 3102 */ 3103 boolean isSuccess() { 3104 return staticKind != StaticKind.UNDEFINED; 3105 } 3106 3107 /** 3108 * Does this result have given static kind? 3109 */ 3110 boolean hasKind(StaticKind sk) { 3111 return this.staticKind == sk; 3112 } 3113 3114 /** 3115 * Error recovery helper: can this lookup result be ignored (for the purpose of returning 3116 * some 'better' result) ? 3117 */ 3118 boolean canIgnore() { 3119 switch (sym.kind) { 3120 case ABSENT_MTH: 3121 return true; 3122 case WRONG_MTH: 3123 InapplicableSymbolError errSym = 3124 (InapplicableSymbolError)sym.baseSymbol(); 3125 return new Template(MethodCheckDiag.ARITY_MISMATCH.regex()) 3126 .matches(errSym.errCandidate().snd); 3127 case WRONG_MTHS: 3128 InapplicableSymbolsError errSyms = 3129 (InapplicableSymbolsError)sym.baseSymbol(); 3130 return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty(); 3131 default: 3132 return false; 3133 } 3134 } 3135 3136 static ReferenceLookupResult error(Symbol sym) { 3137 return new ReferenceLookupResult(sym, StaticKind.UNDEFINED); 3138 } 3139 } 3140 3141 /** 3142 * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup) 3143 * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the 3144 * result of method reference resolution. 3145 */ 3146 abstract class ReferenceChooser { 3147 /** 3148 * Generate a result from a pair of lookup result objects. This method delegates to the 3149 * appropriate result generation routine. 3150 */ 3151 ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { 3152 return unboundRes != referenceNotFound ? 3153 unboundResult(boundRes, unboundRes) : 3154 boundResult(boundRes); 3155 } 3156 3157 /** 3158 * Generate a symbol from a given bound lookup result. 3159 */ 3160 abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes); 3161 3162 /** 3163 * Generate a symbol from a pair of bound/unbound lookup results. 3164 */ 3165 abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes); 3166 } 3167 3168 /** 3169 * This chooser implements the selection strategy used during a full lookup; this logic 3170 * is described in JLS SE 8 (15.3.2). 3171 */ 3172 ReferenceChooser basicReferenceChooser = new ReferenceChooser() { 3173 3174 @Override 3175 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) { 3176 return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ? 3177 boundRes : //the search produces a non-static method 3178 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false)); 3179 } 3180 3181 @Override 3182 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { 3183 if (boundRes.hasKind(StaticKind.STATIC) && 3184 (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) { 3185 //the first search produces a static method and no non-static method is applicable 3186 //during the second search 3187 return boundRes; 3188 } else if (unboundRes.hasKind(StaticKind.NON_STATIC) && 3189 (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) { 3190 //the second search produces a non-static method and no static method is applicable 3191 //during the first search 3192 return unboundRes; 3193 } else if (boundRes.isSuccess() && unboundRes.isSuccess()) { 3194 //both searches produce some result; ambiguity (error recovery) 3195 return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym)); 3196 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) { 3197 //Both searches failed to produce a result with correct staticness (i.e. first search 3198 //produces an non-static method). Alternatively, a given search produced a result 3199 //with the right staticness, but the other search has applicable methods with wrong 3200 //staticness (error recovery) 3201 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ? 3202 boundRes.sym : unboundRes.sym, true)); 3203 } else { 3204 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery) 3205 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ? 3206 unboundRes : boundRes; 3207 } 3208 } 3209 }; 3210 3211 /** 3212 * This chooser implements the selection strategy used during an arity-based lookup; this logic 3213 * is described in JLS SE 8 (15.12.2.1). 3214 */ 3215 ReferenceChooser structuralReferenceChooser = new ReferenceChooser() { 3216 3217 @Override 3218 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) { 3219 return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ? 3220 boundRes : //the search has at least one applicable non-static method 3221 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false)); 3222 } 3223 3224 @Override 3225 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { 3226 if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) { 3227 //the first search has at least one applicable static method 3228 return boundRes; 3229 } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) { 3230 //the second search has at least one applicable non-static method 3231 return unboundRes; 3232 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) { 3233 //either the first search produces a non-static method, or second search produces 3234 //a non-static method (error recovery) 3235 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ? 3236 boundRes.sym : unboundRes.sym, true)); 3237 } else { 3238 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery) 3239 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ? 3240 unboundRes : boundRes; 3241 } 3242 } 3243 }; 3244 3245 /** 3246 * Helper for defining custom method-like lookup logic; a lookup helper 3247 * provides hooks for (i) the actual lookup logic and (ii) accessing the 3248 * lookup result (this step might result in compiler diagnostics to be generated) 3249 */ 3250 abstract class LookupHelper { 3251 3252 /** name of the symbol to lookup */ 3253 Name name; 3254 3255 /** location in which the lookup takes place */ 3256 Type site; 3257 3258 /** actual types used during the lookup */ 3259 List<Type> argtypes; 3260 3261 /** type arguments used during the lookup */ 3262 List<Type> typeargtypes; 3263 3264 /** Max overload resolution phase handled by this helper */ 3265 MethodResolutionPhase maxPhase; 3266 3267 LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3268 this.name = name; 3269 this.site = site; 3270 this.argtypes = argtypes; 3271 this.typeargtypes = typeargtypes; 3272 this.maxPhase = maxPhase; 3273 } 3274 3275 /** 3276 * Should lookup stop at given phase with given result 3277 */ 3278 final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { 3279 return phase.ordinal() > maxPhase.ordinal() || 3280 !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS; 3281 } 3282 3283 /** 3284 * Search for a symbol under a given overload resolution phase - this method 3285 * is usually called several times, once per each overload resolution phase 3286 */ 3287 abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase); 3288 3289 /** 3290 * Dump overload resolution info 3291 */ 3292 void debug(DiagnosticPosition pos, Symbol sym) { 3293 //do nothing 3294 } 3295 3296 /** 3297 * Validate the result of the lookup 3298 */ 3299 abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym); 3300 } 3301 3302 abstract class BasicLookupHelper extends LookupHelper { 3303 3304 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) { 3305 this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY); 3306 } 3307 3308 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3309 super(name, site, argtypes, typeargtypes, maxPhase); 3310 } 3311 3312 @Override 3313 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3314 Symbol sym = doLookup(env, phase); 3315 if (sym.kind == AMBIGUOUS) { 3316 AmbiguityError a_err = (AmbiguityError)sym.baseSymbol(); 3317 sym = a_err.mergeAbstracts(site); 3318 } 3319 return sym; 3320 } 3321 3322 abstract Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase); 3323 3324 @Override 3325 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 3326 if (sym.kind.isResolutionError()) { 3327 //if nothing is found return the 'first' error 3328 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes); 3329 } 3330 return sym; 3331 } 3332 3333 @Override 3334 void debug(DiagnosticPosition pos, Symbol sym) { 3335 reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym); 3336 } 3337 } 3338 3339 /** 3340 * Helper class for member reference lookup. A reference lookup helper 3341 * defines the basic logic for member reference lookup; a method gives 3342 * access to an 'unbound' helper used to perform an unbound member 3343 * reference lookup. 3344 */ 3345 abstract class ReferenceLookupHelper extends LookupHelper { 3346 3347 /** The member reference tree */ 3348 JCMemberReference referenceTree; 3349 3350 ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 3351 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3352 super(name, site, argtypes, typeargtypes, maxPhase); 3353 this.referenceTree = referenceTree; 3354 } 3355 3356 /** 3357 * Returns an unbound version of this lookup helper. By default, this 3358 * method returns an dummy lookup helper. 3359 */ 3360 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3361 return null; 3362 } 3363 3364 /** 3365 * Get the kind of the member reference 3366 */ 3367 abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym); 3368 3369 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 3370 if (sym.kind == AMBIGUOUS) { 3371 AmbiguityError a_err = (AmbiguityError)sym.baseSymbol(); 3372 sym = a_err.mergeAbstracts(site); 3373 } 3374 //skip error reporting 3375 return sym; 3376 } 3377 } 3378 3379 /** 3380 * Helper class for method reference lookup. The lookup logic is based 3381 * upon Resolve.findMethod; in certain cases, this helper class has a 3382 * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper). 3383 * In such cases, non-static lookup results are thrown away. 3384 */ 3385 class MethodReferenceLookupHelper extends ReferenceLookupHelper { 3386 3387 /** The original method reference lookup site. */ 3388 Type originalSite; 3389 3390 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 3391 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3392 super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase); 3393 this.originalSite = site; 3394 } 3395 3396 @Override 3397 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3398 return findMethod(env, site, name, argtypes, typeargtypes, 3399 phase.isBoxingRequired(), phase.isVarargsRequired()); 3400 } 3401 3402 @Override 3403 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3404 if (TreeInfo.isStaticSelector(referenceTree.expr, names)) { 3405 if (argtypes.nonEmpty() && 3406 (argtypes.head.hasTag(NONE) || 3407 types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) { 3408 return new UnboundMethodReferenceLookupHelper(referenceTree, name, 3409 originalSite, argtypes, typeargtypes, maxPhase); 3410 } else { 3411 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { 3412 @Override 3413 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3414 return this; 3415 } 3416 3417 @Override 3418 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3419 return methodNotFound; 3420 } 3421 3422 @Override 3423 ReferenceKind referenceKind(Symbol sym) { 3424 Assert.error(); 3425 return null; 3426 } 3427 }; 3428 } 3429 } else { 3430 return super.unboundLookup(inferenceContext); 3431 } 3432 } 3433 3434 @Override 3435 ReferenceKind referenceKind(Symbol sym) { 3436 if (sym.isStatic()) { 3437 return ReferenceKind.STATIC; 3438 } else { 3439 Name selName = TreeInfo.name(referenceTree.getQualifierExpression()); 3440 return selName != null && selName == names._super ? 3441 ReferenceKind.SUPER : 3442 ReferenceKind.BOUND; 3443 } 3444 } 3445 } 3446 3447 /** 3448 * Helper class for unbound method reference lookup. Essentially the same 3449 * as the basic method reference lookup helper; main difference is that static 3450 * lookup results are thrown away. If qualifier type is raw, an attempt to 3451 * infer a parameterized type is made using the first actual argument (that 3452 * would otherwise be ignored during the lookup). 3453 */ 3454 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper { 3455 3456 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 3457 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3458 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase); 3459 if (site.isRaw() && !argtypes.head.hasTag(NONE)) { 3460 Type asSuperSite = types.asSuper(argtypes.head, site.tsym); 3461 this.site = types.skipTypeVars(asSuperSite, true); 3462 } 3463 } 3464 3465 @Override 3466 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { 3467 return this; 3468 } 3469 3470 @Override 3471 ReferenceKind referenceKind(Symbol sym) { 3472 return ReferenceKind.UNBOUND; 3473 } 3474 } 3475 3476 /** 3477 * Helper class for array constructor lookup; an array constructor lookup 3478 * is simulated by looking up a method that returns the array type specified 3479 * as qualifier, and that accepts a single int parameter (size of the array). 3480 */ 3481 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper { 3482 3483 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 3484 List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3485 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 3486 } 3487 3488 @Override 3489 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3490 WriteableScope sc = WriteableScope.create(syms.arrayClass); 3491 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); 3492 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass); 3493 sc.enter(arrayConstr); 3494 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false); 3495 } 3496 3497 @Override 3498 ReferenceKind referenceKind(Symbol sym) { 3499 return ReferenceKind.ARRAY_CTOR; 3500 } 3501 } 3502 3503 /** 3504 * Helper class for constructor reference lookup. The lookup logic is based 3505 * upon either Resolve.findMethod or Resolve.findDiamond - depending on 3506 * whether the constructor reference needs diamond inference (this is the case 3507 * if the qualifier type is raw). A special erroneous symbol is returned 3508 * if the lookup returns the constructor of an inner class and there's no 3509 * enclosing instance in scope. 3510 */ 3511 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper { 3512 3513 boolean needsInference; 3514 3515 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 3516 List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 3517 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 3518 if (site.isRaw()) { 3519 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata()); 3520 needsInference = true; 3521 } 3522 } 3523 3524 @Override 3525 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 3526 Symbol sym = needsInference ? 3527 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : 3528 findMethod(env, site, name, argtypes, typeargtypes, 3529 phase.isBoxingRequired(), phase.isVarargsRequired()); 3530 return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym; 3531 } 3532 3533 @Override 3534 ReferenceKind referenceKind(Symbol sym) { 3535 return site.getEnclosingType().hasTag(NONE) ? 3536 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER; 3537 } 3538 } 3539 3540 /** 3541 * Main overload resolution routine. On each overload resolution step, a 3542 * lookup helper class is used to perform the method/constructor lookup; 3543 * at the end of the lookup, the helper is used to validate the results 3544 * (this last step might trigger overload resolution diagnostics). 3545 */ 3546 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) { 3547 MethodResolutionContext resolveContext = new MethodResolutionContext(); 3548 resolveContext.methodCheck = methodCheck; 3549 return lookupMethod(env, pos, location, resolveContext, lookupHelper); 3550 } 3551 3552 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, 3553 MethodResolutionContext resolveContext, LookupHelper lookupHelper) { 3554 MethodResolutionContext prevResolutionContext = currentResolutionContext; 3555 try { 3556 Symbol bestSoFar = methodNotFound; 3557 currentResolutionContext = resolveContext; 3558 for (MethodResolutionPhase phase : methodResolutionSteps) { 3559 if (lookupHelper.shouldStop(bestSoFar, phase)) 3560 break; 3561 MethodResolutionPhase prevPhase = currentResolutionContext.step; 3562 Symbol prevBest = bestSoFar; 3563 currentResolutionContext.step = phase; 3564 Symbol sym = lookupHelper.lookup(env, phase); 3565 lookupHelper.debug(pos, sym); 3566 bestSoFar = phase.mergeResults(bestSoFar, sym); 3567 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase; 3568 } 3569 return lookupHelper.access(env, pos, location, bestSoFar); 3570 } finally { 3571 currentResolutionContext = prevResolutionContext; 3572 } 3573 } 3574 3575 /** 3576 * Resolve `c.name' where name == this or name == super. 3577 * @param pos The position to use for error reporting. 3578 * @param env The environment current at the expression. 3579 * @param c The qualifier. 3580 * @param name The identifier's name. 3581 */ 3582 Symbol resolveSelf(DiagnosticPosition pos, 3583 Env<AttrContext> env, 3584 TypeSymbol c, 3585 Name name) { 3586 Env<AttrContext> env1 = env; 3587 boolean staticOnly = false; 3588 while (env1.outer != null) { 3589 if (isStatic(env1)) staticOnly = true; 3590 if (env1.enclClass.sym == c) { 3591 Symbol sym = env1.info.scope.findFirst(name); 3592 if (sym != null) { 3593 if (staticOnly) sym = new StaticError(sym); 3594 return accessBase(sym, pos, env.enclClass.sym.type, 3595 name, true); 3596 } 3597 } 3598 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 3599 env1 = env1.outer; 3600 } 3601 if (c.isInterface() && 3602 name == names._super && !isStatic(env) && 3603 types.isDirectSuperInterface(c, env.enclClass.sym)) { 3604 //this might be a default super call if one of the superinterfaces is 'c' 3605 for (Type t : pruneInterfaces(env.enclClass.type)) { 3606 if (t.tsym == c) { 3607 env.info.defaultSuperCallSite = t; 3608 return new VarSymbol(0, names._super, 3609 types.asSuper(env.enclClass.type, c), env.enclClass.sym); 3610 } 3611 } 3612 //find a direct super type that is a subtype of 'c' 3613 for (Type i : types.directSupertypes(env.enclClass.type)) { 3614 if (i.tsym.isSubClass(c, types) && i.tsym != c) { 3615 log.error(pos, 3616 Errors.IllegalDefaultSuperCall(c, 3617 Fragments.RedundantSupertype(c, i))); 3618 return syms.errSymbol; 3619 } 3620 } 3621 Assert.error(); 3622 } 3623 log.error(pos, Errors.NotEnclClass(c)); 3624 return syms.errSymbol; 3625 } 3626 //where 3627 private List<Type> pruneInterfaces(Type t) { 3628 ListBuffer<Type> result = new ListBuffer<>(); 3629 for (Type t1 : types.interfaces(t)) { 3630 boolean shouldAdd = true; 3631 for (Type t2 : types.directSupertypes(t)) { 3632 if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) { 3633 shouldAdd = false; 3634 } 3635 } 3636 if (shouldAdd) { 3637 result.append(t1); 3638 } 3639 } 3640 return result.toList(); 3641 } 3642 3643 3644 /** 3645 * Resolve `c.this' for an enclosing class c that contains the 3646 * named member. 3647 * @param pos The position to use for error reporting. 3648 * @param env The environment current at the expression. 3649 * @param member The member that must be contained in the result. 3650 */ 3651 Symbol resolveSelfContaining(DiagnosticPosition pos, 3652 Env<AttrContext> env, 3653 Symbol member, 3654 boolean isSuperCall) { 3655 Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall); 3656 if (sym == null) { 3657 log.error(pos, Errors.EnclClassRequired(member)); 3658 return syms.errSymbol; 3659 } else { 3660 return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true); 3661 } 3662 } 3663 3664 boolean enclosingInstanceMissing(Env<AttrContext> env, Type type) { 3665 if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) { 3666 Symbol encl = resolveSelfContainingInternal(env, type.tsym, false); 3667 return encl == null || encl.kind.isResolutionError(); 3668 } 3669 return false; 3670 } 3671 3672 private Symbol resolveSelfContainingInternal(Env<AttrContext> env, 3673 Symbol member, 3674 boolean isSuperCall) { 3675 Name name = names._this; 3676 Env<AttrContext> env1 = isSuperCall ? env.outer : env; 3677 boolean staticOnly = false; 3678 if (env1 != null) { 3679 while (env1 != null && env1.outer != null) { 3680 if (isStatic(env1)) staticOnly = true; 3681 if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) { 3682 Symbol sym = env1.info.scope.findFirst(name); 3683 if (sym != null) { 3684 if (staticOnly) sym = new StaticError(sym); 3685 return sym; 3686 } 3687 } 3688 if ((env1.enclClass.sym.flags() & STATIC) != 0) 3689 staticOnly = true; 3690 env1 = env1.outer; 3691 } 3692 } 3693 return null; 3694 } 3695 3696 /** 3697 * Resolve an appropriate implicit this instance for t's container. 3698 * JLS 8.8.5.1 and 15.9.2 3699 */ 3700 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) { 3701 return resolveImplicitThis(pos, env, t, false); 3702 } 3703 3704 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) { 3705 Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH) 3706 ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) 3707 : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; 3708 if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) { 3709 log.error(pos, Errors.CantRefBeforeCtorCalled("this")); 3710 } 3711 return thisType; 3712 } 3713 3714 /* *************************************************************************** 3715 * ResolveError classes, indicating error situations when accessing symbols 3716 ****************************************************************************/ 3717 3718 //used by TransTypes when checking target type of synthetic cast 3719 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) { 3720 AccessError error = new AccessError(env, env.enclClass.type, type.tsym); 3721 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null); 3722 } 3723 //where 3724 private void logResolveError(ResolveError error, 3725 DiagnosticPosition pos, 3726 Symbol location, 3727 Type site, 3728 Name name, 3729 List<Type> argtypes, 3730 List<Type> typeargtypes) { 3731 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 3732 pos, location, site, name, argtypes, typeargtypes); 3733 if (d != null) { 3734 d.setFlag(DiagnosticFlag.RESOLVE_ERROR); 3735 log.report(d); 3736 } 3737 } 3738 3739 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); 3740 3741 public Object methodArguments(List<Type> argtypes) { 3742 if (argtypes == null || argtypes.isEmpty()) { 3743 return noArgs; 3744 } else { 3745 ListBuffer<Object> diagArgs = new ListBuffer<>(); 3746 for (Type t : argtypes) { 3747 if (t.hasTag(DEFERRED)) { 3748 diagArgs.append(((DeferredAttr.DeferredType)t).tree); 3749 } else { 3750 diagArgs.append(t); 3751 } 3752 } 3753 return diagArgs; 3754 } 3755 } 3756 3757 /** 3758 * Root class for resolution errors. Subclass of ResolveError 3759 * represent a different kinds of resolution error - as such they must 3760 * specify how they map into concrete compiler diagnostics. 3761 */ 3762 abstract class ResolveError extends Symbol { 3763 3764 /** The name of the kind of error, for debugging only. */ 3765 final String debugName; 3766 3767 ResolveError(Kind kind, String debugName) { 3768 super(kind, 0, null, null, null); 3769 this.debugName = debugName; 3770 } 3771 3772 @Override @DefinedBy(Api.LANGUAGE_MODEL) 3773 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 3774 throw new AssertionError(); 3775 } 3776 3777 @Override 3778 public String toString() { 3779 return debugName; 3780 } 3781 3782 @Override 3783 public boolean exists() { 3784 return false; 3785 } 3786 3787 @Override 3788 public boolean isStatic() { 3789 return false; 3790 } 3791 3792 /** 3793 * Create an external representation for this erroneous symbol to be 3794 * used during attribution - by default this returns the symbol of a 3795 * brand new error type which stores the original type found 3796 * during resolution. 3797 * 3798 * @param name the name used during resolution 3799 * @param location the location from which the symbol is accessed 3800 */ 3801 protected Symbol access(Name name, TypeSymbol location) { 3802 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 3803 } 3804 3805 /** 3806 * Create a diagnostic representing this resolution error. 3807 * 3808 * @param dkind The kind of the diagnostic to be created (e.g error). 3809 * @param pos The position to be used for error reporting. 3810 * @param site The original type from where the selection took place. 3811 * @param name The name of the symbol to be resolved. 3812 * @param argtypes The invocation's value arguments, 3813 * if we looked for a method. 3814 * @param typeargtypes The invocation's type arguments, 3815 * if we looked for a method. 3816 */ 3817 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3818 DiagnosticPosition pos, 3819 Symbol location, 3820 Type site, 3821 Name name, 3822 List<Type> argtypes, 3823 List<Type> typeargtypes); 3824 } 3825 3826 /** 3827 * This class is the root class of all resolution errors caused by 3828 * an invalid symbol being found during resolution. 3829 */ 3830 abstract class InvalidSymbolError extends ResolveError { 3831 3832 /** The invalid symbol found during resolution */ 3833 Symbol sym; 3834 3835 InvalidSymbolError(Kind kind, Symbol sym, String debugName) { 3836 super(kind, debugName); 3837 this.sym = sym; 3838 } 3839 3840 @Override 3841 public boolean exists() { 3842 return true; 3843 } 3844 3845 @Override 3846 public String toString() { 3847 return super.toString() + " wrongSym=" + sym; 3848 } 3849 3850 @Override 3851 public Symbol access(Name name, TypeSymbol location) { 3852 if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP)) 3853 return types.createErrorType(name, location, sym.type).tsym; 3854 else 3855 return sym; 3856 } 3857 } 3858 3859 class BadRestrictedTypeError extends ResolveError { 3860 private final Name typeName; 3861 BadRestrictedTypeError(Name typeName) { 3862 super(Kind.BAD_RESTRICTED_TYPE, "bad var use"); 3863 this.typeName = typeName; 3864 } 3865 3866 @Override 3867 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 3868 return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName); 3869 } 3870 } 3871 3872 /** 3873 * InvalidSymbolError error class indicating that a symbol matching a 3874 * given name does not exists in a given site. 3875 */ 3876 class SymbolNotFoundError extends ResolveError { 3877 3878 SymbolNotFoundError(Kind kind) { 3879 this(kind, "symbol not found error"); 3880 } 3881 3882 SymbolNotFoundError(Kind kind, String debugName) { 3883 super(kind, debugName); 3884 } 3885 3886 @Override 3887 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3888 DiagnosticPosition pos, 3889 Symbol location, 3890 Type site, 3891 Name name, 3892 List<Type> argtypes, 3893 List<Type> typeargtypes) { 3894 argtypes = argtypes == null ? List.nil() : argtypes; 3895 typeargtypes = typeargtypes == null ? List.nil() : typeargtypes; 3896 if (name == names.error) 3897 return null; 3898 3899 boolean hasLocation = false; 3900 if (location == null) { 3901 location = site.tsym; 3902 } 3903 if (!location.name.isEmpty()) { 3904 if (location.kind == PCK && !site.tsym.exists()) { 3905 return diags.create(dkind, log.currentSource(), pos, 3906 "doesnt.exist", location); 3907 } 3908 hasLocation = !location.name.equals(names._this) && 3909 !location.name.equals(names._super); 3910 } 3911 boolean isConstructor = name == names.init; 3912 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind(); 3913 Name idname = isConstructor ? site.tsym.name : name; 3914 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); 3915 if (hasLocation) { 3916 return diags.create(dkind, log.currentSource(), pos, 3917 errKey, kindname, idname, //symbol kindname, name 3918 typeargtypes, args(argtypes), //type parameters and arguments (if any) 3919 getLocationDiag(location, site)); //location kindname, type 3920 } 3921 else { 3922 return diags.create(dkind, log.currentSource(), pos, 3923 errKey, kindname, idname, //symbol kindname, name 3924 typeargtypes, args(argtypes)); //type parameters and arguments (if any) 3925 } 3926 } 3927 //where 3928 private Object args(List<Type> args) { 3929 return args.isEmpty() ? args : methodArguments(args); 3930 } 3931 3932 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) { 3933 String key = "cant.resolve"; 3934 String suffix = hasLocation ? ".location" : ""; 3935 switch (kindname) { 3936 case METHOD: 3937 case CONSTRUCTOR: { 3938 suffix += ".args"; 3939 suffix += hasTypeArgs ? ".params" : ""; 3940 } 3941 } 3942 return key + suffix; 3943 } 3944 private JCDiagnostic getLocationDiag(Symbol location, Type site) { 3945 if (location.kind == VAR) { 3946 return diags.fragment(Fragments.Location1(kindName(location), 3947 location, 3948 location.type)); 3949 } else { 3950 return diags.fragment(Fragments.Location(typeKindName(site), 3951 site, 3952 null)); 3953 } 3954 } 3955 } 3956 3957 /** 3958 * InvalidSymbolError error class indicating that a given symbol 3959 * (either a method, a constructor or an operand) is not applicable 3960 * given an actual arguments/type argument list. 3961 */ 3962 class InapplicableSymbolError extends ResolveError { 3963 3964 protected MethodResolutionContext resolveContext; 3965 3966 InapplicableSymbolError(MethodResolutionContext context) { 3967 this(WRONG_MTH, "inapplicable symbol error", context); 3968 } 3969 3970 protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) { 3971 super(kind, debugName); 3972 this.resolveContext = context; 3973 } 3974 3975 @Override 3976 public String toString() { 3977 return super.toString(); 3978 } 3979 3980 @Override 3981 public boolean exists() { 3982 return true; 3983 } 3984 3985 @Override 3986 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 3987 DiagnosticPosition pos, 3988 Symbol location, 3989 Type site, 3990 Name name, 3991 List<Type> argtypes, 3992 List<Type> typeargtypes) { 3993 if (name == names.error) 3994 return null; 3995 3996 Pair<Symbol, JCDiagnostic> c = errCandidate(); 3997 if (compactMethodDiags) { 3998 JCDiagnostic simpleDiag = 3999 MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd); 4000 if (simpleDiag != null) { 4001 return simpleDiag; 4002 } 4003 } 4004 Symbol ws = c.fst.asMemberOf(site, types); 4005 return diags.create(dkind, log.currentSource(), pos, 4006 "cant.apply.symbol", 4007 kindName(ws), 4008 ws.name == names.init ? ws.owner.name : ws.name, 4009 methodArguments(ws.type.getParameterTypes()), 4010 methodArguments(argtypes), 4011 kindName(ws.owner), 4012 ws.owner.type, 4013 c.snd); 4014 } 4015 4016 @Override 4017 public Symbol access(Name name, TypeSymbol location) { 4018 Symbol sym = bestCandidate(); 4019 return types.createErrorType(name, location, sym != null ? sym.type : syms.errSymbol.type).tsym; 4020 } 4021 4022 protected Symbol bestCandidate() { 4023 return errCandidate().fst; 4024 } 4025 4026 protected Pair<Symbol, JCDiagnostic> errCandidate() { 4027 Candidate bestSoFar = null; 4028 for (Candidate c : resolveContext.candidates) { 4029 if (c.isApplicable()) continue; 4030 bestSoFar = c; 4031 } 4032 Assert.checkNonNull(bestSoFar); 4033 return new Pair<>(bestSoFar.sym, bestSoFar.details); 4034 } 4035 } 4036 4037 /** 4038 * ResolveError error class indicating that a symbol (either methods, constructors or operand) 4039 * is not applicable given an actual arguments/type argument list. 4040 */ 4041 class InapplicableSymbolsError extends InapplicableSymbolError { 4042 4043 InapplicableSymbolsError(MethodResolutionContext context) { 4044 super(WRONG_MTHS, "inapplicable symbols", context); 4045 } 4046 4047 @Override 4048 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4049 DiagnosticPosition pos, 4050 Symbol location, 4051 Type site, 4052 Name name, 4053 List<Type> argtypes, 4054 List<Type> typeargtypes) { 4055 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates(); 4056 Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ? 4057 filterCandidates(candidatesMap) : 4058 mapCandidates(); 4059 if (filteredCandidates.isEmpty()) { 4060 filteredCandidates = candidatesMap; 4061 } 4062 boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size(); 4063 if (filteredCandidates.size() > 1) { 4064 JCDiagnostic err = diags.create(dkind, 4065 null, 4066 truncatedDiag ? 4067 EnumSet.of(DiagnosticFlag.COMPRESSED) : 4068 EnumSet.noneOf(DiagnosticFlag.class), 4069 log.currentSource(), 4070 pos, 4071 "cant.apply.symbols", 4072 name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(), 4073 name == names.init ? site.tsym.name : name, 4074 methodArguments(argtypes)); 4075 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site)); 4076 } else if (filteredCandidates.size() == 1) { 4077 Map.Entry<Symbol, JCDiagnostic> _e = 4078 filteredCandidates.entrySet().iterator().next(); 4079 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue()); 4080 JCDiagnostic d = new InapplicableSymbolError(resolveContext) { 4081 @Override 4082 protected Pair<Symbol, JCDiagnostic> errCandidate() { 4083 return p; 4084 } 4085 }.getDiagnostic(dkind, pos, 4086 location, site, name, argtypes, typeargtypes); 4087 if (truncatedDiag) { 4088 d.setFlag(DiagnosticFlag.COMPRESSED); 4089 } 4090 return d; 4091 } else { 4092 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, 4093 location, site, name, argtypes, typeargtypes); 4094 } 4095 } 4096 //where 4097 private Map<Symbol, JCDiagnostic> mapCandidates() { 4098 MostSpecificMap candidates = new MostSpecificMap(); 4099 for (Candidate c : resolveContext.candidates) { 4100 if (c.isApplicable()) continue; 4101 candidates.put(c); 4102 } 4103 return candidates; 4104 } 4105 4106 @SuppressWarnings("serial") 4107 private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> { 4108 private void put(Candidate c) { 4109 ListBuffer<Symbol> overridden = new ListBuffer<>(); 4110 for (Symbol s : keySet()) { 4111 if (s == c.sym) { 4112 continue; 4113 } 4114 if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) { 4115 overridden.add(s); 4116 } else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) { 4117 return; 4118 } 4119 } 4120 for (Symbol s : overridden) { 4121 remove(s); 4122 } 4123 put(c.sym, c.details); 4124 } 4125 } 4126 4127 Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) { 4128 Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>(); 4129 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) { 4130 JCDiagnostic d = _entry.getValue(); 4131 if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) { 4132 candidates.put(_entry.getKey(), d); 4133 } 4134 } 4135 return candidates; 4136 } 4137 4138 private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) { 4139 List<JCDiagnostic> details = List.nil(); 4140 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) { 4141 Symbol sym = _entry.getKey(); 4142 JCDiagnostic detailDiag = 4143 diags.fragment(Fragments.InapplicableMethod(Kinds.kindName(sym), 4144 sym.location(site, types), 4145 sym.asMemberOf(site, types), 4146 _entry.getValue())); 4147 details = details.prepend(detailDiag); 4148 } 4149 //typically members are visited in reverse order (see Scope) 4150 //so we need to reverse the candidate list so that candidates 4151 //conform to source order 4152 return details; 4153 } 4154 4155 @Override 4156 protected Symbol bestCandidate() { 4157 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates(); 4158 Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap); 4159 if (filteredCandidates.size() == 1) { 4160 return filteredCandidates.keySet().iterator().next(); 4161 } 4162 return null; 4163 } 4164 } 4165 4166 /** 4167 * DiamondError error class indicating that a constructor symbol is not applicable 4168 * given an actual arguments/type argument list using diamond inference. 4169 */ 4170 class DiamondError extends InapplicableSymbolError { 4171 4172 Symbol sym; 4173 4174 public DiamondError(Symbol sym, MethodResolutionContext context) { 4175 super(sym.kind, "diamondError", context); 4176 this.sym = sym; 4177 } 4178 4179 JCDiagnostic getDetails() { 4180 return (sym.kind == WRONG_MTH) ? 4181 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd : 4182 null; 4183 } 4184 4185 @Override 4186 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 4187 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4188 JCDiagnostic details = getDetails(); 4189 if (details != null && compactMethodDiags) { 4190 JCDiagnostic simpleDiag = 4191 MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details); 4192 if (simpleDiag != null) { 4193 return simpleDiag; 4194 } 4195 } 4196 String key = details == null ? 4197 "cant.apply.diamond" : 4198 "cant.apply.diamond.1"; 4199 return diags.create(dkind, log.currentSource(), pos, key, 4200 Fragments.Diamond(site.tsym), details); 4201 } 4202 } 4203 4204 /** 4205 * An InvalidSymbolError error class indicating that a symbol is not 4206 * accessible from a given site 4207 */ 4208 class AccessError extends InvalidSymbolError { 4209 4210 private Env<AttrContext> env; 4211 private Type site; 4212 4213 AccessError(Env<AttrContext> env, Type site, Symbol sym) { 4214 super(HIDDEN, sym, "access error"); 4215 this.env = env; 4216 this.site = site; 4217 } 4218 4219 @Override 4220 public boolean exists() { 4221 return false; 4222 } 4223 4224 @Override 4225 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4226 DiagnosticPosition pos, 4227 Symbol location, 4228 Type site, 4229 Name name, 4230 List<Type> argtypes, 4231 List<Type> typeargtypes) { 4232 if (sym.name == names.init && sym.owner != site.tsym) { 4233 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, 4234 pos, location, site, name, argtypes, typeargtypes); 4235 } 4236 else if ((sym.flags() & PUBLIC) != 0 4237 || (env != null && this.site != null 4238 && !isAccessible(env, this.site))) { 4239 if (sym.owner.kind == PCK) { 4240 return diags.create(dkind, log.currentSource(), 4241 pos, "not.def.access.package.cant.access", 4242 sym, sym.location(), inaccessiblePackageReason(env, sym.packge())); 4243 } else if ( sym.packge() != syms.rootPackage 4244 && !symbolPackageVisible(env, sym)) { 4245 return diags.create(dkind, log.currentSource(), 4246 pos, "not.def.access.class.intf.cant.access.reason", 4247 sym, sym.location(), sym.location().packge(), 4248 inaccessiblePackageReason(env, sym.packge())); 4249 } else { 4250 return diags.create(dkind, log.currentSource(), 4251 pos, "not.def.access.class.intf.cant.access", 4252 sym, sym.location()); 4253 } 4254 } 4255 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { 4256 return diags.create(dkind, log.currentSource(), 4257 pos, "report.access", sym, 4258 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 4259 sym.location()); 4260 } 4261 else { 4262 return diags.create(dkind, log.currentSource(), 4263 pos, "not.def.public.cant.access", sym, sym.location()); 4264 } 4265 } 4266 4267 private String toString(Type type) { 4268 StringBuilder sb = new StringBuilder(); 4269 sb.append(type); 4270 if (type != null) { 4271 sb.append("[tsym:").append(type.tsym); 4272 if (type.tsym != null) 4273 sb.append("packge:").append(type.tsym.packge()); 4274 sb.append("]"); 4275 } 4276 return sb.toString(); 4277 } 4278 } 4279 4280 class InvisibleSymbolError extends InvalidSymbolError { 4281 4282 private final Env<AttrContext> env; 4283 private final boolean suppressError; 4284 4285 InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) { 4286 super(HIDDEN, sym, "invisible class error"); 4287 this.env = env; 4288 this.suppressError = suppressError; 4289 this.name = sym.name; 4290 } 4291 4292 @Override 4293 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4294 DiagnosticPosition pos, 4295 Symbol location, 4296 Type site, 4297 Name name, 4298 List<Type> argtypes, 4299 List<Type> typeargtypes) { 4300 if (suppressError) 4301 return null; 4302 4303 if (sym.kind == PCK) { 4304 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge()); 4305 return diags.create(dkind, log.currentSource(), 4306 pos, "package.not.visible", sym, details); 4307 } 4308 4309 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge()); 4310 4311 if (pos.getTree() != null) { 4312 Symbol o = sym; 4313 JCTree tree = pos.getTree(); 4314 4315 while (o.kind != PCK && tree.hasTag(SELECT)) { 4316 o = o.owner; 4317 tree = ((JCFieldAccess) tree).selected; 4318 } 4319 4320 if (o.kind == PCK) { 4321 pos = tree.pos(); 4322 4323 return diags.create(dkind, log.currentSource(), 4324 pos, "package.not.visible", o, details); 4325 } 4326 } 4327 4328 return diags.create(dkind, log.currentSource(), 4329 pos, "not.def.access.package.cant.access", sym, sym.packge(), details); 4330 } 4331 } 4332 4333 JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) { 4334 //no dependency: 4335 if (!env.toplevel.modle.readModules.contains(sym.modle)) { 4336 //does not read: 4337 if (sym.modle != syms.unnamedModule) { 4338 if (env.toplevel.modle != syms.unnamedModule) { 4339 return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle, 4340 sym, 4341 sym.modle)); 4342 } else { 4343 return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym, 4344 sym.modle)); 4345 } 4346 } else { 4347 return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym, 4348 env.toplevel.modle)); 4349 } 4350 } else { 4351 if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) { 4352 //not exported to this module: 4353 if (env.toplevel.modle != syms.unnamedModule) { 4354 return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym, 4355 sym.modle, 4356 env.toplevel.modle)); 4357 } else { 4358 return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym, 4359 sym.modle)); 4360 } 4361 } else { 4362 //not exported: 4363 if (env.toplevel.modle != syms.unnamedModule) { 4364 return diags.fragment(Fragments.NotDefAccessNotExported(sym, 4365 sym.modle)); 4366 } else { 4367 return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym, 4368 sym.modle)); 4369 } 4370 } 4371 } 4372 } 4373 4374 /** 4375 * InvalidSymbolError error class indicating that an instance member 4376 * has erroneously been accessed from a static context. 4377 */ 4378 class StaticError extends InvalidSymbolError { 4379 4380 StaticError(Symbol sym) { 4381 super(STATICERR, sym, "static error"); 4382 } 4383 4384 @Override 4385 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4386 DiagnosticPosition pos, 4387 Symbol location, 4388 Type site, 4389 Name name, 4390 List<Type> argtypes, 4391 List<Type> typeargtypes) { 4392 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS)) 4393 ? types.erasure(sym.type).tsym 4394 : sym); 4395 return diags.create(dkind, log.currentSource(), pos, 4396 "non-static.cant.be.ref", kindName(sym), errSym); 4397 } 4398 } 4399 4400 /** 4401 * InvalidSymbolError error class indicating that a pair of symbols 4402 * (either methods, constructors or operands) are ambiguous 4403 * given an actual arguments/type argument list. 4404 */ 4405 class AmbiguityError extends ResolveError { 4406 4407 /** The other maximally specific symbol */ 4408 List<Symbol> ambiguousSyms = List.nil(); 4409 4410 @Override 4411 public boolean exists() { 4412 return true; 4413 } 4414 4415 AmbiguityError(Symbol sym1, Symbol sym2) { 4416 super(AMBIGUOUS, "ambiguity error"); 4417 ambiguousSyms = flatten(sym2).appendList(flatten(sym1)); 4418 } 4419 4420 private List<Symbol> flatten(Symbol sym) { 4421 if (sym.kind == AMBIGUOUS) { 4422 return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms; 4423 } else { 4424 return List.of(sym); 4425 } 4426 } 4427 4428 AmbiguityError addAmbiguousSymbol(Symbol s) { 4429 ambiguousSyms = ambiguousSyms.prepend(s); 4430 return this; 4431 } 4432 4433 @Override 4434 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 4435 DiagnosticPosition pos, 4436 Symbol location, 4437 Type site, 4438 Name name, 4439 List<Type> argtypes, 4440 List<Type> typeargtypes) { 4441 List<Symbol> diagSyms = ambiguousSyms.reverse(); 4442 Symbol s1 = diagSyms.head; 4443 Symbol s2 = diagSyms.tail.head; 4444 Name sname = s1.name; 4445 if (sname == names.init) sname = s1.owner.name; 4446 return diags.create(dkind, log.currentSource(), 4447 pos, "ref.ambiguous", sname, 4448 kindName(s1), 4449 s1, 4450 s1.location(site, types), 4451 kindName(s2), 4452 s2, 4453 s2.location(site, types)); 4454 } 4455 4456 /** 4457 * If multiple applicable methods are found during overload and none of them 4458 * is more specific than the others, attempt to merge their signatures. 4459 */ 4460 Symbol mergeAbstracts(Type site) { 4461 List<Symbol> ambiguousInOrder = ambiguousSyms.reverse(); 4462 return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this); 4463 } 4464 4465 @Override 4466 protected Symbol access(Name name, TypeSymbol location) { 4467 Symbol firstAmbiguity = ambiguousSyms.last(); 4468 return firstAmbiguity.kind == TYP ? 4469 types.createErrorType(name, location, firstAmbiguity.type).tsym : 4470 firstAmbiguity; 4471 } 4472 } 4473 4474 class BadVarargsMethod extends ResolveError { 4475 4476 ResolveError delegatedError; 4477 4478 BadVarargsMethod(ResolveError delegatedError) { 4479 super(delegatedError.kind, "badVarargs"); 4480 this.delegatedError = delegatedError; 4481 } 4482 4483 @Override 4484 public Symbol baseSymbol() { 4485 return delegatedError.baseSymbol(); 4486 } 4487 4488 @Override 4489 protected Symbol access(Name name, TypeSymbol location) { 4490 return delegatedError.access(name, location); 4491 } 4492 4493 @Override 4494 public boolean exists() { 4495 return true; 4496 } 4497 4498 @Override 4499 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4500 return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes); 4501 } 4502 } 4503 4504 /** 4505 * BadMethodReferenceError error class indicating that a method reference symbol has been found, 4506 * but with the wrong staticness. 4507 */ 4508 class BadMethodReferenceError extends StaticError { 4509 4510 boolean unboundLookup; 4511 4512 public BadMethodReferenceError(Symbol sym, boolean unboundLookup) { 4513 super(sym); 4514 this.unboundLookup = unboundLookup; 4515 } 4516 4517 @Override 4518 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4519 final String key; 4520 if (!unboundLookup) { 4521 key = "bad.static.method.in.bound.lookup"; 4522 } else if (sym.isStatic()) { 4523 key = "bad.static.method.in.unbound.lookup"; 4524 } else { 4525 key = "bad.instance.method.in.unbound.lookup"; 4526 } 4527 return sym.kind.isResolutionError() ? 4528 ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) : 4529 diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym); 4530 } 4531 } 4532 4533 /** 4534 * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found, 4535 * but pointing to a class for which an enclosing instance is not available. 4536 */ 4537 class BadConstructorReferenceError extends InvalidSymbolError { 4538 4539 public BadConstructorReferenceError(Symbol sym) { 4540 super(MISSING_ENCL, sym, "BadConstructorReferenceError"); 4541 } 4542 4543 @Override 4544 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4545 return diags.create(dkind, log.currentSource(), pos, 4546 "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); 4547 } 4548 } 4549 4550 class BadClassFileError extends InvalidSymbolError { 4551 4552 private final CompletionFailure ex; 4553 4554 public BadClassFileError(CompletionFailure ex) { 4555 super(HIDDEN, ex.sym, "BadClassFileError"); 4556 this.name = sym.name; 4557 this.ex = ex; 4558 } 4559 4560 @Override 4561 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 4562 JCDiagnostic d = diags.create(dkind, log.currentSource(), pos, 4563 "cant.access", ex.sym, ex.getDetailValue()); 4564 4565 d.setFlag(DiagnosticFlag.NON_DEFERRABLE); 4566 return d; 4567 } 4568 4569 } 4570 4571 /** 4572 * Helper class for method resolution diagnostic simplification. 4573 * Certain resolution diagnostic are rewritten as simpler diagnostic 4574 * where the enclosing resolution diagnostic (i.e. 'inapplicable method') 4575 * is stripped away, as it doesn't carry additional info. The logic 4576 * for matching a given diagnostic is given in terms of a template 4577 * hierarchy: a diagnostic template can be specified programmatically, 4578 * so that only certain diagnostics are matched. Each templete is then 4579 * associated with a rewriter object that carries out the task of rewtiting 4580 * the diagnostic to a simpler one. 4581 */ 4582 static class MethodResolutionDiagHelper { 4583 4584 /** 4585 * A diagnostic rewriter transforms a method resolution diagnostic 4586 * into a simpler one 4587 */ 4588 interface DiagnosticRewriter { 4589 JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, 4590 DiagnosticPosition preferredPos, DiagnosticSource preferredSource, 4591 DiagnosticType preferredKind, JCDiagnostic d); 4592 } 4593 4594 /** 4595 * A diagnostic template is made up of two ingredients: (i) a regular 4596 * expression for matching a diagnostic key and (ii) a list of sub-templates 4597 * for matching diagnostic arguments. 4598 */ 4599 static class Template { 4600 4601 /** regex used to match diag key */ 4602 String regex; 4603 4604 /** templates used to match diagnostic args */ 4605 Template[] subTemplates; 4606 4607 Template(String key, Template... subTemplates) { 4608 this.regex = key; 4609 this.subTemplates = subTemplates; 4610 } 4611 4612 /** 4613 * Returns true if the regex matches the diagnostic key and if 4614 * all diagnostic arguments are matches by corresponding sub-templates. 4615 */ 4616 boolean matches(Object o) { 4617 JCDiagnostic d = (JCDiagnostic)o; 4618 Object[] args = d.getArgs(); 4619 if (!d.getCode().matches(regex) || 4620 subTemplates.length != d.getArgs().length) { 4621 return false; 4622 } 4623 for (int i = 0; i < args.length ; i++) { 4624 if (!subTemplates[i].matches(args[i])) { 4625 return false; 4626 } 4627 } 4628 return true; 4629 } 4630 } 4631 4632 /** 4633 * Common rewriter for all argument mismatch simplifications. 4634 */ 4635 static class ArgMismatchRewriter implements DiagnosticRewriter { 4636 4637 /** the index of the subdiagnostic to be used as primary. */ 4638 int causeIndex; 4639 4640 public ArgMismatchRewriter(int causeIndex) { 4641 this.causeIndex = causeIndex; 4642 } 4643 4644 @Override 4645 public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, 4646 DiagnosticPosition preferredPos, DiagnosticSource preferredSource, 4647 DiagnosticType preferredKind, JCDiagnostic d) { 4648 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex]; 4649 DiagnosticPosition pos = d.getDiagnosticPosition(); 4650 if (pos == null) { 4651 pos = preferredPos; 4652 } 4653 return diags.create(preferredKind, preferredSource, pos, 4654 "prob.found.req", cause); 4655 } 4656 } 4657 4658 /** a dummy template that match any diagnostic argument */ 4659 static final Template skip = new Template("") { 4660 @Override 4661 boolean matches(Object d) { 4662 return true; 4663 } 4664 }; 4665 4666 /** template for matching inference-free arguments mismatch failures */ 4667 static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip); 4668 4669 /** template for matching inference related arguments mismatch failures */ 4670 static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) { 4671 @Override 4672 boolean matches(Object o) { 4673 if (!super.matches(o)) { 4674 return false; 4675 } 4676 JCDiagnostic d = (JCDiagnostic)o; 4677 @SuppressWarnings("unchecked") 4678 List<Type> tvars = (List<Type>)d.getArgs()[0]; 4679 return !containsAny(d, tvars); 4680 } 4681 4682 BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> { 4683 if (o instanceof Type) { 4684 return ((Type)o).containsAny(ts); 4685 } else if (o instanceof JCDiagnostic) { 4686 return containsAny((JCDiagnostic)o, ts); 4687 } else { 4688 return false; 4689 } 4690 }; 4691 4692 boolean containsAny(JCDiagnostic d, List<Type> ts) { 4693 return Stream.of(d.getArgs()) 4694 .anyMatch(o -> containsPredicate.test(o, ts)); 4695 } 4696 }; 4697 4698 /** rewriter map used for method resolution simplification */ 4699 static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>(); 4700 4701 static { 4702 rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0)); 4703 rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1)); 4704 } 4705 4706 /** 4707 * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it, 4708 * and rewrite it accordingly. 4709 */ 4710 static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source, 4711 DiagnosticType dkind, JCDiagnostic d) { 4712 for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) { 4713 if (_entry.getKey().matches(d)) { 4714 JCDiagnostic simpleDiag = 4715 _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d); 4716 simpleDiag.setFlag(DiagnosticFlag.COMPRESSED); 4717 return simpleDiag; 4718 } 4719 } 4720 return null; 4721 } 4722 } 4723 4724 enum MethodResolutionPhase { 4725 BASIC(false, false), 4726 BOX(true, false), 4727 VARARITY(true, true) { 4728 @Override 4729 public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { 4730 //Check invariants (see {@code LookupHelper.shouldStop}) 4731 Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS); 4732 if (!sym.kind.isResolutionError()) { 4733 //varargs resolution successful 4734 return sym; 4735 } else { 4736 //pick best error 4737 switch (bestSoFar.kind) { 4738 case WRONG_MTH: 4739 case WRONG_MTHS: 4740 //Override previous errors if they were caused by argument mismatch. 4741 //This generally means preferring current symbols - but we need to pay 4742 //attention to the fact that the varargs lookup returns 'less' candidates 4743 //than the previous rounds, and adjust that accordingly. 4744 switch (sym.kind) { 4745 case WRONG_MTH: 4746 //if the previous round matched more than one method, return that 4747 //result instead 4748 return bestSoFar.kind == WRONG_MTHS ? 4749 bestSoFar : sym; 4750 case ABSENT_MTH: 4751 //do not override erroneous symbol if the arity lookup did not 4752 //match any method 4753 return bestSoFar; 4754 case WRONG_MTHS: 4755 default: 4756 //safe to override 4757 return sym; 4758 } 4759 default: 4760 //otherwise, return first error 4761 return bestSoFar; 4762 } 4763 } 4764 } 4765 }; 4766 4767 final boolean isBoxingRequired; 4768 final boolean isVarargsRequired; 4769 4770 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { 4771 this.isBoxingRequired = isBoxingRequired; 4772 this.isVarargsRequired = isVarargsRequired; 4773 } 4774 4775 public boolean isBoxingRequired() { 4776 return isBoxingRequired; 4777 } 4778 4779 public boolean isVarargsRequired() { 4780 return isVarargsRequired; 4781 } 4782 4783 public Symbol mergeResults(Symbol prev, Symbol sym) { 4784 return sym; 4785 } 4786 } 4787 4788 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); 4789 4790 /** 4791 * A resolution context is used to keep track of intermediate results of 4792 * overload resolution, such as list of method that are not applicable 4793 * (used to generate more precise diagnostics) and so on. Resolution contexts 4794 * can be nested - this means that when each overload resolution routine should 4795 * work within the resolution context it created. 4796 */ 4797 class MethodResolutionContext { 4798 4799 private List<Candidate> candidates = List.nil(); 4800 4801 MethodResolutionPhase step = null; 4802 4803 MethodCheck methodCheck = resolveMethodCheck; 4804 4805 private boolean internalResolution = false; 4806 private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE; 4807 4808 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { 4809 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); 4810 candidates = candidates.append(c); 4811 } 4812 4813 void addApplicableCandidate(Symbol sym, Type mtype) { 4814 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype); 4815 candidates = candidates.append(c); 4816 } 4817 4818 DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) { 4819 DeferredAttrContext parent = (pendingResult == null) 4820 ? deferredAttr.emptyDeferredAttrContext 4821 : pendingResult.checkContext.deferredAttrContext(); 4822 return deferredAttr.new DeferredAttrContext(attrMode, sym, step, 4823 inferenceContext, parent, warn); 4824 } 4825 4826 /** 4827 * This class represents an overload resolution candidate. There are two 4828 * kinds of candidates: applicable methods and inapplicable methods; 4829 * applicable methods have a pointer to the instantiated method type, 4830 * while inapplicable candidates contain further details about the 4831 * reason why the method has been considered inapplicable. 4832 */ 4833 @SuppressWarnings("overrides") 4834 class Candidate { 4835 4836 final MethodResolutionPhase step; 4837 final Symbol sym; 4838 final JCDiagnostic details; 4839 final Type mtype; 4840 4841 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) { 4842 this.step = step; 4843 this.sym = sym; 4844 this.details = details; 4845 this.mtype = mtype; 4846 } 4847 4848 boolean isApplicable() { 4849 return mtype != null; 4850 } 4851 } 4852 4853 DeferredAttr.AttrMode attrMode() { 4854 return attrMode; 4855 } 4856 4857 boolean internal() { 4858 return internalResolution; 4859 } 4860 } 4861 4862 MethodResolutionContext currentResolutionContext = null; 4863 }