1 /* 2 * Copyright (c) 1999, 2012, 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 26 package com.sun.tools.javac.comp; 27 28 import com.sun.tools.javac.api.Formattable.LocalizedString; 29 import com.sun.tools.javac.code.*; 30 import com.sun.tools.javac.code.Type.*; 31 import com.sun.tools.javac.code.Symbol.*; 32 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; 33 import com.sun.tools.javac.file.JavacFileManager; 34 import com.sun.tools.javac.jvm.*; 35 import com.sun.tools.javac.tree.*; 36 import com.sun.tools.javac.tree.JCTree.*; 37 import com.sun.tools.javac.util.*; 38 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 39 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 40 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; 41 import javax.tools.JavaFileManager; 42 43 import java.util.Arrays; 44 import java.util.Collection; 45 import java.util.EnumMap; 46 import java.util.EnumSet; 47 import java.util.HashSet; 48 import java.util.Map; 49 import java.util.Set; 50 51 import javax.lang.model.element.ElementVisitor; 52 53 import static com.sun.tools.javac.code.Flags.*; 54 import static com.sun.tools.javac.code.Flags.BLOCK; 55 import static com.sun.tools.javac.code.Kinds.*; 56 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; 57 import static com.sun.tools.javac.code.TypeTags.*; 58 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; 59 import static com.sun.tools.javac.tree.JCTree.Tag.*; 60 import javax.tools.JavaFileObject; 61 62 /** Helper class for name resolution, used mostly by the attribution phase. 63 * 64 * <p><b>This is NOT part of any supported API. 65 * If you write code that depends on this, you do so at your own risk. 66 * This code and its internal interfaces are subject to change or 67 * deletion without notice.</b> 68 */ 69 public class Resolve { 70 protected static final Context.Key<Resolve> resolveKey = 71 new Context.Key<Resolve>(); 72 73 Names names; 74 Log log; 75 Symtab syms; 76 Check chk; 77 Infer infer; 78 JavacFileManager fm; 79 Lint lint; 80 ClassReader reader; 81 TreeInfo treeinfo; 82 Types types; 83 JCDiagnostic.Factory diags; 84 public final boolean boxingEnabled; // = source.allowBoxing(); 85 public final boolean varargsEnabled; // = source.allowVarargs(); 86 public final boolean allowMethodHandles; 87 private final boolean debugResolve; 88 final EnumSet<VerboseResolutionMode> verboseResolutionMode; 89 90 Scope polymorphicSignatureScope; 91 92 protected Resolve(Context context) { 93 context.put(resolveKey, this); 94 syms = Symtab.instance(context); 95 96 varNotFound = new 97 SymbolNotFoundError(ABSENT_VAR); 98 wrongMethod = new 99 InapplicableSymbolError(); 100 wrongMethods = new 101 InapplicableSymbolsError(); 102 methodNotFound = new 103 SymbolNotFoundError(ABSENT_MTH); 104 typeNotFound = new 105 SymbolNotFoundError(ABSENT_TYP); 106 107 names = Names.instance(context); 108 log = Log.instance(context); 109 chk = Check.instance(context); 110 infer = Infer.instance(context); 111 if (context.get(JavaFileManager.class) instanceof JavacFileManager) { 112 fm = (JavacFileManager)context.get(JavaFileManager.class); 113 } else { 114 fm = null; 115 } 116 lint = Lint.instance(context); 117 reader = ClassReader.instance(context); 118 treeinfo = TreeInfo.instance(context); 119 types = Types.instance(context); 120 diags = JCDiagnostic.Factory.instance(context); 121 Source source = Source.instance(context); 122 boxingEnabled = source.allowBoxing(); 123 varargsEnabled = source.allowVarargs(); 124 Options options = Options.instance(context); 125 debugResolve = options.isSet("debugresolve"); 126 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); 127 Target target = Target.instance(context); 128 allowMethodHandles = target.hasMethodHandles(); 129 polymorphicSignatureScope = new Scope(syms.noSymbol); 130 131 inapplicableMethodException = new InapplicableMethodException(diags); 132 } 133 134 /** error symbols, which are returned when resolution fails 135 */ 136 private final SymbolNotFoundError varNotFound; 137 private final InapplicableSymbolError wrongMethod; 138 private final InapplicableSymbolsError wrongMethods; 139 private final SymbolNotFoundError methodNotFound; 140 private final SymbolNotFoundError typeNotFound; 141 142 public static Resolve instance(Context context) { 143 Resolve instance = context.get(resolveKey); 144 if (instance == null) 145 instance = new Resolve(context); 146 return instance; 147 } 148 149 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support"> 150 enum VerboseResolutionMode { 151 SUCCESS("success"), 152 FAILURE("failure"), 153 APPLICABLE("applicable"), 154 INAPPLICABLE("inapplicable"), 155 DEFERRED_INST("deferred-inference"), 156 PREDEF("predef"), 157 OBJECT_INIT("object-init"), 158 INTERNAL("internal"); 159 160 String opt; 161 162 private VerboseResolutionMode(String opt) { 163 this.opt = opt; 164 } 165 166 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) { 167 String s = opts.get("verboseResolution"); 168 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class); 169 if (s == null) return res; 170 if (s.contains("all")) { 171 res = EnumSet.allOf(VerboseResolutionMode.class); 172 } 173 Collection<String> args = Arrays.asList(s.split(",")); 174 for (VerboseResolutionMode mode : values()) { 175 if (args.contains(mode.opt)) { 176 res.add(mode); 177 } else if (args.contains("-" + mode.opt)) { 178 res.remove(mode); 179 } 180 } 181 return res; 182 } 183 } 184 185 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, 186 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) { 187 boolean success = bestSoFar.kind < ERRONEOUS; 188 189 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { 190 return; 191 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { 192 return; 193 } 194 195 if (bestSoFar.name == names.init && 196 bestSoFar.owner == syms.objectType.tsym && 197 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { 198 return; //skip diags for Object constructor resolution 199 } else if (site == syms.predefClass.type && 200 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { 201 return; //skip spurious diags for predef symbols (i.e. operators) 202 } else if (currentResolutionContext.internalResolution && 203 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { 204 return; 205 } 206 207 int pos = 0; 208 int mostSpecificPos = -1; 209 ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb(); 210 for (Candidate c : currentResolutionContext.candidates) { 211 if (currentResolutionContext.step != c.step || 212 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || 213 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) { 214 continue; 215 } else { 216 subDiags.append(c.isApplicable() ? 217 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) : 218 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details)); 219 if (c.sym == bestSoFar) 220 mostSpecificPos = pos; 221 pos++; 222 } 223 } 224 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; 225 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, 226 site.tsym, mostSpecificPos, currentResolutionContext.step, 227 methodArguments(argtypes), methodArguments(typeargtypes)); 228 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); 229 log.report(d); 230 } 231 232 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) { 233 JCDiagnostic subDiag = null; 234 if (inst.getReturnType().tag == FORALL) { 235 Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(), 236 ((ForAll)inst.getReturnType()).qtype); 237 subDiag = diags.fragment("partial.inst.sig", diagType); 238 } else if (sym.type.tag == FORALL) { 239 subDiag = diags.fragment("full.inst.sig", inst.asMethodType()); 240 } 241 242 String key = subDiag == null ? 243 "applicable.method.found" : 244 "applicable.method.found.1"; 245 246 return diags.fragment(key, pos, sym, subDiag); 247 } 248 249 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) { 250 return diags.fragment("not.applicable.method.found", pos, sym, subDiag); 251 } 252 // </editor-fold> 253 254 /* ************************************************************************ 255 * Identifier resolution 256 *************************************************************************/ 257 258 /** An environment is "static" if its static level is greater than 259 * the one of its outer environment 260 */ 261 static boolean isStatic(Env<AttrContext> env) { 262 return env.info.staticLevel > env.outer.info.staticLevel; 263 } 264 265 /** An environment is an "initializer" if it is a constructor or 266 * an instance initializer. 267 */ 268 static boolean isInitializer(Env<AttrContext> env) { 269 Symbol owner = env.info.scope.owner; 270 return owner.isConstructor() || 271 owner.owner.kind == TYP && 272 (owner.kind == VAR || 273 owner.kind == MTH && (owner.flags() & BLOCK) != 0) && 274 (owner.flags() & STATIC) == 0; 275 } 276 277 /** Is class accessible in given evironment? 278 * @param env The current environment. 279 * @param c The class whose accessibility is checked. 280 */ 281 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) { 282 return isAccessible(env, c, false); 283 } 284 285 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) { 286 boolean isAccessible = false; 287 switch ((short)(c.flags() & AccessFlags)) { 288 case PRIVATE: 289 isAccessible = 290 env.enclClass.sym.outermostClass() == 291 c.owner.outermostClass(); 292 break; 293 case 0: 294 isAccessible = 295 env.toplevel.packge == c.owner // fast special case 296 || 297 env.toplevel.packge == c.packge() 298 || 299 // Hack: this case is added since synthesized default constructors 300 // of anonymous classes should be allowed to access 301 // classes which would be inaccessible otherwise. 302 env.enclMethod != null && 303 (env.enclMethod.mods.flags & ANONCONSTR) != 0; 304 break; 305 default: // error recovery 306 case PUBLIC: 307 isAccessible = true; 308 break; 309 case PROTECTED: 310 isAccessible = 311 env.toplevel.packge == c.owner // fast special case 312 || 313 env.toplevel.packge == c.packge() 314 || 315 isInnerSubClass(env.enclClass.sym, c.owner); 316 break; 317 } 318 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ? 319 isAccessible : 320 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner); 321 } 322 //where 323 /** Is given class a subclass of given base class, or an inner class 324 * of a subclass? 325 * Return null if no such class exists. 326 * @param c The class which is the subclass or is contained in it. 327 * @param base The base class 328 */ 329 private boolean isInnerSubClass(ClassSymbol c, Symbol base) { 330 while (c != null && !c.isSubClass(base, types)) { 331 c = c.owner.enclClass(); 332 } 333 return c != null; 334 } 335 336 boolean isAccessible(Env<AttrContext> env, Type t) { 337 return isAccessible(env, t, false); 338 } 339 340 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { 341 return (t.tag == ARRAY) 342 ? isAccessible(env, types.elemtype(t)) 343 : isAccessible(env, t.tsym, checkInner); 344 } 345 346 /** Is symbol accessible as a member of given type in given evironment? 347 * @param env The current environment. 348 * @param site The type of which the tested symbol is regarded 349 * as a member. 350 * @param sym The symbol. 351 */ 352 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) { 353 return isAccessible(env, site, sym, false); 354 } 355 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) { 356 if (sym.name == names.init && sym.owner != site.tsym) return false; 357 switch ((short)(sym.flags() & AccessFlags)) { 358 case PRIVATE: 359 return 360 (env.enclClass.sym == sym.owner // fast special case 361 || 362 env.enclClass.sym.outermostClass() == 363 sym.owner.outermostClass()) 364 && 365 sym.isInheritedIn(site.tsym, types); 366 case 0: 367 return 368 (env.toplevel.packge == sym.owner.owner // fast special case 369 || 370 env.toplevel.packge == sym.packge()) 371 && 372 isAccessible(env, site, checkInner) 373 && 374 sym.isInheritedIn(site.tsym, types) 375 && 376 notOverriddenIn(site, sym); 377 case PROTECTED: 378 return 379 (env.toplevel.packge == sym.owner.owner // fast special case 380 || 381 env.toplevel.packge == sym.packge() 382 || 383 isProtectedAccessible(sym, env.enclClass.sym, site) 384 || 385 // OK to select instance method or field from 'super' or type name 386 // (but type names should be disallowed elsewhere!) 387 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) 388 && 389 isAccessible(env, site, checkInner) 390 && 391 notOverriddenIn(site, sym); 392 default: // this case includes erroneous combinations as well 393 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym); 394 } 395 } 396 //where 397 /* `sym' is accessible only if not overridden by 398 * another symbol which is a member of `site' 399 * (because, if it is overridden, `sym' is not strictly 400 * speaking a member of `site'). A polymorphic signature method 401 * cannot be overridden (e.g. MH.invokeExact(Object[])). 402 */ 403 private boolean notOverriddenIn(Type site, Symbol sym) { 404 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) 405 return true; 406 else { 407 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 408 return (s2 == null || s2 == sym || sym.owner == s2.owner || 409 s2.isPolymorphicSignatureGeneric() || 410 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); 411 } 412 } 413 //where 414 /** Is given protected symbol accessible if it is selected from given site 415 * and the selection takes place in given class? 416 * @param sym The symbol with protected access 417 * @param c The class where the access takes place 418 * @site The type of the qualifier 419 */ 420 private 421 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { 422 while (c != null && 423 !(c.isSubClass(sym.owner, types) && 424 (c.flags() & INTERFACE) == 0 && 425 // In JLS 2e 6.6.2.1, the subclass restriction applies 426 // only to instance fields and methods -- types are excluded 427 // regardless of whether they are declared 'static' or not. 428 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) 429 c = c.owner.enclClass(); 430 return c != null; 431 } 432 433 /** Try to instantiate the type of a method so that it fits 434 * given type arguments and argument types. If succesful, return 435 * the method's instantiated type, else return null. 436 * The instantiation will take into account an additional leading 437 * formal parameter if the method is an instance method seen as a member 438 * of un underdetermined site In this case, we treat site as an additional 439 * parameter and the parameters of the class containing the method as 440 * additional type variables that get instantiated. 441 * 442 * @param env The current environment 443 * @param site The type of which the method is a member. 444 * @param m The method symbol. 445 * @param argtypes The invocation's given value arguments. 446 * @param typeargtypes The invocation's given type arguments. 447 * @param allowBoxing Allow boxing conversions of arguments. 448 * @param useVarargs Box trailing arguments into an array for varargs. 449 */ 450 Type rawInstantiate(Env<AttrContext> env, 451 Type site, 452 Symbol m, 453 List<Type> argtypes, 454 List<Type> typeargtypes, 455 boolean allowBoxing, 456 boolean useVarargs, 457 Warner warn) 458 throws Infer.InferenceException { 459 boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles; 460 if (useVarargs && (m.flags() & VARARGS) == 0) 461 throw inapplicableMethodException.setMessage(); 462 Type mt = types.memberType(site, m); 463 464 // tvars is the list of formal type variables for which type arguments 465 // need to inferred. 466 List<Type> tvars = null; 467 if (env.info.tvars != null) { 468 tvars = types.newInstances(env.info.tvars); 469 mt = types.subst(mt, env.info.tvars, tvars); 470 } 471 if (typeargtypes == null) typeargtypes = List.nil(); 472 if (mt.tag != FORALL && typeargtypes.nonEmpty()) { 473 // This is not a polymorphic method, but typeargs are supplied 474 // which is fine, see JLS 15.12.2.1 475 } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) { 476 ForAll pmt = (ForAll) mt; 477 if (typeargtypes.length() != pmt.tvars.length()) 478 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args 479 // Check type arguments are within bounds 480 List<Type> formals = pmt.tvars; 481 List<Type> actuals = typeargtypes; 482 while (formals.nonEmpty() && actuals.nonEmpty()) { 483 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head), 484 pmt.tvars, typeargtypes); 485 for (; bounds.nonEmpty(); bounds = bounds.tail) 486 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) 487 throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds); 488 formals = formals.tail; 489 actuals = actuals.tail; 490 } 491 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes); 492 } else if (mt.tag == FORALL) { 493 ForAll pmt = (ForAll) mt; 494 List<Type> tvars1 = types.newInstances(pmt.tvars); 495 tvars = tvars.appendList(tvars1); 496 mt = types.subst(pmt.qtype, pmt.tvars, tvars1); 497 } 498 499 // find out whether we need to go the slow route via infer 500 boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/ 501 polymorphicSignature; 502 for (List<Type> l = argtypes; 503 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded; 504 l = l.tail) { 505 if (l.head.tag == FORALL) instNeeded = true; 506 } 507 508 if (instNeeded) 509 return polymorphicSignature ? 510 infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) : 511 infer.instantiateMethod(env, 512 tvars, 513 (MethodType)mt, 514 m, 515 argtypes, 516 allowBoxing, 517 useVarargs, 518 warn); 519 520 checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(), 521 allowBoxing, useVarargs, warn); 522 return mt; 523 } 524 525 /** Same but returns null instead throwing a NoInstanceException 526 */ 527 Type instantiate(Env<AttrContext> env, 528 Type site, 529 Symbol m, 530 List<Type> argtypes, 531 List<Type> typeargtypes, 532 boolean allowBoxing, 533 boolean useVarargs, 534 Warner warn) { 535 try { 536 return rawInstantiate(env, site, m, argtypes, typeargtypes, 537 allowBoxing, useVarargs, warn); 538 } catch (InapplicableMethodException ex) { 539 return null; 540 } 541 } 542 543 /** Check if a parameter list accepts a list of args. 544 */ 545 boolean argumentsAcceptable(Env<AttrContext> env, 546 List<Type> argtypes, 547 List<Type> formals, 548 boolean allowBoxing, 549 boolean useVarargs, 550 Warner warn) { 551 try { 552 checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn); 553 return true; 554 } catch (InapplicableMethodException ex) { 555 return false; 556 } 557 } 558 /** 559 * A check handler is used by the main method applicability routine in order 560 * to handle specific method applicability failures. It is assumed that a class 561 * implementing this interface should throw exceptions that are a subtype of 562 * InapplicableMethodException (see below). Such exception will terminate the 563 * method applicability check and propagate important info outwards (for the 564 * purpose of generating better diagnostics). 565 */ 566 interface MethodCheckHandler { 567 /* The number of actuals and formals differ */ 568 InapplicableMethodException arityMismatch(); 569 /* An actual argument type does not conform to the corresponding formal type */ 570 InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected); 571 /* The element type of a varargs is not accessible in the current context */ 572 InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected); 573 } 574 575 /** 576 * Basic method check handler used within Resolve - all methods end up 577 * throwing InapplicableMethodException; a diagnostic fragment that describes 578 * the cause as to why the method is not applicable is set on the exception 579 * before it is thrown. 580 */ 581 MethodCheckHandler resolveHandler = new MethodCheckHandler() { 582 public InapplicableMethodException arityMismatch() { 583 return inapplicableMethodException.setMessage("arg.length.mismatch"); 584 } 585 public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) { 586 String key = varargs ? 587 "varargs.argument.mismatch" : 588 "no.conforming.assignment.exists"; 589 return inapplicableMethodException.setMessage(key, 590 found, expected); 591 } 592 public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) { 593 return inapplicableMethodException.setMessage("inaccessible.varargs.type", 594 expected, Kinds.kindName(location), location); 595 } 596 }; 597 598 void checkRawArgumentsAcceptable(Env<AttrContext> env, 599 List<Type> argtypes, 600 List<Type> formals, 601 boolean allowBoxing, 602 boolean useVarargs, 603 Warner warn) { 604 checkRawArgumentsAcceptable(env, List.<Type>nil(), argtypes, formals, 605 allowBoxing, useVarargs, warn, resolveHandler); 606 } 607 608 /** 609 * Main method applicability routine. Given a list of actual types A, 610 * a list of formal types F, determines whether the types in A are 611 * compatible (by method invocation conversion) with the types in F. 612 * 613 * Since this routine is shared between overload resolution and method 614 * type-inference, it is crucial that actual types are converted to the 615 * corresponding 'undet' form (i.e. where inference variables are replaced 616 * with undetvars) so that constraints can be propagated and collected. 617 * 618 * Moreover, if one or more types in A is a poly type, this routine calls 619 * Infer.instantiateArg in order to complete the poly type (this might involve 620 * deferred attribution). 621 * 622 * A method check handler (see above) is used in order to report errors. 623 */ 624 List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env, 625 List<Type> undetvars, 626 List<Type> argtypes, 627 List<Type> formals, 628 boolean allowBoxing, 629 boolean useVarargs, 630 Warner warn, 631 MethodCheckHandler handler) { 632 Type varargsFormal = useVarargs ? formals.last() : null; 633 ListBuffer<Type> checkedArgs = ListBuffer.lb(); 634 635 if (varargsFormal == null && 636 argtypes.size() != formals.size()) { 637 throw handler.arityMismatch(); // not enough args 638 } 639 640 while (argtypes.nonEmpty() && formals.head != varargsFormal) { 641 Type undetFormal = infer.asUndetType(formals.head, undetvars); 642 Type capturedActual = types.capture(argtypes.head); 643 boolean works = allowBoxing ? 644 types.isConvertible(capturedActual, undetFormal, warn) : 645 types.isSubtypeUnchecked(capturedActual, undetFormal, warn); 646 if (!works) { 647 throw handler.argumentMismatch(false, argtypes.head, formals.head); 648 } 649 checkedArgs.append(capturedActual); 650 argtypes = argtypes.tail; 651 formals = formals.tail; 652 } 653 654 if (formals.head != varargsFormal) { 655 throw handler.arityMismatch(); // not enough args 656 } 657 658 if (useVarargs) { 659 //note: if applicability check is triggered by most specific test, 660 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) 661 Type elt = types.elemtype(varargsFormal); 662 Type eltUndet = infer.asUndetType(elt, undetvars); 663 while (argtypes.nonEmpty()) { 664 Type capturedActual = types.capture(argtypes.head); 665 if (!types.isConvertible(capturedActual, eltUndet, warn)) { 666 throw handler.argumentMismatch(true, argtypes.head, elt); 667 } 668 checkedArgs.append(capturedActual); 669 argtypes = argtypes.tail; 670 } 671 //check varargs element type accessibility 672 if (undetvars.isEmpty() && !isAccessible(env, elt)) { 673 Symbol location = env.enclClass.sym; 674 throw handler.inaccessibleVarargs(location, elt); 675 } 676 } 677 return checkedArgs.toList(); 678 } 679 // where 680 public static class InapplicableMethodException extends RuntimeException { 681 private static final long serialVersionUID = 0; 682 683 JCDiagnostic diagnostic; 684 JCDiagnostic.Factory diags; 685 686 InapplicableMethodException(JCDiagnostic.Factory diags) { 687 this.diagnostic = null; 688 this.diags = diags; 689 } 690 InapplicableMethodException setMessage() { 691 this.diagnostic = null; 692 return this; 693 } 694 InapplicableMethodException setMessage(String key) { 695 this.diagnostic = key != null ? diags.fragment(key) : null; 696 return this; 697 } 698 InapplicableMethodException setMessage(String key, Object... args) { 699 this.diagnostic = key != null ? diags.fragment(key, args) : null; 700 return this; 701 } 702 InapplicableMethodException setMessage(JCDiagnostic diag) { 703 this.diagnostic = diag; 704 return this; 705 } 706 707 public JCDiagnostic getDiagnostic() { 708 return diagnostic; 709 } 710 } 711 private final InapplicableMethodException inapplicableMethodException; 712 713 /* *************************************************************************** 714 * Symbol lookup 715 * the following naming conventions for arguments are used 716 * 717 * env is the environment where the symbol was mentioned 718 * site is the type of which the symbol is a member 719 * name is the symbol's name 720 * if no arguments are given 721 * argtypes are the value arguments, if we search for a method 722 * 723 * If no symbol was found, a ResolveError detailing the problem is returned. 724 ****************************************************************************/ 725 726 /** Find field. Synthetic fields are always skipped. 727 * @param env The current environment. 728 * @param site The original type from where the selection takes place. 729 * @param name The name of the field. 730 * @param c The class to search for the field. This is always 731 * a superclass or implemented interface of site's class. 732 */ 733 Symbol findField(Env<AttrContext> env, 734 Type site, 735 Name name, 736 TypeSymbol c) { 737 while (c.type.tag == TYPEVAR) 738 c = c.type.getUpperBound().tsym; 739 Symbol bestSoFar = varNotFound; 740 Symbol sym; 741 Scope.Entry e = c.members().lookup(name); 742 while (e.scope != null) { 743 if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) { 744 return isAccessible(env, site, e.sym) 745 ? e.sym : new AccessError(env, site, e.sym); 746 } 747 e = e.next(); 748 } 749 Type st = types.supertype(c.type); 750 if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) { 751 sym = findField(env, site, name, st.tsym); 752 if (sym.kind < bestSoFar.kind) bestSoFar = sym; 753 } 754 for (List<Type> l = types.interfaces(c.type); 755 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 756 l = l.tail) { 757 sym = findField(env, site, name, l.head.tsym); 758 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 759 sym.owner != bestSoFar.owner) 760 bestSoFar = new AmbiguityError(bestSoFar, sym); 761 else if (sym.kind < bestSoFar.kind) 762 bestSoFar = sym; 763 } 764 return bestSoFar; 765 } 766 767 /** Resolve a field identifier, throw a fatal error if not found. 768 * @param pos The position to use for error reporting. 769 * @param env The environment current at the method invocation. 770 * @param site The type of the qualifying expression, in which 771 * identifier is searched. 772 * @param name The identifier's name. 773 */ 774 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env, 775 Type site, Name name) { 776 Symbol sym = findField(env, site, name, site.tsym); 777 if (sym.kind == VAR) return (VarSymbol)sym; 778 else throw new FatalError( 779 diags.fragment("fatal.err.cant.locate.field", 780 name)); 781 } 782 783 /** Find unqualified variable or field with given name. 784 * Synthetic fields always skipped. 785 * @param env The current environment. 786 * @param name The name of the variable or field. 787 */ 788 Symbol findVar(Env<AttrContext> env, Name name) { 789 Symbol bestSoFar = varNotFound; 790 Symbol sym; 791 Env<AttrContext> env1 = env; 792 boolean staticOnly = false; 793 while (env1.outer != null) { 794 if (isStatic(env1)) staticOnly = true; 795 Scope.Entry e = env1.info.scope.lookup(name); 796 while (e.scope != null && 797 (e.sym.kind != VAR || 798 (e.sym.flags_field & SYNTHETIC) != 0)) 799 e = e.next(); 800 sym = (e.scope != null) 801 ? e.sym 802 : findField( 803 env1, env1.enclClass.sym.type, name, env1.enclClass.sym); 804 if (sym.exists()) { 805 if (staticOnly && 806 sym.kind == VAR && 807 sym.owner.kind == TYP && 808 (sym.flags() & STATIC) == 0) 809 return new StaticError(sym); 810 else 811 return sym; 812 } else if (sym.kind < bestSoFar.kind) { 813 bestSoFar = sym; 814 } 815 816 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 817 env1 = env1.outer; 818 } 819 820 sym = findField(env, syms.predefClass.type, name, syms.predefClass); 821 if (sym.exists()) 822 return sym; 823 if (bestSoFar.exists()) 824 return bestSoFar; 825 826 Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 827 for (; e.scope != null; e = e.next()) { 828 sym = e.sym; 829 Type origin = e.getOrigin().owner.type; 830 if (sym.kind == VAR) { 831 if (e.sym.owner.type != origin) 832 sym = sym.clone(e.getOrigin().owner); 833 return isAccessible(env, origin, sym) 834 ? sym : new AccessError(env, origin, sym); 835 } 836 } 837 838 Symbol origin = null; 839 e = env.toplevel.starImportScope.lookup(name); 840 for (; e.scope != null; e = e.next()) { 841 sym = e.sym; 842 if (sym.kind != VAR) 843 continue; 844 // invariant: sym.kind == VAR 845 if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner) 846 return new AmbiguityError(bestSoFar, sym); 847 else if (bestSoFar.kind >= VAR) { 848 origin = e.getOrigin().owner; 849 bestSoFar = isAccessible(env, origin.type, sym) 850 ? sym : new AccessError(env, origin.type, sym); 851 } 852 } 853 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type) 854 return bestSoFar.clone(origin); 855 else 856 return bestSoFar; 857 } 858 859 Warner noteWarner = new Warner(); 860 861 /** Select the best method for a call site among two choices. 862 * @param env The current environment. 863 * @param site The original type from where the 864 * selection takes place. 865 * @param argtypes The invocation's value arguments, 866 * @param typeargtypes The invocation's type arguments, 867 * @param sym Proposed new best match. 868 * @param bestSoFar Previously found best match. 869 * @param allowBoxing Allow boxing conversions of arguments. 870 * @param useVarargs Box trailing arguments into an array for varargs. 871 */ 872 @SuppressWarnings("fallthrough") 873 Symbol selectBest(Env<AttrContext> env, 874 Type site, 875 List<Type> argtypes, 876 List<Type> typeargtypes, 877 Symbol sym, 878 Symbol bestSoFar, 879 boolean allowBoxing, 880 boolean useVarargs, 881 boolean operator) { 882 if (sym.kind == ERR) return bestSoFar; 883 if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; 884 Assert.check(sym.kind < AMBIGUOUS); 885 try { 886 Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes, 887 allowBoxing, useVarargs, Warner.noWarnings); 888 if (!operator) 889 currentResolutionContext.addApplicableCandidate(sym, mt); 890 } catch (InapplicableMethodException ex) { 891 if (!operator) 892 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); 893 switch (bestSoFar.kind) { 894 case ABSENT_MTH: 895 return wrongMethod; 896 case WRONG_MTH: 897 if (operator) return bestSoFar; 898 case WRONG_MTHS: 899 return wrongMethods; 900 default: 901 return bestSoFar; 902 } 903 } 904 if (!isAccessible(env, site, sym)) { 905 return (bestSoFar.kind == ABSENT_MTH) 906 ? new AccessError(env, site, sym) 907 : bestSoFar; 908 } 909 return (bestSoFar.kind > AMBIGUOUS) 910 ? sym 911 : mostSpecific(sym, bestSoFar, env, site, 912 allowBoxing && operator, useVarargs); 913 } 914 915 /* Return the most specific of the two methods for a call, 916 * given that both are accessible and applicable. 917 * @param m1 A new candidate for most specific. 918 * @param m2 The previous most specific candidate. 919 * @param env The current environment. 920 * @param site The original type from where the selection 921 * takes place. 922 * @param allowBoxing Allow boxing conversions of arguments. 923 * @param useVarargs Box trailing arguments into an array for varargs. 924 */ 925 Symbol mostSpecific(Symbol m1, 926 Symbol m2, 927 Env<AttrContext> env, 928 final Type site, 929 boolean allowBoxing, 930 boolean useVarargs) { 931 switch (m2.kind) { 932 case MTH: 933 if (m1 == m2) return m1; 934 boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs); 935 boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs); 936 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 937 Type mt1 = types.memberType(site, m1); 938 Type mt2 = types.memberType(site, m2); 939 if (!types.overrideEquivalent(mt1, mt2)) 940 return ambiguityError(m1, m2); 941 942 // same signature; select (a) the non-bridge method, or 943 // (b) the one that overrides the other, or (c) the concrete 944 // one, or (d) merge both abstract signatures 945 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) 946 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 947 948 // if one overrides or hides the other, use it 949 TypeSymbol m1Owner = (TypeSymbol)m1.owner; 950 TypeSymbol m2Owner = (TypeSymbol)m2.owner; 951 if (types.asSuper(m1Owner.type, m2Owner) != null && 952 ((m1.owner.flags_field & INTERFACE) == 0 || 953 (m2.owner.flags_field & INTERFACE) != 0) && 954 m1.overrides(m2, m1Owner, types, false)) 955 return m1; 956 if (types.asSuper(m2Owner.type, m1Owner) != null && 957 ((m2.owner.flags_field & INTERFACE) == 0 || 958 (m1.owner.flags_field & INTERFACE) != 0) && 959 m2.overrides(m1, m2Owner, types, false)) 960 return m2; 961 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; 962 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; 963 if (m1Abstract && !m2Abstract) return m2; 964 if (m2Abstract && !m1Abstract) return m1; 965 // both abstract or both concrete 966 if (!m1Abstract && !m2Abstract) 967 return ambiguityError(m1, m2); 968 // check that both signatures have the same erasure 969 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), 970 m2.erasure(types).getParameterTypes())) 971 return ambiguityError(m1, m2); 972 // both abstract, neither overridden; merge throws clause and result type 973 Type mst = mostSpecificReturnType(mt1, mt2); 974 if (mst == null) { 975 // Theoretically, this can't happen, but it is possible 976 // due to error recovery or mixing incompatible class files 977 return ambiguityError(m1, m2); 978 } 979 Symbol mostSpecific = mst == mt1 ? m1 : m2; 980 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); 981 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); 982 MethodSymbol result = new MethodSymbol( 983 mostSpecific.flags(), 984 mostSpecific.name, 985 newSig, 986 mostSpecific.owner) { 987 @Override 988 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 989 if (origin == site.tsym) 990 return this; 991 else 992 return super.implementation(origin, types, checkResult); 993 } 994 }; 995 return result; 996 } 997 if (m1SignatureMoreSpecific) return m1; 998 if (m2SignatureMoreSpecific) return m2; 999 return ambiguityError(m1, m2); 1000 case AMBIGUOUS: 1001 AmbiguityError e = (AmbiguityError)m2; 1002 Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs); 1003 Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs); 1004 if (err1 == err2) return err1; 1005 if (err1 == e.sym && err2 == e.sym2) return m2; 1006 if (err1 instanceof AmbiguityError && 1007 err2 instanceof AmbiguityError && 1008 ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym) 1009 return ambiguityError(m1, m2); 1010 else 1011 return ambiguityError(err1, err2); 1012 default: 1013 throw new AssertionError(); 1014 } 1015 } 1016 //where 1017 private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) { 1018 noteWarner.clear(); 1019 Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs)); 1020 Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs), 1021 types.lowerBoundArgtypes(mtype1), null, 1022 allowBoxing, false, noteWarner); 1023 return mtype2 != null && 1024 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); 1025 } 1026 //where 1027 private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) { 1028 List<Type> fromArgs = from.type.getParameterTypes(); 1029 List<Type> toArgs = to.type.getParameterTypes(); 1030 if (useVarargs && 1031 (from.flags() & VARARGS) != 0 && 1032 (to.flags() & VARARGS) != 0) { 1033 Type varargsTypeFrom = fromArgs.last(); 1034 Type varargsTypeTo = toArgs.last(); 1035 ListBuffer<Type> args = ListBuffer.lb(); 1036 if (toArgs.length() < fromArgs.length()) { 1037 //if we are checking a varargs method 'from' against another varargs 1038 //method 'to' (where arity of 'to' < arity of 'from') then expand signature 1039 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to' 1040 //until 'to' signature has the same arity as 'from') 1041 while (fromArgs.head != varargsTypeFrom) { 1042 args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head); 1043 fromArgs = fromArgs.tail; 1044 toArgs = toArgs.head == varargsTypeTo ? 1045 toArgs : 1046 toArgs.tail; 1047 } 1048 } else { 1049 //formal argument list is same as original list where last 1050 //argument (array type) is removed 1051 args.appendList(toArgs.reverse().tail.reverse()); 1052 } 1053 //append varargs element type as last synthetic formal 1054 args.append(types.elemtype(varargsTypeTo)); 1055 Type mtype = types.createMethodTypeWithParameters(to.type, args.toList()); 1056 return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner); 1057 } else { 1058 return to; 1059 } 1060 } 1061 //where 1062 Type mostSpecificReturnType(Type mt1, Type mt2) { 1063 Type rt1 = mt1.getReturnType(); 1064 Type rt2 = mt2.getReturnType(); 1065 1066 if (mt1.tag == FORALL && mt2.tag == FORALL) { 1067 //if both are generic methods, adjust return type ahead of subtyping check 1068 rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments()); 1069 } 1070 //first use subtyping, then return type substitutability 1071 if (types.isSubtype(rt1, rt2)) { 1072 return mt1; 1073 } else if (types.isSubtype(rt2, rt1)) { 1074 return mt2; 1075 } else if (types.returnTypeSubstitutable(mt1, mt2)) { 1076 return mt1; 1077 } else if (types.returnTypeSubstitutable(mt2, mt1)) { 1078 return mt2; 1079 } else { 1080 return null; 1081 } 1082 } 1083 //where 1084 Symbol ambiguityError(Symbol m1, Symbol m2) { 1085 if (((m1.flags() | m2.flags()) & CLASH) != 0) { 1086 return (m1.flags() & CLASH) == 0 ? m1 : m2; 1087 } else { 1088 return new AmbiguityError(m1, m2); 1089 } 1090 } 1091 1092 /** Find best qualified method matching given name, type and value 1093 * arguments. 1094 * @param env The current environment. 1095 * @param site The original type from where the selection 1096 * takes place. 1097 * @param name The method's name. 1098 * @param argtypes The method's value arguments. 1099 * @param typeargtypes The method's type arguments 1100 * @param allowBoxing Allow boxing conversions of arguments. 1101 * @param useVarargs Box trailing arguments into an array for varargs. 1102 */ 1103 Symbol findMethod(Env<AttrContext> env, 1104 Type site, 1105 Name name, 1106 List<Type> argtypes, 1107 List<Type> typeargtypes, 1108 boolean allowBoxing, 1109 boolean useVarargs, 1110 boolean operator) { 1111 Symbol bestSoFar = methodNotFound; 1112 bestSoFar = findMethod(env, 1113 site, 1114 name, 1115 argtypes, 1116 typeargtypes, 1117 site.tsym.type, 1118 true, 1119 bestSoFar, 1120 allowBoxing, 1121 useVarargs, 1122 operator, 1123 new HashSet<TypeSymbol>()); 1124 reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar); 1125 return bestSoFar; 1126 } 1127 // where 1128 private Symbol findMethod(Env<AttrContext> env, 1129 Type site, 1130 Name name, 1131 List<Type> argtypes, 1132 List<Type> typeargtypes, 1133 Type intype, 1134 boolean abstractok, 1135 Symbol bestSoFar, 1136 boolean allowBoxing, 1137 boolean useVarargs, 1138 boolean operator, 1139 Set<TypeSymbol> seen) { 1140 for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) { 1141 while (ct.tag == TYPEVAR) 1142 ct = ct.getUpperBound(); 1143 ClassSymbol c = (ClassSymbol)ct.tsym; 1144 if (!seen.add(c)) return bestSoFar; 1145 if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0) 1146 abstractok = false; 1147 for (Scope.Entry e = c.members().lookup(name); 1148 e.scope != null; 1149 e = e.next()) { 1150 //- System.out.println(" e " + e.sym); 1151 if (e.sym.kind == MTH && 1152 (e.sym.flags_field & SYNTHETIC) == 0) { 1153 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 1154 e.sym, bestSoFar, 1155 allowBoxing, 1156 useVarargs, 1157 operator); 1158 } 1159 } 1160 if (name == names.init) 1161 break; 1162 //- System.out.println(" - " + bestSoFar); 1163 if (abstractok) { 1164 Symbol concrete = methodNotFound; 1165 if ((bestSoFar.flags() & ABSTRACT) == 0) 1166 concrete = bestSoFar; 1167 for (List<Type> l = types.interfaces(c.type); 1168 l.nonEmpty(); 1169 l = l.tail) { 1170 bestSoFar = findMethod(env, site, name, argtypes, 1171 typeargtypes, 1172 l.head, abstractok, bestSoFar, 1173 allowBoxing, useVarargs, operator, seen); 1174 } 1175 if (concrete != bestSoFar && 1176 concrete.kind < ERR && bestSoFar.kind < ERR && 1177 types.isSubSignature(concrete.type, bestSoFar.type)) 1178 bestSoFar = concrete; 1179 } 1180 } 1181 return bestSoFar; 1182 } 1183 1184 /** Find unqualified method matching given name, type and value arguments. 1185 * @param env The current environment. 1186 * @param name The method's name. 1187 * @param argtypes The method's value arguments. 1188 * @param typeargtypes The method's type arguments. 1189 * @param allowBoxing Allow boxing conversions of arguments. 1190 * @param useVarargs Box trailing arguments into an array for varargs. 1191 */ 1192 Symbol findFun(Env<AttrContext> env, Name name, 1193 List<Type> argtypes, List<Type> typeargtypes, 1194 boolean allowBoxing, boolean useVarargs) { 1195 Symbol bestSoFar = methodNotFound; 1196 Symbol sym; 1197 Env<AttrContext> env1 = env; 1198 boolean staticOnly = false; 1199 while (env1.outer != null) { 1200 if (isStatic(env1)) staticOnly = true; 1201 sym = findMethod( 1202 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 1203 allowBoxing, useVarargs, false); 1204 if (sym.exists()) { 1205 if (staticOnly && 1206 sym.kind == MTH && 1207 sym.owner.kind == TYP && 1208 (sym.flags() & STATIC) == 0) return new StaticError(sym); 1209 else return sym; 1210 } else if (sym.kind < bestSoFar.kind) { 1211 bestSoFar = sym; 1212 } 1213 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1214 env1 = env1.outer; 1215 } 1216 1217 sym = findMethod(env, syms.predefClass.type, name, argtypes, 1218 typeargtypes, allowBoxing, useVarargs, false); 1219 if (sym.exists()) 1220 return sym; 1221 1222 Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 1223 for (; e.scope != null; e = e.next()) { 1224 sym = e.sym; 1225 Type origin = e.getOrigin().owner.type; 1226 if (sym.kind == MTH) { 1227 if (e.sym.owner.type != origin) 1228 sym = sym.clone(e.getOrigin().owner); 1229 if (!isAccessible(env, origin, sym)) 1230 sym = new AccessError(env, origin, sym); 1231 bestSoFar = selectBest(env, origin, 1232 argtypes, typeargtypes, 1233 sym, bestSoFar, 1234 allowBoxing, useVarargs, false); 1235 } 1236 } 1237 if (bestSoFar.exists()) 1238 return bestSoFar; 1239 1240 e = env.toplevel.starImportScope.lookup(name); 1241 for (; e.scope != null; e = e.next()) { 1242 sym = e.sym; 1243 Type origin = e.getOrigin().owner.type; 1244 if (sym.kind == MTH) { 1245 if (e.sym.owner.type != origin) 1246 sym = sym.clone(e.getOrigin().owner); 1247 if (!isAccessible(env, origin, sym)) 1248 sym = new AccessError(env, origin, sym); 1249 bestSoFar = selectBest(env, origin, 1250 argtypes, typeargtypes, 1251 sym, bestSoFar, 1252 allowBoxing, useVarargs, false); 1253 } 1254 } 1255 return bestSoFar; 1256 } 1257 1258 /** Load toplevel or member class with given fully qualified name and 1259 * verify that it is accessible. 1260 * @param env The current environment. 1261 * @param name The fully qualified name of the class to be loaded. 1262 */ 1263 Symbol loadClass(Env<AttrContext> env, Name name) { 1264 try { 1265 ClassSymbol c = reader.loadClass(name); 1266 checkForHiddenAccess(env, c); 1267 return isAccessible(env, c) ? c : new AccessError(c); 1268 } catch (ClassReader.BadClassFile err) { 1269 throw err; 1270 } catch (CompletionFailure ex) { 1271 return typeNotFound; 1272 } 1273 } 1274 1275 /** Check that a hidden class is not accessed from any other file than its own. 1276 */ 1277 void checkForHiddenAccess(Env<AttrContext> env, ClassSymbol c) { 1278 // If we are warning about hidden classes, verify that the class is package private (0) 1279 // and that the code that refers to the class belongs to the same package, this is necessary 1280 // because this warning should not trigger on normal access errors. Those are handled by isAccessible. 1281 // 1282 // If the class name is hidden (ie stored in a source file with a different name than the class and 1283 // it is not an inner class) and the code that refers to the hidden class resides in a different source 1284 // file, then warn! 1285 1286 if (lint.isEnabled(Lint.LintCategory.HIDDENCLASS) && 1287 (short)(c.flags() & AccessFlags) == 0 && 1288 env.toplevel.packge == c.packge() && 1289 c.owner instanceof PackageSymbol && 1290 !c.sourcefile.isNameCompatible(c.getSimpleName().toString(), JavaFileObject.Kind.SOURCE) && 1291 !fm.isSameFile(c.sourcefile, env.toplevel.sourcefile)) 1292 { 1293 log.warning("hidden.class.accessed.from.outside.of.its.source.file", 1294 c, c.sourcefile, env.toplevel.sourcefile); 1295 } 1296 } 1297 1298 /** Find qualified member type. 1299 * @param env The current environment. 1300 * @param site The original type from where the selection takes 1301 * place. 1302 * @param name The type's name. 1303 * @param c The class to search for the member type. This is 1304 * always a superclass or implemented interface of 1305 * site's class. 1306 */ 1307 Symbol findMemberType(Env<AttrContext> env, 1308 Type site, 1309 Name name, 1310 TypeSymbol c) { 1311 Symbol bestSoFar = typeNotFound; 1312 Symbol sym; 1313 Scope.Entry e = c.members().lookup(name); 1314 while (e.scope != null) { 1315 if (e.sym.kind == TYP) { 1316 return isAccessible(env, site, e.sym) 1317 ? e.sym 1318 : new AccessError(env, site, e.sym); 1319 } 1320 e = e.next(); 1321 } 1322 Type st = types.supertype(c.type); 1323 if (st != null && st.tag == CLASS) { 1324 sym = findMemberType(env, site, name, st.tsym); 1325 if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1326 } 1327 for (List<Type> l = types.interfaces(c.type); 1328 bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1329 l = l.tail) { 1330 sym = findMemberType(env, site, name, l.head.tsym); 1331 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 1332 sym.owner != bestSoFar.owner) 1333 bestSoFar = new AmbiguityError(bestSoFar, sym); 1334 else if (sym.kind < bestSoFar.kind) 1335 bestSoFar = sym; 1336 } 1337 return bestSoFar; 1338 } 1339 1340 /** Find a global type in given scope and load corresponding class. 1341 * @param env The current environment. 1342 * @param scope The scope in which to look for the type. 1343 * @param name The type's name. 1344 */ 1345 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) { 1346 Symbol bestSoFar = typeNotFound; 1347 for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) { 1348 Symbol sym = loadClass(env, e.sym.flatName()); 1349 if (bestSoFar.kind == TYP && sym.kind == TYP && 1350 bestSoFar != sym) 1351 return new AmbiguityError(bestSoFar, sym); 1352 else if (sym.kind < bestSoFar.kind) 1353 bestSoFar = sym; 1354 } 1355 return bestSoFar; 1356 } 1357 1358 /** Find an unqualified type symbol. 1359 * @param env The current environment. 1360 * @param name The type's name. 1361 */ 1362 Symbol findType(Env<AttrContext> env, Name name) { 1363 Symbol bestSoFar = typeNotFound; 1364 Symbol sym; 1365 boolean staticOnly = false; 1366 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) { 1367 if (isStatic(env1)) staticOnly = true; 1368 for (Scope.Entry e = env1.info.scope.lookup(name); 1369 e.scope != null; 1370 e = e.next()) { 1371 if (e.sym.kind == TYP) { 1372 if (staticOnly && 1373 e.sym.type.tag == TYPEVAR && 1374 e.sym.owner.kind == TYP) return new StaticError(e.sym); 1375 return e.sym; 1376 } 1377 } 1378 1379 sym = findMemberType(env1, env1.enclClass.sym.type, name, 1380 env1.enclClass.sym); 1381 if (staticOnly && sym.kind == TYP && 1382 sym.type.tag == CLASS && 1383 sym.type.getEnclosingType().tag == CLASS && 1384 env1.enclClass.sym.type.isParameterized() && 1385 sym.type.getEnclosingType().isParameterized()) 1386 return new StaticError(sym); 1387 else if (sym.exists()) return sym; 1388 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1389 1390 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass; 1391 if ((encl.sym.flags() & STATIC) != 0) 1392 staticOnly = true; 1393 } 1394 1395 if (!env.tree.hasTag(IMPORT)) { 1396 sym = findGlobalType(env, env.toplevel.namedImportScope, name); 1397 if (sym.exists()) return sym; 1398 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1399 1400 sym = findGlobalType(env, env.toplevel.packge.members(), name); 1401 if (sym.exists()) return sym; 1402 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1403 1404 sym = findGlobalType(env, env.toplevel.starImportScope, name); 1405 if (sym.exists()) return sym; 1406 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1407 } 1408 1409 return bestSoFar; 1410 } 1411 1412 /** Find an unqualified identifier which matches a specified kind set. 1413 * @param env The current environment. 1414 * @param name The indentifier's name. 1415 * @param kind Indicates the possible symbol kinds 1416 * (a subset of VAL, TYP, PCK). 1417 */ 1418 Symbol findIdent(Env<AttrContext> env, Name name, int kind) { 1419 Symbol bestSoFar = typeNotFound; 1420 Symbol sym; 1421 1422 if ((kind & VAR) != 0) { 1423 sym = findVar(env, name); 1424 if (sym.exists()) return sym; 1425 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1426 } 1427 1428 if ((kind & TYP) != 0) { 1429 sym = findType(env, name); 1430 if (sym.exists()) return sym; 1431 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1432 } 1433 1434 if ((kind & PCK) != 0) return reader.enterPackage(name); 1435 else return bestSoFar; 1436 } 1437 1438 /** Find an identifier in a package which matches a specified kind set. 1439 * @param env The current environment. 1440 * @param name The identifier's name. 1441 * @param kind Indicates the possible symbol kinds 1442 * (a nonempty subset of TYP, PCK). 1443 */ 1444 Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck, 1445 Name name, int kind) { 1446 Name fullname = TypeSymbol.formFullName(name, pck); 1447 Symbol bestSoFar = typeNotFound; 1448 PackageSymbol pack = null; 1449 if ((kind & PCK) != 0) { 1450 pack = reader.enterPackage(fullname); 1451 if (pack.exists()) return pack; 1452 } 1453 if ((kind & TYP) != 0) { 1454 Symbol sym = loadClass(env, fullname); 1455 if (sym.exists()) { 1456 // don't allow programs to use flatnames 1457 if (name == sym.name) return sym; 1458 } 1459 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1460 } 1461 return (pack != null) ? pack : bestSoFar; 1462 } 1463 1464 /** Find an identifier among the members of a given type `site'. 1465 * @param env The current environment. 1466 * @param site The type containing the symbol to be found. 1467 * @param name The identifier's name. 1468 * @param kind Indicates the possible symbol kinds 1469 * (a subset of VAL, TYP). 1470 */ 1471 Symbol findIdentInType(Env<AttrContext> env, Type site, 1472 Name name, int kind) { 1473 Symbol bestSoFar = typeNotFound; 1474 Symbol sym; 1475 if ((kind & VAR) != 0) { 1476 sym = findField(env, site, name, site.tsym); 1477 if (sym.exists()) return sym; 1478 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1479 } 1480 1481 if ((kind & TYP) != 0) { 1482 sym = findMemberType(env, site, name, site.tsym); 1483 if (sym.exists()) return sym; 1484 else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1485 } 1486 return bestSoFar; 1487 } 1488 1489 /* *************************************************************************** 1490 * Access checking 1491 * The following methods convert ResolveErrors to ErrorSymbols, issuing 1492 * an error message in the process 1493 ****************************************************************************/ 1494 1495 /** If `sym' is a bad symbol: report error and return errSymbol 1496 * else pass through unchanged, 1497 * additional arguments duplicate what has been used in trying to find the 1498 * symbol (--> flyweight pattern). This improves performance since we 1499 * expect misses to happen frequently. 1500 * 1501 * @param sym The symbol that was found, or a ResolveError. 1502 * @param pos The position to use for error reporting. 1503 * @param site The original type from where the selection took place. 1504 * @param name The symbol's name. 1505 * @param argtypes The invocation's value arguments, 1506 * if we looked for a method. 1507 * @param typeargtypes The invocation's type arguments, 1508 * if we looked for a method. 1509 */ 1510 Symbol access(Symbol sym, 1511 DiagnosticPosition pos, 1512 Symbol location, 1513 Type site, 1514 Name name, 1515 boolean qualified, 1516 List<Type> argtypes, 1517 List<Type> typeargtypes) { 1518 if (sym.kind >= AMBIGUOUS) { 1519 ResolveError errSym = (ResolveError)sym; 1520 if (!site.isErroneous() && 1521 !Type.isErroneous(argtypes) && 1522 (typeargtypes==null || !Type.isErroneous(typeargtypes))) 1523 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes); 1524 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol); 1525 } 1526 return sym; 1527 } 1528 1529 /** Same as original access(), but without location. 1530 */ 1531 Symbol access(Symbol sym, 1532 DiagnosticPosition pos, 1533 Type site, 1534 Name name, 1535 boolean qualified, 1536 List<Type> argtypes, 1537 List<Type> typeargtypes) { 1538 return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes); 1539 } 1540 1541 /** Same as original access(), but without type arguments and arguments. 1542 */ 1543 Symbol access(Symbol sym, 1544 DiagnosticPosition pos, 1545 Symbol location, 1546 Type site, 1547 Name name, 1548 boolean qualified) { 1549 if (sym.kind >= AMBIGUOUS) 1550 return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null); 1551 else 1552 return sym; 1553 } 1554 1555 /** Same as original access(), but without location, type arguments and arguments. 1556 */ 1557 Symbol access(Symbol sym, 1558 DiagnosticPosition pos, 1559 Type site, 1560 Name name, 1561 boolean qualified) { 1562 return access(sym, pos, site.tsym, site, name, qualified); 1563 } 1564 1565 /** Check that sym is not an abstract method. 1566 */ 1567 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { 1568 if ((sym.flags() & ABSTRACT) != 0) 1569 log.error(pos, "abstract.cant.be.accessed.directly", 1570 kindName(sym), sym, sym.location()); 1571 } 1572 1573 /* *************************************************************************** 1574 * Debugging 1575 ****************************************************************************/ 1576 1577 /** print all scopes starting with scope s and proceeding outwards. 1578 * used for debugging. 1579 */ 1580 public void printscopes(Scope s) { 1581 while (s != null) { 1582 if (s.owner != null) 1583 System.err.print(s.owner + ": "); 1584 for (Scope.Entry e = s.elems; e != null; e = e.sibling) { 1585 if ((e.sym.flags() & ABSTRACT) != 0) 1586 System.err.print("abstract "); 1587 System.err.print(e.sym + " "); 1588 } 1589 System.err.println(); 1590 s = s.next; 1591 } 1592 } 1593 1594 void printscopes(Env<AttrContext> env) { 1595 while (env.outer != null) { 1596 System.err.println("------------------------------"); 1597 printscopes(env.info.scope); 1598 env = env.outer; 1599 } 1600 } 1601 1602 public void printscopes(Type t) { 1603 while (t.tag == CLASS) { 1604 printscopes(t.tsym.members()); 1605 t = types.supertype(t); 1606 } 1607 } 1608 1609 /* *************************************************************************** 1610 * Name resolution 1611 * Naming conventions are as for symbol lookup 1612 * Unlike the find... methods these methods will report access errors 1613 ****************************************************************************/ 1614 1615 /** Resolve an unqualified (non-method) identifier. 1616 * @param pos The position to use for error reporting. 1617 * @param env The environment current at the identifier use. 1618 * @param name The identifier's name. 1619 * @param kind The set of admissible symbol kinds for the identifier. 1620 */ 1621 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env, 1622 Name name, int kind) { 1623 return access( 1624 findIdent(env, name, kind), 1625 pos, env.enclClass.sym.type, name, false); 1626 } 1627 1628 /** Resolve an unqualified method identifier. 1629 * @param pos The position to use for error reporting. 1630 * @param env The environment current at the method invocation. 1631 * @param name The identifier's name. 1632 * @param argtypes The types of the invocation's value arguments. 1633 * @param typeargtypes The types of the invocation's type arguments. 1634 */ 1635 Symbol resolveMethod(DiagnosticPosition pos, 1636 Env<AttrContext> env, 1637 Name name, 1638 List<Type> argtypes, 1639 List<Type> typeargtypes) { 1640 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1641 try { 1642 currentResolutionContext = new MethodResolutionContext(); 1643 Symbol sym = methodNotFound; 1644 List<MethodResolutionPhase> steps = methodResolutionSteps; 1645 while (steps.nonEmpty() && 1646 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1647 sym.kind >= ERRONEOUS) { 1648 currentResolutionContext.step = steps.head; 1649 sym = findFun(env, name, argtypes, typeargtypes, 1650 steps.head.isBoxingRequired, 1651 env.info.varArgs = steps.head.isVarargsRequired); 1652 currentResolutionContext.resolutionCache.put(steps.head, sym); 1653 steps = steps.tail; 1654 } 1655 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 1656 MethodResolutionPhase errPhase = 1657 currentResolutionContext.firstErroneousResolutionPhase(); 1658 sym = access(currentResolutionContext.resolutionCache.get(errPhase), 1659 pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); 1660 env.info.varArgs = errPhase.isVarargsRequired; 1661 } 1662 return sym; 1663 } 1664 finally { 1665 currentResolutionContext = prevResolutionContext; 1666 } 1667 } 1668 1669 /** Resolve a qualified method identifier 1670 * @param pos The position to use for error reporting. 1671 * @param env The environment current at the method invocation. 1672 * @param site The type of the qualifying expression, in which 1673 * identifier is searched. 1674 * @param name The identifier's name. 1675 * @param argtypes The types of the invocation's value arguments. 1676 * @param typeargtypes The types of the invocation's type arguments. 1677 */ 1678 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 1679 Type site, Name name, List<Type> argtypes, 1680 List<Type> typeargtypes) { 1681 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes); 1682 } 1683 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 1684 Symbol location, Type site, Name name, List<Type> argtypes, 1685 List<Type> typeargtypes) { 1686 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes); 1687 } 1688 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext, 1689 DiagnosticPosition pos, Env<AttrContext> env, 1690 Symbol location, Type site, Name name, List<Type> argtypes, 1691 List<Type> typeargtypes) { 1692 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1693 try { 1694 currentResolutionContext = resolveContext; 1695 Symbol sym = methodNotFound; 1696 List<MethodResolutionPhase> steps = methodResolutionSteps; 1697 while (steps.nonEmpty() && 1698 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1699 sym.kind >= ERRONEOUS) { 1700 currentResolutionContext.step = steps.head; 1701 sym = findMethod(env, site, name, argtypes, typeargtypes, 1702 steps.head.isBoxingRequired(), 1703 env.info.varArgs = steps.head.isVarargsRequired(), false); 1704 currentResolutionContext.resolutionCache.put(steps.head, sym); 1705 steps = steps.tail; 1706 } 1707 if (sym.kind >= AMBIGUOUS) { 1708 if (site.tsym.isPolymorphicSignatureGeneric()) { 1709 //polymorphic receiver - synthesize new method symbol 1710 env.info.varArgs = false; 1711 sym = findPolymorphicSignatureInstance(env, 1712 site, name, null, argtypes); 1713 } 1714 else { 1715 //if nothing is found return the 'first' error 1716 MethodResolutionPhase errPhase = 1717 currentResolutionContext.firstErroneousResolutionPhase(); 1718 sym = access(currentResolutionContext.resolutionCache.get(errPhase), 1719 pos, location, site, name, true, argtypes, typeargtypes); 1720 env.info.varArgs = errPhase.isVarargsRequired; 1721 } 1722 } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) { 1723 //non-instantiated polymorphic signature - synthesize new method symbol 1724 env.info.varArgs = false; 1725 sym = findPolymorphicSignatureInstance(env, 1726 site, name, (MethodSymbol)sym, argtypes); 1727 } 1728 return sym; 1729 } 1730 finally { 1731 currentResolutionContext = prevResolutionContext; 1732 } 1733 } 1734 1735 /** Find or create an implicit method of exactly the given type (after erasure). 1736 * Searches in a side table, not the main scope of the site. 1737 * This emulates the lookup process required by JSR 292 in JVM. 1738 * @param env Attribution environment 1739 * @param site The original type from where the selection takes place. 1740 * @param name The method's name. 1741 * @param spMethod A template for the implicit method, or null. 1742 * @param argtypes The required argument types. 1743 * @param typeargtypes The required type arguments. 1744 */ 1745 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site, 1746 Name name, 1747 MethodSymbol spMethod, // sig. poly. method or null if none 1748 List<Type> argtypes) { 1749 Type mtype = infer.instantiatePolymorphicSignatureInstance(env, 1750 site, name, spMethod, argtypes); 1751 long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE | 1752 (spMethod != null ? 1753 spMethod.flags() & Flags.AccessFlags : 1754 Flags.PUBLIC | Flags.STATIC); 1755 Symbol m = null; 1756 for (Scope.Entry e = polymorphicSignatureScope.lookup(name); 1757 e.scope != null; 1758 e = e.next()) { 1759 Symbol sym = e.sym; 1760 if (types.isSameType(mtype, sym.type) && 1761 (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) && 1762 types.isSameType(sym.owner.type, site)) { 1763 m = sym; 1764 break; 1765 } 1766 } 1767 if (m == null) { 1768 // create the desired method 1769 m = new MethodSymbol(flags, name, mtype, site.tsym); 1770 polymorphicSignatureScope.enter(m); 1771 } 1772 return m; 1773 } 1774 1775 /** Resolve a qualified method identifier, throw a fatal error if not 1776 * found. 1777 * @param pos The position to use for error reporting. 1778 * @param env The environment current at the method invocation. 1779 * @param site The type of the qualifying expression, in which 1780 * identifier is searched. 1781 * @param name The identifier's name. 1782 * @param argtypes The types of the invocation's value arguments. 1783 * @param typeargtypes The types of the invocation's type arguments. 1784 */ 1785 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env, 1786 Type site, Name name, 1787 List<Type> argtypes, 1788 List<Type> typeargtypes) { 1789 MethodResolutionContext resolveContext = new MethodResolutionContext(); 1790 resolveContext.internalResolution = true; 1791 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym, 1792 site, name, argtypes, typeargtypes); 1793 if (sym.kind == MTH) return (MethodSymbol)sym; 1794 else throw new FatalError( 1795 diags.fragment("fatal.err.cant.locate.meth", 1796 name)); 1797 } 1798 1799 /** Resolve constructor. 1800 * @param pos The position to use for error reporting. 1801 * @param env The environment current at the constructor invocation. 1802 * @param site The type of class for which a constructor is searched. 1803 * @param argtypes The types of the constructor invocation's value 1804 * arguments. 1805 * @param typeargtypes The types of the constructor invocation's type 1806 * arguments. 1807 */ 1808 Symbol resolveConstructor(DiagnosticPosition pos, 1809 Env<AttrContext> env, 1810 Type site, 1811 List<Type> argtypes, 1812 List<Type> typeargtypes) { 1813 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); 1814 } 1815 private Symbol resolveConstructor(MethodResolutionContext resolveContext, 1816 DiagnosticPosition pos, 1817 Env<AttrContext> env, 1818 Type site, 1819 List<Type> argtypes, 1820 List<Type> typeargtypes) { 1821 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1822 try { 1823 currentResolutionContext = resolveContext; 1824 Symbol sym = methodNotFound; 1825 List<MethodResolutionPhase> steps = methodResolutionSteps; 1826 while (steps.nonEmpty() && 1827 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1828 sym.kind >= ERRONEOUS) { 1829 currentResolutionContext.step = steps.head; 1830 sym = findConstructor(pos, env, site, argtypes, typeargtypes, 1831 steps.head.isBoxingRequired(), 1832 env.info.varArgs = steps.head.isVarargsRequired()); 1833 currentResolutionContext.resolutionCache.put(steps.head, sym); 1834 steps = steps.tail; 1835 } 1836 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 1837 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1838 sym = access(currentResolutionContext.resolutionCache.get(errPhase), 1839 pos, site, names.init, true, argtypes, typeargtypes); 1840 env.info.varArgs = errPhase.isVarargsRequired(); 1841 } 1842 return sym; 1843 } 1844 finally { 1845 currentResolutionContext = prevResolutionContext; 1846 } 1847 } 1848 1849 /** Resolve constructor using diamond inference. 1850 * @param pos The position to use for error reporting. 1851 * @param env The environment current at the constructor invocation. 1852 * @param site The type of class for which a constructor is searched. 1853 * The scope of this class has been touched in attribution. 1854 * @param argtypes The types of the constructor invocation's value 1855 * arguments. 1856 * @param typeargtypes The types of the constructor invocation's type 1857 * arguments. 1858 */ 1859 Symbol resolveDiamond(DiagnosticPosition pos, 1860 Env<AttrContext> env, 1861 Type site, 1862 List<Type> argtypes, 1863 List<Type> typeargtypes) { 1864 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1865 try { 1866 currentResolutionContext = new MethodResolutionContext(); 1867 Symbol sym = methodNotFound; 1868 List<MethodResolutionPhase> steps = methodResolutionSteps; 1869 while (steps.nonEmpty() && 1870 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1871 sym.kind >= ERRONEOUS) { 1872 currentResolutionContext.step = steps.head; 1873 sym = findDiamond(env, site, argtypes, typeargtypes, 1874 steps.head.isBoxingRequired(), 1875 env.info.varArgs = steps.head.isVarargsRequired()); 1876 currentResolutionContext.resolutionCache.put(steps.head, sym); 1877 steps = steps.tail; 1878 } 1879 if (sym.kind >= AMBIGUOUS) { 1880 final JCDiagnostic details = sym.kind == WRONG_MTH ? 1881 currentResolutionContext.candidates.head.details : 1882 null; 1883 Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") { 1884 @Override 1885 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 1886 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 1887 String key = details == null ? 1888 "cant.apply.diamond" : 1889 "cant.apply.diamond.1"; 1890 return diags.create(dkind, log.currentSource(), pos, key, 1891 diags.fragment("diamond", site.tsym), details); 1892 } 1893 }; 1894 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1895 sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes); 1896 env.info.varArgs = errPhase.isVarargsRequired(); 1897 } 1898 return sym; 1899 } 1900 finally { 1901 currentResolutionContext = prevResolutionContext; 1902 } 1903 } 1904 1905 /** This method scans all the constructor symbol in a given class scope - 1906 * assuming that the original scope contains a constructor of the kind: 1907 * Foo(X x, Y y), where X,Y are class type-variables declared in Foo, 1908 * a method check is executed against the modified constructor type: 1909 * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond 1910 * inference. The inferred return type of the synthetic constructor IS 1911 * the inferred type for the diamond operator. 1912 */ 1913 private Symbol findDiamond(Env<AttrContext> env, 1914 Type site, 1915 List<Type> argtypes, 1916 List<Type> typeargtypes, 1917 boolean allowBoxing, 1918 boolean useVarargs) { 1919 Symbol bestSoFar = methodNotFound; 1920 for (Scope.Entry e = site.tsym.members().lookup(names.init); 1921 e.scope != null; 1922 e = e.next()) { 1923 //- System.out.println(" e " + e.sym); 1924 if (e.sym.kind == MTH && 1925 (e.sym.flags_field & SYNTHETIC) == 0) { 1926 List<Type> oldParams = e.sym.type.tag == FORALL ? 1927 ((ForAll)e.sym.type).tvars : 1928 List.<Type>nil(); 1929 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), 1930 types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site)); 1931 bestSoFar = selectBest(env, site, argtypes, typeargtypes, 1932 new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym), 1933 bestSoFar, 1934 allowBoxing, 1935 useVarargs, 1936 false); 1937 } 1938 } 1939 return bestSoFar; 1940 } 1941 1942 /** Resolve constructor. 1943 * @param pos The position to use for error reporting. 1944 * @param env The environment current at the constructor invocation. 1945 * @param site The type of class for which a constructor is searched. 1946 * @param argtypes The types of the constructor invocation's value 1947 * arguments. 1948 * @param typeargtypes The types of the constructor invocation's type 1949 * arguments. 1950 * @param allowBoxing Allow boxing and varargs conversions. 1951 * @param useVarargs Box trailing arguments into an array for varargs. 1952 */ 1953 Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1954 Type site, List<Type> argtypes, 1955 List<Type> typeargtypes, 1956 boolean allowBoxing, 1957 boolean useVarargs) { 1958 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1959 try { 1960 currentResolutionContext = new MethodResolutionContext(); 1961 return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs); 1962 } 1963 finally { 1964 currentResolutionContext = prevResolutionContext; 1965 } 1966 } 1967 1968 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1969 Type site, List<Type> argtypes, 1970 List<Type> typeargtypes, 1971 boolean allowBoxing, 1972 boolean useVarargs) { 1973 Symbol sym = findMethod(env, site, 1974 names.init, argtypes, 1975 typeargtypes, allowBoxing, 1976 useVarargs, false); 1977 chk.checkDeprecated(pos, env.info.scope.owner, sym); 1978 return sym; 1979 } 1980 1981 /** Resolve a constructor, throw a fatal error if not found. 1982 * @param pos The position to use for error reporting. 1983 * @param env The environment current at the method invocation. 1984 * @param site The type to be constructed. 1985 * @param argtypes The types of the invocation's value arguments. 1986 * @param typeargtypes The types of the invocation's type arguments. 1987 */ 1988 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1989 Type site, 1990 List<Type> argtypes, 1991 List<Type> typeargtypes) { 1992 MethodResolutionContext resolveContext = new MethodResolutionContext(); 1993 resolveContext.internalResolution = true; 1994 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 1995 if (sym.kind == MTH) return (MethodSymbol)sym; 1996 else throw new FatalError( 1997 diags.fragment("fatal.err.cant.locate.ctor", site)); 1998 } 1999 2000 /** Resolve operator. 2001 * @param pos The position to use for error reporting. 2002 * @param optag The tag of the operation tree. 2003 * @param env The environment current at the operation. 2004 * @param argtypes The types of the operands. 2005 */ 2006 Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, 2007 Env<AttrContext> env, List<Type> argtypes) { 2008 MethodResolutionContext prevResolutionContext = currentResolutionContext; 2009 try { 2010 currentResolutionContext = new MethodResolutionContext(); 2011 Name name = treeinfo.operatorName(optag); 2012 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 2013 null, false, false, true); 2014 if (boxingEnabled && sym.kind >= WRONG_MTHS) 2015 sym = findMethod(env, syms.predefClass.type, name, argtypes, 2016 null, true, false, true); 2017 return access(sym, pos, env.enclClass.sym.type, name, 2018 false, argtypes, null); 2019 } 2020 finally { 2021 currentResolutionContext = prevResolutionContext; 2022 } 2023 } 2024 2025 /** Resolve operator. 2026 * @param pos The position to use for error reporting. 2027 * @param optag The tag of the operation tree. 2028 * @param env The environment current at the operation. 2029 * @param arg The type of the operand. 2030 */ 2031 Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) { 2032 return resolveOperator(pos, optag, env, List.of(arg)); 2033 } 2034 2035 /** Resolve binary operator. 2036 * @param pos The position to use for error reporting. 2037 * @param optag The tag of the operation tree. 2038 * @param env The environment current at the operation. 2039 * @param left The types of the left operand. 2040 * @param right The types of the right operand. 2041 */ 2042 Symbol resolveBinaryOperator(DiagnosticPosition pos, 2043 JCTree.Tag optag, 2044 Env<AttrContext> env, 2045 Type left, 2046 Type right) { 2047 return resolveOperator(pos, optag, env, List.of(left, right)); 2048 } 2049 2050 /** 2051 * Resolve `c.name' where name == this or name == super. 2052 * @param pos The position to use for error reporting. 2053 * @param env The environment current at the expression. 2054 * @param c The qualifier. 2055 * @param name The identifier's name. 2056 */ 2057 Symbol resolveSelf(DiagnosticPosition pos, 2058 Env<AttrContext> env, 2059 TypeSymbol c, 2060 Name name) { 2061 Env<AttrContext> env1 = env; 2062 boolean staticOnly = false; 2063 while (env1.outer != null) { 2064 if (isStatic(env1)) staticOnly = true; 2065 if (env1.enclClass.sym == c) { 2066 Symbol sym = env1.info.scope.lookup(name).sym; 2067 if (sym != null) { 2068 if (staticOnly) sym = new StaticError(sym); 2069 return access(sym, pos, env.enclClass.sym.type, 2070 name, true); 2071 } 2072 } 2073 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 2074 env1 = env1.outer; 2075 } 2076 log.error(pos, "not.encl.class", c); 2077 return syms.errSymbol; 2078 } 2079 2080 /** 2081 * Resolve `c.this' for an enclosing class c that contains the 2082 * named member. 2083 * @param pos The position to use for error reporting. 2084 * @param env The environment current at the expression. 2085 * @param member The member that must be contained in the result. 2086 */ 2087 Symbol resolveSelfContaining(DiagnosticPosition pos, 2088 Env<AttrContext> env, 2089 Symbol member, 2090 boolean isSuperCall) { 2091 Name name = names._this; 2092 Env<AttrContext> env1 = isSuperCall ? env.outer : env; 2093 boolean staticOnly = false; 2094 if (env1 != null) { 2095 while (env1 != null && env1.outer != null) { 2096 if (isStatic(env1)) staticOnly = true; 2097 if (env1.enclClass.sym.isSubClass(member.owner, types)) { 2098 Symbol sym = env1.info.scope.lookup(name).sym; 2099 if (sym != null) { 2100 if (staticOnly) sym = new StaticError(sym); 2101 return access(sym, pos, env.enclClass.sym.type, 2102 name, true); 2103 } 2104 } 2105 if ((env1.enclClass.sym.flags() & STATIC) != 0) 2106 staticOnly = true; 2107 env1 = env1.outer; 2108 } 2109 } 2110 log.error(pos, "encl.class.required", member); 2111 return syms.errSymbol; 2112 } 2113 2114 /** 2115 * Resolve an appropriate implicit this instance for t's container. 2116 * JLS 8.8.5.1 and 15.9.2 2117 */ 2118 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) { 2119 return resolveImplicitThis(pos, env, t, false); 2120 } 2121 2122 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) { 2123 Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0) 2124 ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) 2125 : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; 2126 if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) 2127 log.error(pos, "cant.ref.before.ctor.called", "this"); 2128 return thisType; 2129 } 2130 2131 /* *************************************************************************** 2132 * ResolveError classes, indicating error situations when accessing symbols 2133 ****************************************************************************/ 2134 2135 //used by TransTypes when checking target type of synthetic cast 2136 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) { 2137 AccessError error = new AccessError(env, env.enclClass.type, type.tsym); 2138 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null); 2139 } 2140 //where 2141 private void logResolveError(ResolveError error, 2142 DiagnosticPosition pos, 2143 Symbol location, 2144 Type site, 2145 Name name, 2146 List<Type> argtypes, 2147 List<Type> typeargtypes) { 2148 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, 2149 pos, location, site, name, argtypes, typeargtypes); 2150 if (d != null) { 2151 d.setFlag(DiagnosticFlag.RESOLVE_ERROR); 2152 log.report(d); 2153 } 2154 } 2155 2156 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); 2157 2158 public Object methodArguments(List<Type> argtypes) { 2159 return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes; 2160 } 2161 2162 /** 2163 * Root class for resolution errors. Subclass of ResolveError 2164 * represent a different kinds of resolution error - as such they must 2165 * specify how they map into concrete compiler diagnostics. 2166 */ 2167 private abstract class ResolveError extends Symbol { 2168 2169 /** The name of the kind of error, for debugging only. */ 2170 final String debugName; 2171 2172 ResolveError(int kind, String debugName) { 2173 super(kind, 0, null, null, null); 2174 this.debugName = debugName; 2175 } 2176 2177 @Override 2178 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 2179 throw new AssertionError(); 2180 } 2181 2182 @Override 2183 public String toString() { 2184 return debugName; 2185 } 2186 2187 @Override 2188 public boolean exists() { 2189 return false; 2190 } 2191 2192 /** 2193 * Create an external representation for this erroneous symbol to be 2194 * used during attribution - by default this returns the symbol of a 2195 * brand new error type which stores the original type found 2196 * during resolution. 2197 * 2198 * @param name the name used during resolution 2199 * @param location the location from which the symbol is accessed 2200 */ 2201 protected Symbol access(Name name, TypeSymbol location) { 2202 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 2203 } 2204 2205 /** 2206 * Create a diagnostic representing this resolution error. 2207 * 2208 * @param dkind The kind of the diagnostic to be created (e.g error). 2209 * @param pos The position to be used for error reporting. 2210 * @param site The original type from where the selection took place. 2211 * @param name The name of the symbol to be resolved. 2212 * @param argtypes The invocation's value arguments, 2213 * if we looked for a method. 2214 * @param typeargtypes The invocation's type arguments, 2215 * if we looked for a method. 2216 */ 2217 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2218 DiagnosticPosition pos, 2219 Symbol location, 2220 Type site, 2221 Name name, 2222 List<Type> argtypes, 2223 List<Type> typeargtypes); 2224 2225 /** 2226 * A name designates an operator if it consists 2227 * of a non-empty sequence of operator symbols +-~!/*%&|^<>= 2228 */ 2229 boolean isOperator(Name name) { 2230 int i = 0; 2231 while (i < name.getByteLength() && 2232 "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++; 2233 return i > 0 && i == name.getByteLength(); 2234 } 2235 } 2236 2237 /** 2238 * This class is the root class of all resolution errors caused by 2239 * an invalid symbol being found during resolution. 2240 */ 2241 abstract class InvalidSymbolError extends ResolveError { 2242 2243 /** The invalid symbol found during resolution */ 2244 Symbol sym; 2245 2246 InvalidSymbolError(int kind, Symbol sym, String debugName) { 2247 super(kind, debugName); 2248 this.sym = sym; 2249 } 2250 2251 @Override 2252 public boolean exists() { 2253 return true; 2254 } 2255 2256 @Override 2257 public String toString() { 2258 return super.toString() + " wrongSym=" + sym; 2259 } 2260 2261 @Override 2262 public Symbol access(Name name, TypeSymbol location) { 2263 if (sym.kind >= AMBIGUOUS) 2264 return ((ResolveError)sym).access(name, location); 2265 else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0) 2266 return types.createErrorType(name, location, sym.type).tsym; 2267 else 2268 return sym; 2269 } 2270 } 2271 2272 /** 2273 * InvalidSymbolError error class indicating that a symbol matching a 2274 * given name does not exists in a given site. 2275 */ 2276 class SymbolNotFoundError extends ResolveError { 2277 2278 SymbolNotFoundError(int kind) { 2279 super(kind, "symbol not found error"); 2280 } 2281 2282 @Override 2283 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2284 DiagnosticPosition pos, 2285 Symbol location, 2286 Type site, 2287 Name name, 2288 List<Type> argtypes, 2289 List<Type> typeargtypes) { 2290 argtypes = argtypes == null ? List.<Type>nil() : argtypes; 2291 typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes; 2292 if (name == names.error) 2293 return null; 2294 2295 if (isOperator(name)) { 2296 boolean isUnaryOp = argtypes.size() == 1; 2297 String key = argtypes.size() == 1 ? 2298 "operator.cant.be.applied" : 2299 "operator.cant.be.applied.1"; 2300 Type first = argtypes.head; 2301 Type second = !isUnaryOp ? argtypes.tail.head : null; 2302 return diags.create(dkind, log.currentSource(), pos, 2303 key, name, first, second); 2304 } 2305 boolean hasLocation = false; 2306 if (location == null) { 2307 location = site.tsym; 2308 } 2309 if (!location.name.isEmpty()) { 2310 if (location.kind == PCK && !site.tsym.exists()) { 2311 return diags.create(dkind, log.currentSource(), pos, 2312 "doesnt.exist", location); 2313 } 2314 hasLocation = !location.name.equals(names._this) && 2315 !location.name.equals(names._super); 2316 } 2317 boolean isConstructor = kind == ABSENT_MTH && 2318 name == names.table.names.init; 2319 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind); 2320 Name idname = isConstructor ? site.tsym.name : name; 2321 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); 2322 if (hasLocation) { 2323 return diags.create(dkind, log.currentSource(), pos, 2324 errKey, kindname, idname, //symbol kindname, name 2325 typeargtypes, argtypes, //type parameters and arguments (if any) 2326 getLocationDiag(location, site)); //location kindname, type 2327 } 2328 else { 2329 return diags.create(dkind, log.currentSource(), pos, 2330 errKey, kindname, idname, //symbol kindname, name 2331 typeargtypes, argtypes); //type parameters and arguments (if any) 2332 } 2333 } 2334 //where 2335 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) { 2336 String key = "cant.resolve"; 2337 String suffix = hasLocation ? ".location" : ""; 2338 switch (kindname) { 2339 case METHOD: 2340 case CONSTRUCTOR: { 2341 suffix += ".args"; 2342 suffix += hasTypeArgs ? ".params" : ""; 2343 } 2344 } 2345 return key + suffix; 2346 } 2347 private JCDiagnostic getLocationDiag(Symbol location, Type site) { 2348 if (location.kind == VAR) { 2349 return diags.fragment("location.1", 2350 kindName(location), 2351 location, 2352 location.type); 2353 } else { 2354 return diags.fragment("location", 2355 typeKindName(site), 2356 site, 2357 null); 2358 } 2359 } 2360 } 2361 2362 /** 2363 * InvalidSymbolError error class indicating that a given symbol 2364 * (either a method, a constructor or an operand) is not applicable 2365 * given an actual arguments/type argument list. 2366 */ 2367 class InapplicableSymbolError extends ResolveError { 2368 2369 InapplicableSymbolError() { 2370 super(WRONG_MTH, "inapplicable symbol error"); 2371 } 2372 2373 protected InapplicableSymbolError(int kind, String debugName) { 2374 super(kind, debugName); 2375 } 2376 2377 @Override 2378 public String toString() { 2379 return super.toString(); 2380 } 2381 2382 @Override 2383 public boolean exists() { 2384 return true; 2385 } 2386 2387 @Override 2388 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2389 DiagnosticPosition pos, 2390 Symbol location, 2391 Type site, 2392 Name name, 2393 List<Type> argtypes, 2394 List<Type> typeargtypes) { 2395 if (name == names.error) 2396 return null; 2397 2398 if (isOperator(name)) { 2399 boolean isUnaryOp = argtypes.size() == 1; 2400 String key = argtypes.size() == 1 ? 2401 "operator.cant.be.applied" : 2402 "operator.cant.be.applied.1"; 2403 Type first = argtypes.head; 2404 Type second = !isUnaryOp ? argtypes.tail.head : null; 2405 return diags.create(dkind, log.currentSource(), pos, 2406 key, name, first, second); 2407 } 2408 else { 2409 Candidate c = errCandidate(); 2410 Symbol ws = c.sym.asMemberOf(site, types); 2411 return diags.create(dkind, log.currentSource(), pos, 2412 "cant.apply.symbol" + (c.details != null ? ".1" : ""), 2413 kindName(ws), 2414 ws.name == names.init ? ws.owner.name : ws.name, 2415 methodArguments(ws.type.getParameterTypes()), 2416 methodArguments(argtypes), 2417 kindName(ws.owner), 2418 ws.owner.type, 2419 c.details); 2420 } 2421 } 2422 2423 @Override 2424 public Symbol access(Name name, TypeSymbol location) { 2425 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 2426 } 2427 2428 protected boolean shouldReport(Candidate c) { 2429 return !c.isApplicable() && 2430 (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) || 2431 (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC)); 2432 } 2433 2434 private Candidate errCandidate() { 2435 for (Candidate c : currentResolutionContext.candidates) { 2436 if (shouldReport(c)) { 2437 return c; 2438 } 2439 } 2440 Assert.error(); 2441 return null; 2442 } 2443 } 2444 2445 /** 2446 * ResolveError error class indicating that a set of symbols 2447 * (either methods, constructors or operands) is not applicable 2448 * given an actual arguments/type argument list. 2449 */ 2450 class InapplicableSymbolsError extends InapplicableSymbolError { 2451 2452 InapplicableSymbolsError() { 2453 super(WRONG_MTHS, "inapplicable symbols"); 2454 } 2455 2456 @Override 2457 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2458 DiagnosticPosition pos, 2459 Symbol location, 2460 Type site, 2461 Name name, 2462 List<Type> argtypes, 2463 List<Type> typeargtypes) { 2464 if (currentResolutionContext.candidates.nonEmpty()) { 2465 JCDiagnostic err = diags.create(dkind, 2466 log.currentSource(), 2467 pos, 2468 "cant.apply.symbols", 2469 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), 2470 getName(), 2471 argtypes); 2472 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); 2473 } else { 2474 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, 2475 location, site, name, argtypes, typeargtypes); 2476 } 2477 } 2478 2479 //where 2480 List<JCDiagnostic> candidateDetails(Type site) { 2481 List<JCDiagnostic> details = List.nil(); 2482 for (Candidate c : currentResolutionContext.candidates) { 2483 if (!shouldReport(c)) continue; 2484 JCDiagnostic detailDiag = diags.fragment("inapplicable.method", 2485 Kinds.kindName(c.sym), 2486 c.sym.location(site, types), 2487 c.sym.asMemberOf(site, types), 2488 c.details); 2489 details = details.prepend(detailDiag); 2490 } 2491 return details.reverse(); 2492 } 2493 2494 private Name getName() { 2495 Symbol sym = currentResolutionContext.candidates.head.sym; 2496 return sym.name == names.init ? 2497 sym.owner.name : 2498 sym.name; 2499 } 2500 } 2501 2502 /** 2503 * An InvalidSymbolError error class indicating that a symbol is not 2504 * accessible from a given site 2505 */ 2506 class AccessError extends InvalidSymbolError { 2507 2508 private Env<AttrContext> env; 2509 private Type site; 2510 2511 AccessError(Symbol sym) { 2512 this(null, null, sym); 2513 } 2514 2515 AccessError(Env<AttrContext> env, Type site, Symbol sym) { 2516 super(HIDDEN, sym, "access error"); 2517 this.env = env; 2518 this.site = site; 2519 if (debugResolve) 2520 log.error("proc.messager", sym + " @ " + site + " is inaccessible."); 2521 } 2522 2523 @Override 2524 public boolean exists() { 2525 return false; 2526 } 2527 2528 @Override 2529 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2530 DiagnosticPosition pos, 2531 Symbol location, 2532 Type site, 2533 Name name, 2534 List<Type> argtypes, 2535 List<Type> typeargtypes) { 2536 if (sym.owner.type.tag == ERROR) 2537 return null; 2538 2539 if (sym.name == names.init && sym.owner != site.tsym) { 2540 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, 2541 pos, location, site, name, argtypes, typeargtypes); 2542 } 2543 else if ((sym.flags() & PUBLIC) != 0 2544 || (env != null && this.site != null 2545 && !isAccessible(env, this.site))) { 2546 return diags.create(dkind, log.currentSource(), 2547 pos, "not.def.access.class.intf.cant.access", 2548 sym, sym.location()); 2549 } 2550 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { 2551 return diags.create(dkind, log.currentSource(), 2552 pos, "report.access", sym, 2553 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)), 2554 sym.location()); 2555 } 2556 else { 2557 return diags.create(dkind, log.currentSource(), 2558 pos, "not.def.public.cant.access", sym, sym.location()); 2559 } 2560 } 2561 } 2562 2563 /** 2564 * InvalidSymbolError error class indicating that an instance member 2565 * has erroneously been accessed from a static context. 2566 */ 2567 class StaticError extends InvalidSymbolError { 2568 2569 StaticError(Symbol sym) { 2570 super(STATICERR, sym, "static error"); 2571 } 2572 2573 @Override 2574 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2575 DiagnosticPosition pos, 2576 Symbol location, 2577 Type site, 2578 Name name, 2579 List<Type> argtypes, 2580 List<Type> typeargtypes) { 2581 Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS) 2582 ? types.erasure(sym.type).tsym 2583 : sym); 2584 return diags.create(dkind, log.currentSource(), pos, 2585 "non-static.cant.be.ref", kindName(sym), errSym); 2586 } 2587 } 2588 2589 /** 2590 * InvalidSymbolError error class indicating that a pair of symbols 2591 * (either methods, constructors or operands) are ambiguous 2592 * given an actual arguments/type argument list. 2593 */ 2594 class AmbiguityError extends InvalidSymbolError { 2595 2596 /** The other maximally specific symbol */ 2597 Symbol sym2; 2598 2599 AmbiguityError(Symbol sym1, Symbol sym2) { 2600 super(AMBIGUOUS, sym1, "ambiguity error"); 2601 this.sym2 = sym2; 2602 } 2603 2604 @Override 2605 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, 2606 DiagnosticPosition pos, 2607 Symbol location, 2608 Type site, 2609 Name name, 2610 List<Type> argtypes, 2611 List<Type> typeargtypes) { 2612 AmbiguityError pair = this; 2613 while (true) { 2614 if (pair.sym.kind == AMBIGUOUS) 2615 pair = (AmbiguityError)pair.sym; 2616 else if (pair.sym2.kind == AMBIGUOUS) 2617 pair = (AmbiguityError)pair.sym2; 2618 else break; 2619 } 2620 Name sname = pair.sym.name; 2621 if (sname == names.init) sname = pair.sym.owner.name; 2622 return diags.create(dkind, log.currentSource(), 2623 pos, "ref.ambiguous", sname, 2624 kindName(pair.sym), 2625 pair.sym, 2626 pair.sym.location(site, types), 2627 kindName(pair.sym2), 2628 pair.sym2, 2629 pair.sym2.location(site, types)); 2630 } 2631 } 2632 2633 enum MethodResolutionPhase { 2634 BASIC(false, false), 2635 BOX(true, false), 2636 VARARITY(true, true); 2637 2638 boolean isBoxingRequired; 2639 boolean isVarargsRequired; 2640 2641 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { 2642 this.isBoxingRequired = isBoxingRequired; 2643 this.isVarargsRequired = isVarargsRequired; 2644 } 2645 2646 public boolean isBoxingRequired() { 2647 return isBoxingRequired; 2648 } 2649 2650 public boolean isVarargsRequired() { 2651 return isVarargsRequired; 2652 } 2653 2654 public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) { 2655 return (varargsEnabled || !isVarargsRequired) && 2656 (boxingEnabled || !isBoxingRequired); 2657 } 2658 } 2659 2660 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); 2661 2662 /** 2663 * A resolution context is used to keep track of intermediate results of 2664 * overload resolution, such as list of method that are not applicable 2665 * (used to generate more precise diagnostics) and so on. Resolution contexts 2666 * can be nested - this means that when each overload resolution routine should 2667 * work within the resolution context it created. 2668 */ 2669 class MethodResolutionContext { 2670 2671 private List<Candidate> candidates = List.nil(); 2672 2673 private Map<MethodResolutionPhase, Symbol> resolutionCache = 2674 new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class); 2675 2676 private MethodResolutionPhase step = null; 2677 2678 private boolean internalResolution = false; 2679 2680 private MethodResolutionPhase firstErroneousResolutionPhase() { 2681 MethodResolutionPhase bestSoFar = BASIC; 2682 Symbol sym = methodNotFound; 2683 List<MethodResolutionPhase> steps = methodResolutionSteps; 2684 while (steps.nonEmpty() && 2685 steps.head.isApplicable(boxingEnabled, varargsEnabled) && 2686 sym.kind >= WRONG_MTHS) { 2687 sym = resolutionCache.get(steps.head); 2688 bestSoFar = steps.head; 2689 steps = steps.tail; 2690 } 2691 return bestSoFar; 2692 } 2693 2694 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { 2695 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); 2696 if (!candidates.contains(c)) 2697 candidates = candidates.append(c); 2698 } 2699 2700 void addApplicableCandidate(Symbol sym, Type mtype) { 2701 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype); 2702 candidates = candidates.append(c); 2703 } 2704 2705 /** 2706 * This class represents an overload resolution candidate. There are two 2707 * kinds of candidates: applicable methods and inapplicable methods; 2708 * applicable methods have a pointer to the instantiated method type, 2709 * while inapplicable candidates contain further details about the 2710 * reason why the method has been considered inapplicable. 2711 */ 2712 class Candidate { 2713 2714 final MethodResolutionPhase step; 2715 final Symbol sym; 2716 final JCDiagnostic details; 2717 final Type mtype; 2718 2719 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) { 2720 this.step = step; 2721 this.sym = sym; 2722 this.details = details; 2723 this.mtype = mtype; 2724 } 2725 2726 @Override 2727 public boolean equals(Object o) { 2728 if (o instanceof Candidate) { 2729 Symbol s1 = this.sym; 2730 Symbol s2 = ((Candidate)o).sym; 2731 if ((s1 != s2 && 2732 (s1.overrides(s2, s1.owner.type.tsym, types, false) || 2733 (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || 2734 ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) 2735 return true; 2736 } 2737 return false; 2738 } 2739 2740 boolean isApplicable() { 2741 return mtype != null; 2742 } 2743 } 2744 } 2745 2746 MethodResolutionContext currentResolutionContext = null; 2747 }