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