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