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