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