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