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