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