MemberEnter.java revision 2571:10fc81ac75b4
121308Sache/* 221308Sache * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 321308Sache * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 421308Sache * 521308Sache * This code is free software; you can redistribute it and/or modify it 621308Sache * under the terms of the GNU General Public License version 2 only, as 721308Sache * published by the Free Software Foundation. Oracle designates this 821308Sache * particular file as subject to the "Classpath" exception as provided 921308Sache * by Oracle in the LICENSE file that accompanied this code. 1021308Sache * 1121308Sache * This code is distributed in the hope that it will be useful, but WITHOUT 1221308Sache * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1358310Sache * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1421308Sache * version 2 for more details (a copy is included in the LICENSE file that 1521308Sache * accompanied this code). 1621308Sache * 1721308Sache * You should have received a copy of the GNU General Public License version 1821308Sache * 2 along with this work; if not, write to the Free Software Foundation, 1921308Sache * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2021308Sache * 2121308Sache * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2221308Sache * or visit www.oracle.com if you need additional information or have any 2321308Sache * questions. 2458310Sache */ 2521308Sache 2621308Sachepackage com.sun.tools.javac.comp; 2721308Sache 2821308Sacheimport java.util.Collections; 2921308Sacheimport java.util.HashSet; 3021308Sacheimport java.util.IdentityHashMap; 3121308Sacheimport java.util.Set; 3221308Sache 3375406Sacheimport javax.tools.JavaFileObject; 3475406Sache 3521308Sacheimport com.sun.tools.javac.code.*; 3621308Sacheimport com.sun.tools.javac.code.Scope.ImportFilter; 3721308Sacheimport com.sun.tools.javac.code.Scope.NamedImportScope; 3821308Sacheimport com.sun.tools.javac.code.Scope.StarImportScope; 3921308Sacheimport com.sun.tools.javac.code.Scope.WriteableScope; 4021308Sacheimport com.sun.tools.javac.jvm.*; 4121308Sacheimport com.sun.tools.javac.tree.*; 4221308Sacheimport com.sun.tools.javac.util.*; 4321308Sache 4421308Sacheimport com.sun.tools.javac.code.Symbol.*; 4521308Sacheimport com.sun.tools.javac.code.Type.*; 4621308Sacheimport com.sun.tools.javac.code.TypeAnnotationPosition.*; 4721308Sacheimport com.sun.tools.javac.tree.JCTree.*; 4821308Sache 4921308Sacheimport static com.sun.tools.javac.code.Flags.*; 5021308Sacheimport static com.sun.tools.javac.code.Flags.ANNOTATION; 5121308Sacheimport static com.sun.tools.javac.code.Kinds.*; 5221308Sacheimport static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 5321308Sacheimport static com.sun.tools.javac.code.TypeTag.CLASS; 5421308Sacheimport static com.sun.tools.javac.code.TypeTag.ERROR; 5521308Sacheimport static com.sun.tools.javac.code.TypeTag.TYPEVAR; 5621308Sacheimport static com.sun.tools.javac.tree.JCTree.Tag.*; 5721308Sache 5821308Sacheimport com.sun.tools.javac.util.Dependencies.AttributionKind; 5921308Sacheimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 6021308Sacheimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 6121308Sache 6221308Sache/** This is the second phase of Enter, in which classes are completed 6321308Sache * by entering their members into the class scope using 6421308Sache * MemberEnter.complete(). See Enter for an overview. 6521308Sache * 6621308Sache * <p><b>This is NOT part of any supported API. 6721308Sache * If you write code that depends on this, you do so at your own risk. 6821308Sache * This code and its internal interfaces are subject to change or 6921308Sache * deletion without notice.</b> 7021308Sache */ 7121308Sachepublic class MemberEnter extends JCTree.Visitor implements Completer { 7221308Sache protected static final Context.Key<MemberEnter> memberEnterKey = new Context.Key<>(); 7321308Sache 7421308Sache /** A switch to determine whether we check for package/class conflicts 7521308Sache */ 76119610Sache final static boolean checkClash = true; 77119610Sache 7821308Sache private final Names names; 7921308Sache private final Enter enter; 80119610Sache private final Log log; 81119610Sache private final Check chk; 82119610Sache private final Attr attr; 83119610Sache private final Symtab syms; 84119610Sache private final TreeMaker make; 85119610Sache private final Todo todo; 8621308Sache private final Annotate annotate; 8721308Sache private final Types types; 8821308Sache private final JCDiagnostic.Factory diags; 8921308Sache private final Source source; 9021308Sache private final Target target; 9121308Sache private final DeferredLintHandler deferredLintHandler; 92119610Sache private final Lint lint; 93119610Sache private final TypeEnvs typeEnvs; 94119610Sache private final Dependencies dependencies; 95119610Sache 96119610Sache public static MemberEnter instance(Context context) { 97119610Sache MemberEnter instance = context.get(memberEnterKey); 98119610Sache if (instance == null) 9921308Sache instance = new MemberEnter(context); 10021308Sache return instance; 10121308Sache } 10221308Sache 10321308Sache protected MemberEnter(Context context) { 10421308Sache context.put(memberEnterKey, this); 10521308Sache names = Names.instance(context); 10675406Sache enter = Enter.instance(context); 10721308Sache log = Log.instance(context); 10821308Sache chk = Check.instance(context); 10975406Sache attr = Attr.instance(context); 11021308Sache syms = Symtab.instance(context); 11121308Sache make = TreeMaker.instance(context); 11221308Sache todo = Todo.instance(context); 113119610Sache annotate = Annotate.instance(context); 11421308Sache types = Types.instance(context); 11521308Sache diags = JCDiagnostic.Factory.instance(context); 11621308Sache source = Source.instance(context); 11721308Sache target = Target.instance(context); 11821308Sache deferredLintHandler = DeferredLintHandler.instance(context); 11921308Sache lint = Lint.instance(context); 12021308Sache typeEnvs = TypeEnvs.instance(context); 12121308Sache dependencies = Dependencies.instance(context); 12221308Sache allowTypeAnnos = source.allowTypeAnnotations(); 12321308Sache } 12421308Sache 12521308Sache /** Switch: support type annotations. 12621308Sache */ 12721308Sache boolean allowTypeAnnos; 12821308Sache 12921308Sache /** A queue for classes whose members still need to be entered into the 13021308Sache * symbol table. 131119610Sache */ 132119610Sache ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<>(); 133119610Sache 134119610Sache /** Set to true only when the first of a set of classes is 13521308Sache * processed from the half completed queue. 13621308Sache */ 13721308Sache boolean isFirst = true; 13821308Sache 13921308Sache /** A flag to disable completion from time to time during member 14021308Sache * enter, as we only need to look up types. This avoids 14158310Sache * unnecessarily deep recursion. 14258310Sache */ 14321308Sache boolean completionEnabled = true; 14421308Sache 14521308Sache /** The creator that will be used for any varDef's we visit. This 14621308Sache * is used to create the position for any type annotations (or 14721308Sache * annotations that potentially are type annotations) that we 14821308Sache * encounter. 149119610Sache */ 150119610Sache Annotate.PositionCreator creator; 151119610Sache 152119610Sache /* ---------- Processing import clauses ---------------- 15321308Sache */ 15421308Sache 15521308Sache /** Import all classes of a class or package on demand. 15621308Sache * @param pos Position to be used for error reporting. 157 * @param tsym The class or package the members of which are imported. 158 * @param env The env in which the imported classes will be entered. 159 */ 160 private void importAll(int pos, 161 final TypeSymbol tsym, 162 Env<AttrContext> env) { 163 // Check that packages imported from exist (JLS ???). 164 if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) { 165 // If we can't find java.lang, exit immediately. 166 if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) { 167 JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang"); 168 throw new FatalError(msg); 169 } else { 170 log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym); 171 } 172 } 173 env.toplevel.starImportScope.importAll(tsym.members(), tsym.members(), typeImportFilter, false); 174 } 175 176 /** Import all static members of a class or package on demand. 177 * @param pos Position to be used for error reporting. 178 * @param tsym The class or package the members of which are imported. 179 * @param env The env in which the imported classes will be entered. 180 */ 181 private void importStaticAll(int pos, 182 final TypeSymbol tsym, 183 Env<AttrContext> env) { 184 final StarImportScope toScope = env.toplevel.starImportScope; 185 final PackageSymbol packge = env.toplevel.packge; 186 final TypeSymbol origin = tsym; 187 188 // enter imported types immediately 189 new SymbolImporter() { 190 void doImport(TypeSymbol tsym) { 191 toScope.importAll(tsym.members(), origin.members(), staticImportFilter, true); 192 } 193 }.importFrom(tsym); 194 } 195 196 /** Import statics types of a given name. Non-types are handled in Attr. 197 * @param pos Position to be used for error reporting. 198 * @param tsym The class from which the name is imported. 199 * @param name The (simple) name being imported. 200 * @param env The environment containing the named import 201 * scope to add to. 202 */ 203 private void importNamedStatic(final DiagnosticPosition pos, 204 final TypeSymbol tsym, 205 final Name name, 206 final Env<AttrContext> env) { 207 if (tsym.kind != TYP) { 208 log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces"); 209 return; 210 } 211 212 final NamedImportScope toScope = env.toplevel.namedImportScope; 213 final Scope originMembers = tsym.members(); 214 215 // enter imported types immediately 216 new SymbolImporter() { 217 void doImport(TypeSymbol tsym) { 218 Set<Symbol> maskedOut = null; 219 for (Symbol sym : tsym.members().getSymbolsByName(name)) { 220 if (sym.kind == TYP && 221 staticImportFilter.accepts(originMembers, sym) && 222 !chk.checkUniqueStaticImport(pos, env.toplevel, sym)) { 223 if (maskedOut == null) 224 maskedOut = Collections.newSetFromMap(new IdentityHashMap<Symbol, Boolean>()); 225 maskedOut.add(sym); 226 } 227 } 228 ImportFilter importFilter = maskedOut != null ? 229 new MaskedImportFilter(staticImportFilter, maskedOut) : 230 staticImportFilter; 231 toScope.importByName(tsym.members(), originMembers, name, importFilter); 232 } 233 }.importFrom(tsym); 234 } 235 //where: 236 class MaskedImportFilter implements ImportFilter { 237 238 private final ImportFilter delegate; 239 private final Set<Symbol> maskedOut; 240 241 public MaskedImportFilter(ImportFilter delegate, Set<Symbol> maskedOut) { 242 this.delegate = delegate; 243 this.maskedOut = maskedOut; 244 } 245 246 @Override 247 public boolean accepts(Scope origin, Symbol sym) { 248 return !maskedOut.contains(sym) && delegate.accepts(origin, sym); 249 } 250 } 251 abstract class SymbolImporter { 252 Set<Symbol> processed = new HashSet<>(); 253 void importFrom(TypeSymbol tsym) { 254 if (tsym == null || !processed.add(tsym)) 255 return; 256 257 // also import inherited names 258 importFrom(types.supertype(tsym.type).tsym); 259 for (Type t : types.interfaces(tsym.type)) 260 importFrom(t.tsym); 261 262 doImport(tsym); 263 } 264 abstract void doImport(TypeSymbol tsym); 265 } 266 267 /** Import given class. 268 * @param pos Position to be used for error reporting. 269 * @param tsym The class to be imported. 270 * @param env The environment containing the named import 271 * scope to add to. 272 */ 273 private void importNamed(DiagnosticPosition pos, final Symbol tsym, Env<AttrContext> env) { 274 if (tsym.kind == TYP && 275 chk.checkUniqueImport(pos, env.toplevel, tsym)) 276 env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym); 277 } 278 279 /** Construct method type from method signature. 280 * @param msym The MethodSymbol for the method. 281 * @param typarams The method's type parameters. 282 * @param params The method's value parameters. 283 * @param res The method's result type, 284 * null if it is a constructor. 285 * @param recvparam The method's receiver parameter, 286 * null if none given; TODO: or already set here? 287 * @param thrown The method's thrown exceptions. 288 * @param env The method's (local) environment. 289 * @param declAnnos The annotations on the method declaration, 290 * some of which may be type annotations on 291 * the return type. 292 * @param deferPos The deferred diagnostic position for error 293 * reporting. 294 */ 295 Type signature(final MethodSymbol msym, 296 final List<JCTypeParameter> typarams, 297 final List<JCVariableDecl> params, 298 final JCTree res, 299 final JCVariableDecl recvparam, 300 final List<JCExpression> thrown, 301 final Env<AttrContext> env, 302 final List<JCAnnotation> declAnnos, 303 final DiagnosticPosition deferPos) { 304 int i; 305 306 // Enter and attribute type parameters. 307 List<Type> tvars = enter.classEnter(typarams, env); 308 attr.attribTypeVariables(typarams, env); 309 310 // Handle type annotations on type parameters. 311 i = 0; 312 for (List<JCTypeParameter> l = typarams; l.nonEmpty(); 313 l = l.tail, i++) { 314 final JCTypeParameter param = l.head; 315 annotate.annotateTypeLater(param, env, msym, deferPos, 316 annotate.methodTypeParamCreator(i)); 317 // ...and bounds on type parameters. 318 int j = 0; 319 for (List<JCExpression> bounds = param.bounds; 320 bounds.nonEmpty(); bounds = bounds.tail, j++) { 321 annotate.annotateTypeLater(bounds.head, env, msym, deferPos, 322 annotate.methodTypeParamBoundCreator(param, i, j)); 323 } 324 } 325 326 // Enter and attribute value parameters. Type annotations get 327 // METHOD_FORMAL_PARAMETER positions. 328 ListBuffer<Type> argbuf = new ListBuffer<>(); 329 i = 0; 330 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail, i++) { 331 // The types will get annotated by visitVarDef 332 memberEnter(l.head, env, annotate.paramCreator(i)); 333 argbuf.append(l.head.vartype.type); 334 } 335 336 // Attribute result type, if one is given. 337 Type restype; 338 339 if (res != null) { 340 // If we have any declaration annotations, they might 341 // be/also be type annotations on the return type. We 342 // pass them in, so they get classified and then attached 343 // to the method, or the return type, or both. 344 restype = attr.attribType(res, env); 345 annotate.annotateTypeLater(res, declAnnos, env, msym, deferPos, 346 annotate.returnCreator); 347 } else { 348 // For constructors, we don't actually have a type, so we 349 // can't have a type path (except for INNER_TYPE), and we 350 // don't have annotations on arrays, type arguments, and 351 // the like. 352 353 // The only type path we have is if we are in an inner type. 354 List<TypePathEntry> typepath = Annotate.makeInners(msym.owner.type); 355 TypeAnnotationPosition tapos = 356 TypeAnnotationPosition.methodReturn(typepath, env.getLambda(), -1); 357 358 // We don't have to walk down a type. We just have to do 359 // repeating annotation handling, then classify and attach 360 // the annotations. 361 annotate.annotateWithClassifyLater(declAnnos, env, msym, 362 deferPos, tapos); 363 restype = syms.voidType; 364 } 365 366 367 // Attribute receiver type, if one is given. 368 Type recvtype; 369 if (recvparam!=null) { 370 // The type will get annotated by visitVarDef 371 memberEnter(recvparam, env, annotate.receiverCreator); 372 recvtype = recvparam.vartype.type; 373 } else { 374 recvtype = null; 375 } 376 377 // Attribute thrown exceptions. 378 ListBuffer<Type> thrownbuf = new ListBuffer<>(); 379 i = 0; 380 for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail, i++) { 381 Type exc = attr.attribType(l.head, env); 382 // Annotate each exception type. 383 annotate.annotateTypeLater(l.head, env, msym, deferPos, 384 annotate.throwCreator(i)); 385 if (!exc.hasTag(TYPEVAR)) { 386 exc = chk.checkClassType(l.head.pos(), exc); 387 } else if (exc.tsym.owner == msym) { 388 //mark inference variables in 'throws' clause 389 exc.tsym.flags_field |= THROWS; 390 } 391 thrownbuf.append(exc); 392 } 393 MethodType mtype = new MethodType(argbuf.toList(), 394 restype, 395 thrownbuf.toList(), 396 syms.methodClass); 397 mtype.recvtype = recvtype; 398 399 return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype); 400 } 401 402/* ******************************************************************** 403 * Visitor methods for member enter 404 *********************************************************************/ 405 406 ImportFilter staticImportFilter; 407 ImportFilter typeImportFilter = new ImportFilter() { 408 @Override 409 public boolean accepts(Scope origin, Symbol t) { 410 return t.kind == Kinds.TYP; 411 } 412 }; 413 414 protected void memberEnter(JCCompilationUnit tree, Env<AttrContext> env) { 415 ImportFilter prevStaticImportFilter = staticImportFilter; 416 try { 417 final PackageSymbol packge = env.toplevel.packge; 418 this.staticImportFilter = new ImportFilter() { 419 @Override 420 public boolean accepts(Scope origin, Symbol sym) { 421 return sym.isStatic() && 422 chk.staticImportAccessible(sym, packge) && 423 sym.isMemberOf((TypeSymbol) origin.owner, types); 424 } 425 }; 426 memberEnter((JCTree) tree, env); 427 } finally { 428 this.staticImportFilter = prevStaticImportFilter; 429 } 430 } 431 432 /** Visitor argument: the current environment 433 */ 434 protected Env<AttrContext> env; 435 436 /** Enter field and method definitions and process import 437 * clauses, catching any completion failure exceptions. 438 */ 439 protected void memberEnter(JCTree tree, Env<AttrContext> env, 440 Annotate.PositionCreator creator) { 441 Env<AttrContext> prevEnv = this.env; 442 Annotate.PositionCreator prevCreator = this.creator; 443 try { 444 this.env = env; 445 this.creator = creator; 446 tree.accept(this); 447 } catch (CompletionFailure ex) { 448 chk.completionError(tree.pos(), ex); 449 } finally { 450 this.creator = prevCreator; 451 this.env = prevEnv; 452 } 453 } 454 455 456 protected void memberEnter(JCTree tree, Env<AttrContext> env) { 457 memberEnter(tree, env, annotate.noCreator); 458 } 459 460 /** Enter members from a list of trees. 461 */ 462 void memberEnter(List<? extends JCTree> trees, 463 Env<AttrContext> env, 464 Annotate.PositionCreator creator) { 465 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) 466 memberEnter(l.head, env, creator); 467 } 468 469 void memberEnter(List<? extends JCTree> trees, 470 Env<AttrContext> env) { 471 memberEnter(trees, env, annotate.noCreator); 472 } 473 474 /** Enter members for a class. 475 */ 476 void finishClass(final JCClassDecl tree, final Env<AttrContext> env) { 477 if ((tree.mods.flags & Flags.ENUM) != 0 && 478 (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) { 479 addEnumMembers(tree, env); 480 } 481 memberEnter(tree.defs, env, annotate.fieldCreator); 482 } 483 484 /** Add the implicit members for an enum type 485 * to the symbol table. 486 */ 487 private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) { 488 JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass, 489 Type.noAnnotations)); 490 491 // public static T[] values() { return ???; } 492 JCMethodDecl values = make. 493 MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC), 494 names.values, 495 valuesType, 496 List.<JCTypeParameter>nil(), 497 List.<JCVariableDecl>nil(), 498 List.<JCExpression>nil(), // thrown 499 null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))), 500 null); 501 memberEnter(values, env); 502 503 // public static T valueOf(String name) { return ???; } 504 JCMethodDecl valueOf = make. 505 MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC), 506 names.valueOf, 507 make.Type(tree.sym.type), 508 List.<JCTypeParameter>nil(), 509 List.of(make.VarDef(make.Modifiers(Flags.PARAMETER | 510 Flags.MANDATED), 511 names.fromString("name"), 512 make.Type(syms.stringType), null)), 513 List.<JCExpression>nil(), // thrown 514 null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))), 515 null); 516 memberEnter(valueOf, env); 517 } 518 519 public void visitTopLevel(JCCompilationUnit tree) { 520 if (!tree.starImportScope.isEmpty()) { 521 // we must have already processed this toplevel 522 return; 523 } 524 525 DiagnosticPosition prevLintPos = deferredLintHandler.immediate(); 526 Lint prevLint = chk.setLint(lint); 527 528 try { 529 // Import-on-demand java.lang. 530 importAll(tree.pos, syms.enterPackage(names.java_lang), env); 531 532 // Process the package def and all import clauses. 533 memberEnter(tree.defs, env); 534 } finally { 535 chk.setLint(prevLint); 536 deferredLintHandler.setPos(prevLintPos); 537 } 538 } 539 540 public void visitPackageDef(JCPackageDecl tree) { 541 // check that no class exists with same fully qualified name as 542 // toplevel package 543 if (checkClash && tree.pid != null) { 544 Symbol p = env.toplevel.packge; 545 while (p.owner != syms.rootPackage) { 546 p.owner.complete(); // enter all class members of p 547 if (syms.classes.get(p.getQualifiedName()) != null) { 548 log.error(tree.pos, 549 "pkg.clashes.with.class.of.same.name", 550 p); 551 } 552 p = p.owner; 553 } 554 } 555 // process package annotations 556 annotate.annotateLater(tree.annotations, env, env.toplevel.packge); 557 } 558 559 // process the non-static imports and the static imports of types. 560 public void visitImport(JCImport tree) { 561 dependencies.push(AttributionKind.IMPORT, tree); 562 JCFieldAccess imp = (JCFieldAccess)tree.qualid; 563 Name name = TreeInfo.name(imp); 564 565 // Create a local environment pointing to this tree to disable 566 // effects of other imports in Resolve.findGlobalType 567 Env<AttrContext> localEnv = env.dup(tree); 568 569 TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym; 570 if (name == names.asterisk) { 571 // Import on demand. 572 chk.checkCanonical(imp.selected); 573 if (tree.staticImport) 574 importStaticAll(tree.pos, p, env); 575 else 576 importAll(tree.pos, p, env); 577 } else { 578 // Named type import. 579 if (tree.staticImport) { 580 importNamedStatic(tree.pos(), p, name, localEnv); 581 chk.checkCanonical(imp.selected); 582 } else { 583 TypeSymbol c = attribImportType(imp, localEnv).tsym; 584 chk.checkCanonical(imp); 585 importNamed(tree.pos(), c, env); 586 } 587 } 588 dependencies.pop(); 589 } 590 591 public void visitMethodDef(JCMethodDecl tree) { 592 WriteableScope enclScope = enter.enterScope(env); 593 MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner); 594 m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree); 595 tree.sym = m; 596 597 //if this is a default method, add the DEFAULT flag to the enclosing interface 598 if ((tree.mods.flags & DEFAULT) != 0) { 599 m.enclClass().flags_field |= DEFAULT; 600 } 601 602 Env<AttrContext> localEnv = methodEnv(tree, env); 603 604 DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); 605 try { 606 // Compute the method type 607 m.type = signature(m, tree.typarams, tree.params, 608 tree.restype, tree.recvparam, 609 tree.thrown, localEnv, 610 tree.mods.annotations, tree.pos()); 611 } finally { 612 deferredLintHandler.setPos(prevLintPos); 613 } 614 615 if (types.isSignaturePolymorphic(m)) { 616 m.flags_field |= SIGNATURE_POLYMORPHIC; 617 } 618 619 // Set m.params 620 ListBuffer<VarSymbol> params = new ListBuffer<>(); 621 JCVariableDecl lastParam = null; 622 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { 623 JCVariableDecl param = lastParam = l.head; 624 params.append(Assert.checkNonNull(param.sym)); 625 } 626 m.params = params.toList(); 627 628 // mark the method varargs, if necessary 629 if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0) 630 m.flags_field |= Flags.VARARGS; 631 632 localEnv.info.scope.leave(); 633 if (chk.checkUnique(tree.pos(), m, enclScope)) { 634 enclScope.enter(m); 635 } 636 637 if (tree.defaultValue != null) 638 annotateDefaultValueLater(tree.defaultValue, localEnv, 639 m, annotate.noCreator); 640 } 641 642 /** Create a fresh environment for method bodies. 643 * @param tree The method definition. 644 * @param env The environment current outside of the method definition. 645 */ 646 Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) { 647 Env<AttrContext> localEnv = 648 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(tree.sym))); 649 localEnv.enclMethod = tree; 650 if (tree.sym.type != null) { 651 //when this is called in the enter stage, there's no type to be set 652 localEnv.info.returnResult = attr.new ResultInfo(VAL, tree.sym.type.getReturnType()); 653 } 654 if ((tree.mods.flags & STATIC) != 0) localEnv.info.staticLevel++; 655 return localEnv; 656 } 657 658 public void visitVarDef(JCVariableDecl tree) { 659 Env<AttrContext> localEnv = env; 660 if ((tree.mods.flags & STATIC) != 0 || 661 (env.info.scope.owner.flags() & INTERFACE) != 0) { 662 localEnv = env.dup(tree, env.info.dup()); 663 localEnv.info.staticLevel++; 664 } 665 DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); 666 annotate.enterStart(); 667 try { 668 try { 669 if (TreeInfo.isEnumInit(tree)) { 670 attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); 671 } else { 672 attr.attribType(tree.vartype, localEnv); 673 if (TreeInfo.isReceiverParam(tree)) 674 checkReceiver(tree, localEnv); 675 } 676 } finally { 677 deferredLintHandler.setPos(prevLintPos); 678 } 679 680 if ((tree.mods.flags & VARARGS) != 0) { 681 //if we are entering a varargs parameter, we need to 682 //replace its type (a plain array type) with the more 683 //precise VarargsType --- we need to do it this way 684 //because varargs is represented in the tree as a 685 //modifier on the parameter declaration, and not as a 686 //distinct type of array node. 687 ArrayType atype = (ArrayType)tree.vartype.type; 688 tree.vartype.type = atype.makeVarargs(); 689 } 690 WriteableScope enclScope = enter.enterScope(env); 691 VarSymbol v = 692 new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner); 693 v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree); 694 tree.sym = v; 695 if (tree.init != null) { 696 v.flags_field |= HASINIT; 697 if ((v.flags_field & FINAL) != 0 && 698 needsLazyConstValue(tree.init)) { 699 Env<AttrContext> initEnv = getInitEnv(tree, env); 700 initEnv.info.enclVar = v; 701 v.setLazyConstValue(initEnv(tree, initEnv), attr, tree); 702 } 703 } 704 if (chk.checkUnique(tree.pos(), v, enclScope)) { 705 chk.checkTransparentVar(tree.pos(), v, enclScope); 706 enclScope.enter(v); 707 } 708 if (TreeInfo.isReceiverParam(tree)) { 709 // If we are dealing with a receiver parameter, then 710 // we only allow base type annotations to be type 711 // annotations. Receivers are not allowed to have 712 // declaration annotations. 713 annotate.annotateStrictTypeLater(tree.vartype, tree.mods.annotations, 714 localEnv, v, tree.pos(), creator); 715 } else { 716 // Otherwise, we annotate the type. 717 annotate.annotateTypeLater(tree.vartype, tree.mods.annotations, 718 localEnv, v, tree.pos(), creator); 719 } 720 v.pos = tree.pos; 721 } finally { 722 annotate.enterDone(); 723 } 724 } 725 // where 726 void checkType(JCTree tree, Type type, String diag) { 727 if (!tree.type.isErroneous() && !types.isSameType(tree.type, type)) { 728 log.error(tree, diag, type, tree.type); 729 } 730 } 731 void checkReceiver(JCVariableDecl tree, Env<AttrContext> localEnv) { 732 attr.attribExpr(tree.nameexpr, localEnv); 733 MethodSymbol m = localEnv.enclMethod.sym; 734 if (m.isConstructor()) { 735 Type outertype = m.owner.owner.type; 736 if (outertype.hasTag(TypeTag.METHOD)) { 737 // we have a local inner class 738 outertype = m.owner.owner.owner.type; 739 } 740 if (outertype.hasTag(TypeTag.CLASS)) { 741 checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type"); 742 checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name"); 743 } else { 744 log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class"); 745 } 746 } else { 747 checkType(tree.vartype, m.owner.type, "incorrect.receiver.type"); 748 checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name"); 749 } 750 } 751 752 public boolean needsLazyConstValue(JCTree tree) { 753 InitTreeVisitor initTreeVisitor = new InitTreeVisitor(); 754 tree.accept(initTreeVisitor); 755 return initTreeVisitor.result; 756 } 757 758 /** Visitor class for expressions which might be constant expressions. 759 */ 760 static class InitTreeVisitor extends JCTree.Visitor { 761 762 private boolean result = true; 763 764 @Override 765 public void visitTree(JCTree tree) {} 766 767 @Override 768 public void visitNewClass(JCNewClass that) { 769 result = false; 770 } 771 772 @Override 773 public void visitNewArray(JCNewArray that) { 774 result = false; 775 } 776 777 @Override 778 public void visitLambda(JCLambda that) { 779 result = false; 780 } 781 782 @Override 783 public void visitReference(JCMemberReference that) { 784 result = false; 785 } 786 787 @Override 788 public void visitApply(JCMethodInvocation that) { 789 result = false; 790 } 791 792 @Override 793 public void visitSelect(JCFieldAccess tree) { 794 tree.selected.accept(this); 795 } 796 797 @Override 798 public void visitConditional(JCConditional tree) { 799 tree.cond.accept(this); 800 tree.truepart.accept(this); 801 tree.falsepart.accept(this); 802 } 803 804 @Override 805 public void visitParens(JCParens tree) { 806 tree.expr.accept(this); 807 } 808 809 @Override 810 public void visitTypeCast(JCTypeCast tree) { 811 tree.expr.accept(this); 812 } 813 } 814 815 /** Create a fresh environment for a variable's initializer. 816 * If the variable is a field, the owner of the environment's scope 817 * is be the variable itself, otherwise the owner is the method 818 * enclosing the variable definition. 819 * 820 * @param tree The variable definition. 821 * @param env The environment current outside of the variable definition. 822 */ 823 Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) { 824 Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup())); 825 if (tree.sym.owner.kind == TYP) { 826 localEnv.info.scope = env.info.scope.dupUnshared(tree.sym); 827 } 828 if ((tree.mods.flags & STATIC) != 0 || 829 ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null)) 830 localEnv.info.staticLevel++; 831 return localEnv; 832 } 833 834 /** Default member enter visitor method: do nothing 835 */ 836 public void visitTree(JCTree tree) { 837 } 838 839 public void visitErroneous(JCErroneous tree) { 840 if (tree.errs != null) 841 memberEnter(tree.errs, env); 842 } 843 844 public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) { 845 Env<AttrContext> mEnv = methodEnv(tree, env); 846 mEnv.info.lint = mEnv.info.lint.augment(tree.sym); 847 for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) 848 mEnv.info.scope.enterIfAbsent(l.head.type.tsym); 849 for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) 850 mEnv.info.scope.enterIfAbsent(l.head.sym); 851 return mEnv; 852 } 853 854 public Env<AttrContext> getInitEnv(JCVariableDecl tree, Env<AttrContext> env) { 855 Env<AttrContext> iEnv = initEnv(tree, env); 856 return iEnv; 857 } 858 859/* ******************************************************************** 860 * Type completion 861 *********************************************************************/ 862 863 Type attribImportType(JCTree tree, Env<AttrContext> env) { 864 Assert.check(completionEnabled); 865 try { 866 // To prevent deep recursion, suppress completion of some 867 // types. 868 completionEnabled = false; 869 return attr.attribType(tree, env); 870 } finally { 871 completionEnabled = true; 872 } 873 } 874 875 /** 876 * Check if a list of annotations contains a reference to 877 * java.lang.Deprecated. 878 **/ 879 private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) { 880 for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) { 881 JCAnnotation a = al.head; 882 if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty()) 883 return true; 884 } 885 return false; 886 } 887 888 /** Queue processing of an attribute default value. */ 889 void annotateDefaultValueLater(final JCExpression defaultValue, 890 final Env<AttrContext> localEnv, 891 final MethodSymbol m, 892 final Annotate.PositionCreator creator) { 893 annotate.normal(new Annotate.Worker() { 894 @Override 895 public String toString() { 896 return "annotate " + m.owner + "." + 897 m + " default " + defaultValue; 898 } 899 900 @Override 901 public void run() { 902 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 903 try { 904 enterDefaultValue(defaultValue, localEnv, m); 905 } finally { 906 log.useSource(prev); 907 } 908 } 909 }); 910 annotate.validate(new Annotate.Worker() { //validate annotations 911 @Override 912 public void run() { 913 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 914 try { 915 // if default value is an annotation, check it is a well-formed 916 // annotation value (e.g. no duplicate values, no missing values, etc.) 917 chk.validateAnnotationTree(defaultValue); 918 } finally { 919 log.useSource(prev); 920 } 921 } 922 }); 923 } 924 925 /** Enter a default value for an attribute method. */ 926 private void enterDefaultValue(final JCExpression defaultValue, 927 final Env<AttrContext> localEnv, 928 final MethodSymbol m) { 929 m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(), 930 defaultValue, 931 localEnv); 932 } 933 934/* ******************************************************************** 935 * Source completer 936 *********************************************************************/ 937 938 /** Complete entering a class. 939 * @param sym The symbol of the class to be completed. 940 */ 941 public void complete(Symbol sym) throws CompletionFailure { 942 // Suppress some (recursive) MemberEnter invocations 943 if (!completionEnabled) { 944 // Re-install same completer for next time around and return. 945 Assert.check((sym.flags() & Flags.COMPOUND) == 0); 946 sym.completer = this; 947 return; 948 } 949 950 ClassSymbol c = (ClassSymbol)sym; 951 ClassType ct = (ClassType)c.type; 952 Env<AttrContext> env = typeEnvs.get(c); 953 JCClassDecl tree = (JCClassDecl)env.tree; 954 boolean wasFirst = isFirst; 955 isFirst = false; 956 957 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 958 DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); 959 try { 960 dependencies.push(c); 961 962 // Save class environment for later member enter (2) processing. 963 halfcompleted.append(env); 964 965 // Mark class as not yet attributed. 966 c.flags_field |= UNATTRIBUTED; 967 968 // If this is a toplevel-class, make sure any preceding import 969 // clauses have been seen. 970 if (c.owner.kind == PCK) { 971 memberEnter(env.toplevel, env.enclosing(TOPLEVEL)); 972 todo.append(env); 973 } 974 975 if (c.owner.kind == TYP) 976 c.owner.complete(); 977 978 // create an environment for evaluating the base clauses 979 Env<AttrContext> baseEnv = baseEnv(tree, env); 980 981 // Annotations. 982 // In general, we cannot fully process annotations yet, but we 983 // can attribute the annotation types and then check to see if the 984 // @Deprecated annotation is present. 985 attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); 986 if (hasDeprecatedAnnotation(tree.mods.annotations)) 987 c.flags_field |= DEPRECATED; 988 989 // Don't attach declaration annotations to anonymous 990 // classes, they get handled specially below. 991 if (!sym.isAnonymous()) { 992 annotate.annotateLater(tree.mods.annotations, baseEnv, 993 c, tree.pos()); 994 } 995 996 // Determine supertype. 997 Type supertype; 998 999 if (tree.extending != null) { 1000 dependencies.push(AttributionKind.EXTENDS, tree.extending); 1001 try { 1002 supertype = attr.attribBase(tree.extending, baseEnv, 1003 true, false, true); 1004 if (sym.isAnonymous()) { 1005 annotate.annotateAnonClassDefLater(tree.extending, 1006 tree.mods.annotations, 1007 baseEnv, sym, tree.pos(), 1008 annotate.extendsCreator); 1009 } else { 1010 annotate.annotateTypeLater(tree.extending, baseEnv, sym, 1011 tree.pos(), annotate.extendsCreator); 1012 } 1013 } finally { 1014 dependencies.pop(); 1015 } 1016 } else { 1017 supertype = ((tree.mods.flags & Flags.ENUM) != 0) 1018 ? attr.attribBase(enumBase(tree.pos, c), baseEnv, 1019 true, false, false) 1020 : (c.fullname == names.java_lang_Object) 1021 ? Type.noType 1022 : syms.objectType; 1023 } 1024 ct.supertype_field = modelMissingTypes(supertype, tree.extending, false); 1025 1026 // Determine interfaces. 1027 ListBuffer<Type> interfaces = new ListBuffer<>(); 1028 ListBuffer<Type> all_interfaces = null; // lazy init 1029 Set<Type> interfaceSet = new HashSet<>(); 1030 List<JCExpression> interfaceTrees = tree.implementing; 1031 int i = 0; 1032 for (JCExpression iface : interfaceTrees) { 1033 dependencies.push(AttributionKind.IMPLEMENTS, iface); 1034 try { 1035 Type it = attr.attribBase(iface, baseEnv, false, true, true); 1036 if (it.hasTag(CLASS)) { 1037 interfaces.append(it); 1038 if (all_interfaces != null) all_interfaces.append(it); 1039 chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet); 1040 } else { 1041 if (all_interfaces == null) 1042 all_interfaces = new ListBuffer<Type>().appendList(interfaces); 1043 all_interfaces.append(modelMissingTypes(it, iface, true)); 1044 1045 } 1046 if (sym.isAnonymous()) { 1047 // Note: if an anonymous class ever has more than 1048 // one supertype for some reason, this will 1049 // incorrectly attach tree.mods.annotations to ALL 1050 // supertypes, not just the first. 1051 annotate.annotateAnonClassDefLater(iface, tree.mods.annotations, 1052 baseEnv, sym, tree.pos(), 1053 annotate.implementsCreator(i++)); 1054 } else { 1055 annotate.annotateTypeLater(iface, baseEnv, sym, tree.pos(), 1056 annotate.implementsCreator(i++)); 1057 } 1058 } finally { 1059 dependencies.pop(); 1060 } 1061 } 1062 1063 if ((c.flags_field & ANNOTATION) != 0) { 1064 ct.interfaces_field = List.of(syms.annotationType); 1065 ct.all_interfaces_field = ct.interfaces_field; 1066 } else { 1067 ct.interfaces_field = interfaces.toList(); 1068 ct.all_interfaces_field = (all_interfaces == null) 1069 ? ct.interfaces_field : all_interfaces.toList(); 1070 } 1071 1072 if (c.fullname == names.java_lang_Object) { 1073 if (tree.extending != null) { 1074 chk.checkNonCyclic(tree.extending.pos(), 1075 supertype); 1076 ct.supertype_field = Type.noType; 1077 } 1078 else if (tree.implementing.nonEmpty()) { 1079 chk.checkNonCyclic(tree.implementing.head.pos(), 1080 ct.interfaces_field.head); 1081 ct.interfaces_field = List.nil(); 1082 } 1083 } 1084 1085 // class type parameters use baseEnv but everything uses env 1086 1087 chk.checkNonCyclicDecl(tree); 1088 1089 attr.attribTypeVariables(tree.typarams, baseEnv); 1090 // Do this here, where we have the symbol. 1091 int j = 0; 1092 for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); 1093 l = l.tail, j++) { 1094 final JCTypeParameter typaram = l.head; 1095 annotate.annotateTypeLater(typaram, baseEnv, sym, tree.pos(), 1096 annotate.typeParamCreator(j)); 1097 1098 int k = 0; 1099 for(List<JCExpression> b = typaram.bounds; b.nonEmpty(); 1100 b = b.tail, k++) { 1101 final JCExpression bound = b.head; 1102 annotate.annotateTypeLater(bound, baseEnv, sym, tree.pos(), 1103 annotate.typeParamBoundCreator(typaram, j, k)); 1104 } 1105 1106 } 1107 1108 // Add default constructor if needed. 1109 if ((c.flags() & INTERFACE) == 0 && 1110 !TreeInfo.hasConstructors(tree.defs)) { 1111 List<Type> argtypes = List.nil(); 1112 List<Type> typarams = List.nil(); 1113 List<Type> thrown = List.nil(); 1114 long ctorFlags = 0; 1115 boolean based = false; 1116 boolean addConstructor = true; 1117 JCNewClass nc = null; 1118 if (c.name.isEmpty()) { 1119 nc = (JCNewClass)env.next.tree; 1120 if (nc.constructor != null) { 1121 addConstructor = nc.constructor.kind != ERR; 1122 Type superConstrType = types.memberType(c.type, 1123 nc.constructor); 1124 argtypes = superConstrType.getParameterTypes(); 1125 typarams = superConstrType.getTypeArguments(); 1126 ctorFlags = nc.constructor.flags() & VARARGS; 1127 if (nc.encl != null) { 1128 argtypes = argtypes.prepend(nc.encl.type); 1129 based = true; 1130 } 1131 thrown = superConstrType.getThrownTypes(); 1132 } 1133 } 1134 if (addConstructor) { 1135 MethodSymbol basedConstructor = nc != null ? 1136 (MethodSymbol)nc.constructor : null; 1137 JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, 1138 basedConstructor, 1139 typarams, argtypes, thrown, 1140 ctorFlags, based); 1141 tree.defs = tree.defs.prepend(constrDef); 1142 } 1143 } 1144 1145 // enter symbols for 'this' into current scope. 1146 VarSymbol thisSym = 1147 new VarSymbol(FINAL | HASINIT, names._this, c.type, c); 1148 thisSym.pos = Position.FIRSTPOS; 1149 env.info.scope.enter(thisSym); 1150 // if this is a class, enter symbol for 'super' into current scope. 1151 if ((c.flags_field & INTERFACE) == 0 && 1152 ct.supertype_field.hasTag(CLASS)) { 1153 VarSymbol superSym = 1154 new VarSymbol(FINAL | HASINIT, names._super, 1155 ct.supertype_field, c); 1156 superSym.pos = Position.FIRSTPOS; 1157 env.info.scope.enter(superSym); 1158 } 1159 1160 // check that no package exists with same fully qualified name, 1161 // but admit classes in the unnamed package which have the same 1162 // name as a top-level package. 1163 if (checkClash && 1164 c.owner.kind == PCK && c.owner != syms.unnamedPackage && 1165 syms.packageExists(c.fullname)) { 1166 log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c); 1167 } 1168 if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && 1169 !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) { 1170 c.flags_field |= AUXILIARY; 1171 } 1172 } catch (CompletionFailure ex) { 1173 chk.completionError(tree.pos(), ex); 1174 } finally { 1175 deferredLintHandler.setPos(prevLintPos); 1176 log.useSource(prev); 1177 dependencies.pop(); 1178 } 1179 1180 // Enter all member fields and methods of a set of half completed 1181 // classes in a second phase. 1182 if (wasFirst) { 1183 Set<JCCompilationUnit> topLevels = new HashSet<>(); 1184 try { 1185 while (halfcompleted.nonEmpty()) { 1186 Env<AttrContext> toFinish = halfcompleted.next(); 1187 topLevels.add(toFinish.toplevel); 1188 finish(toFinish); 1189 } 1190 } finally { 1191 isFirst = true; 1192 } 1193 1194 for (JCCompilationUnit toplevel : topLevels) { 1195 chk.checkImportsResolvable(toplevel); 1196 } 1197 1198 } 1199 } 1200 1201 private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) { 1202 WriteableScope baseScope = WriteableScope.create(tree.sym); 1203 //import already entered local classes into base scope 1204 for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) { 1205 if (sym.isLocal()) { 1206 baseScope.enter(sym); 1207 } 1208 } 1209 //import current type-parameters into base scope 1210 if (tree.typarams != null) 1211 for (List<JCTypeParameter> typarams = tree.typarams; 1212 typarams.nonEmpty(); 1213 typarams = typarams.tail) 1214 baseScope.enter(typarams.head.type.tsym); 1215 Env<AttrContext> outer = env.outer; // the base clause can't see members of this class 1216 Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope)); 1217 localEnv.baseClause = true; 1218 localEnv.outer = outer; 1219 localEnv.info.isSelfCall = false; 1220 return localEnv; 1221 } 1222 1223 /** Enter member fields and methods of a class 1224 * @param env the environment current for the class block. 1225 */ 1226 private void finish(Env<AttrContext> env) { 1227 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 1228 try { 1229 JCClassDecl tree = (JCClassDecl)env.tree; 1230 finishClass(tree, env); 1231 } finally { 1232 log.useSource(prev); 1233 } 1234 } 1235 1236 /** Generate a base clause for an enum type. 1237 * @param pos The position for trees and diagnostics, if any 1238 * @param c The class symbol of the enum 1239 */ 1240 private JCExpression enumBase(int pos, ClassSymbol c) { 1241 JCExpression result = make.at(pos). 1242 TypeApply(make.QualIdent(syms.enumSym), 1243 List.<JCExpression>of(make.Type(c.type))); 1244 return result; 1245 } 1246 1247 Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) { 1248 if (!t.hasTag(ERROR)) 1249 return t; 1250 1251 return new ErrorType(t.getOriginalType(), t.tsym) { 1252 private Type modelType; 1253 1254 @Override 1255 public Type getModelType() { 1256 if (modelType == null) 1257 modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree); 1258 return modelType; 1259 } 1260 }; 1261 } 1262 // where 1263 private class Synthesizer extends JCTree.Visitor { 1264 Type originalType; 1265 boolean interfaceExpected; 1266 List<ClassSymbol> synthesizedSymbols = List.nil(); 1267 Type result; 1268 1269 Synthesizer(Type originalType, boolean interfaceExpected) { 1270 this.originalType = originalType; 1271 this.interfaceExpected = interfaceExpected; 1272 } 1273 1274 Type visit(JCTree tree) { 1275 tree.accept(this); 1276 return result; 1277 } 1278 1279 List<Type> visit(List<? extends JCTree> trees) { 1280 ListBuffer<Type> lb = new ListBuffer<>(); 1281 for (JCTree t: trees) 1282 lb.append(visit(t)); 1283 return lb.toList(); 1284 } 1285 1286 @Override 1287 public void visitTree(JCTree tree) { 1288 result = syms.errType; 1289 } 1290 1291 @Override 1292 public void visitIdent(JCIdent tree) { 1293 if (!tree.type.hasTag(ERROR)) { 1294 result = tree.type; 1295 } else { 1296 result = synthesizeClass(tree.name, syms.unnamedPackage).type; 1297 } 1298 } 1299 1300 @Override 1301 public void visitSelect(JCFieldAccess tree) { 1302 if (!tree.type.hasTag(ERROR)) { 1303 result = tree.type; 1304 } else { 1305 Type selectedType; 1306 boolean prev = interfaceExpected; 1307 try { 1308 interfaceExpected = false; 1309 selectedType = visit(tree.selected); 1310 } finally { 1311 interfaceExpected = prev; 1312 } 1313 ClassSymbol c = synthesizeClass(tree.name, selectedType.tsym); 1314 result = c.type; 1315 } 1316 } 1317 1318 @Override 1319 public void visitTypeApply(JCTypeApply tree) { 1320 if (!tree.type.hasTag(ERROR)) { 1321 result = tree.type; 1322 } else { 1323 ClassType clazzType = (ClassType) visit(tree.clazz); 1324 if (synthesizedSymbols.contains(clazzType.tsym)) 1325 synthesizeTyparams((ClassSymbol) clazzType.tsym, tree.arguments.size()); 1326 final List<Type> actuals = visit(tree.arguments); 1327 result = new ErrorType(tree.type, clazzType.tsym) { 1328 @Override 1329 public List<Type> getTypeArguments() { 1330 return actuals; 1331 } 1332 }; 1333 } 1334 } 1335 1336 ClassSymbol synthesizeClass(Name name, Symbol owner) { 1337 int flags = interfaceExpected ? INTERFACE : 0; 1338 ClassSymbol c = new ClassSymbol(flags, name, owner); 1339 c.members_field = new Scope.ErrorScope(c); 1340 c.type = new ErrorType(originalType, c) { 1341 @Override 1342 public List<Type> getTypeArguments() { 1343 return typarams_field; 1344 } 1345 }; 1346 synthesizedSymbols = synthesizedSymbols.prepend(c); 1347 return c; 1348 } 1349 1350 void synthesizeTyparams(ClassSymbol sym, int n) { 1351 ClassType ct = (ClassType) sym.type; 1352 Assert.check(ct.typarams_field.isEmpty()); 1353 if (n == 1) { 1354 TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType, 1355 Type.noAnnotations); 1356 ct.typarams_field = ct.typarams_field.prepend(v); 1357 } else { 1358 for (int i = n; i > 0; i--) { 1359 TypeVar v = new TypeVar(names.fromString("T" + i), sym, 1360 syms.botType, Type.noAnnotations); 1361 ct.typarams_field = ct.typarams_field.prepend(v); 1362 } 1363 } 1364 } 1365 } 1366 1367 1368/* *************************************************************************** 1369 * tree building 1370 ****************************************************************************/ 1371 1372 /** Generate default constructor for given class. For classes different 1373 * from java.lang.Object, this is: 1374 * 1375 * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown { 1376 * super(x_0, ..., x_n) 1377 * } 1378 * 1379 * or, if based == true: 1380 * 1381 * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown { 1382 * x_0.super(x_1, ..., x_n) 1383 * } 1384 * 1385 * @param make The tree factory. 1386 * @param c The class owning the default constructor. 1387 * @param argtypes The parameter types of the constructor. 1388 * @param thrown The thrown exceptions of the constructor. 1389 * @param based Is first parameter a this$n? 1390 */ 1391 JCTree DefaultConstructor(TreeMaker make, 1392 ClassSymbol c, 1393 MethodSymbol baseInit, 1394 List<Type> typarams, 1395 List<Type> argtypes, 1396 List<Type> thrown, 1397 long flags, 1398 boolean based) { 1399 JCTree result; 1400 if ((c.flags() & ENUM) != 0 && 1401 (types.supertype(c.type).tsym == syms.enumSym)) { 1402 // constructors of true enums are private 1403 flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR; 1404 } else 1405 flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR; 1406 if (c.name.isEmpty()) { 1407 flags |= ANONCONSTR; 1408 } 1409 Type mType = new MethodType(argtypes, null, thrown, c); 1410 Type initType = typarams.nonEmpty() ? 1411 new ForAll(typarams, mType) : 1412 mType; 1413 MethodSymbol init = new MethodSymbol(flags, names.init, 1414 initType, c); 1415 init.params = createDefaultConstructorParams(make, baseInit, init, 1416 argtypes, based); 1417 List<JCVariableDecl> params = make.Params(argtypes, init); 1418 List<JCStatement> stats = List.nil(); 1419 if (c.type != syms.objectType) { 1420 stats = stats.prepend(SuperCall(make, typarams, params, based)); 1421 } 1422 result = make.MethodDef(init, make.Block(0, stats)); 1423 return result; 1424 } 1425 1426 private List<VarSymbol> createDefaultConstructorParams( 1427 TreeMaker make, 1428 MethodSymbol baseInit, 1429 MethodSymbol init, 1430 List<Type> argtypes, 1431 boolean based) { 1432 List<VarSymbol> initParams = null; 1433 List<Type> argTypesList = argtypes; 1434 if (based) { 1435 /* In this case argtypes will have an extra type, compared to baseInit, 1436 * corresponding to the type of the enclosing instance i.e.: 1437 * 1438 * Inner i = outer.new Inner(1){} 1439 * 1440 * in the above example argtypes will be (Outer, int) and baseInit 1441 * will have parameter's types (int). So in this case we have to add 1442 * first the extra type in argtypes and then get the names of the 1443 * parameters from baseInit. 1444 */ 1445 initParams = List.nil(); 1446 VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init); 1447 initParams = initParams.append(param); 1448 argTypesList = argTypesList.tail; 1449 } 1450 if (baseInit != null && baseInit.params != null && 1451 baseInit.params.nonEmpty() && argTypesList.nonEmpty()) { 1452 initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams; 1453 List<VarSymbol> baseInitParams = baseInit.params; 1454 while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) { 1455 VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER, 1456 baseInitParams.head.name, argTypesList.head, init); 1457 initParams = initParams.append(param); 1458 baseInitParams = baseInitParams.tail; 1459 argTypesList = argTypesList.tail; 1460 } 1461 } 1462 return initParams; 1463 } 1464 1465 /** Generate call to superclass constructor. This is: 1466 * 1467 * super(id_0, ..., id_n) 1468 * 1469 * or, if based == true 1470 * 1471 * id_0.super(id_1,...,id_n) 1472 * 1473 * where id_0, ..., id_n are the names of the given parameters. 1474 * 1475 * @param make The tree factory 1476 * @param params The parameters that need to be passed to super 1477 * @param typarams The type parameters that need to be passed to super 1478 * @param based Is first parameter a this$n? 1479 */ 1480 JCExpressionStatement SuperCall(TreeMaker make, 1481 List<Type> typarams, 1482 List<JCVariableDecl> params, 1483 boolean based) { 1484 JCExpression meth; 1485 if (based) { 1486 meth = make.Select(make.Ident(params.head), names._super); 1487 params = params.tail; 1488 } else { 1489 meth = make.Ident(names._super); 1490 } 1491 List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null; 1492 return make.Exec(make.Apply(typeargs, meth, make.Idents(params))); 1493 } 1494} 1495