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