memberenter.java
来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,108 行 · 第 1/3 页
JAVA
1,108 行
return false; } /** Enter a set of annotations. */ private void enterAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env, Symbol s) { ListBuffer<Attribute.Compound> buf = new ListBuffer<Attribute.Compound>(); Set<TypeSymbol> annotated = new HashSet<TypeSymbol>(); if (!skipAnnotations) for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) { JCAnnotation a = al.head; Attribute.Compound c = annotate.enterAnnotation(a, syms.annotationType, env); if (c == null) continue; buf.append(c); // Note: @Deprecated has no effect on local variables and parameters if (!c.type.isErroneous() && s.owner.kind != MTH && types.isSameType(c.type, syms.deprecatedType)) s.flags_field |= Flags.DEPRECATED; if (!annotated.add(a.type.tsym)) log.error(a.pos, "duplicate.annotation"); } s.attributes_field = buf.toList(); } /** Queue processing of an attribute default value. */ void annotateDefaultValueLater(final JCExpression defaultValue, final Env<AttrContext> localEnv, final MethodSymbol m) { annotate.later(new Annotate.Annotator() { public String toString() { return "annotate " + m.owner + "." + m + " default " + defaultValue; } public void enterAnnotation() { JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); try { enterDefaultValue(defaultValue, localEnv, m); } finally { log.useSource(prev); } } }); } /** Enter a default value for an attribute method. */ private void enterDefaultValue(final JCExpression defaultValue, final Env<AttrContext> localEnv, final MethodSymbol m) { m.defaultValue = annotate.enterAttributeValue(m.type.getReturnType(), defaultValue, localEnv); }/* ******************************************************************** * Source completer *********************************************************************/ /** Complete entering a class. * @param sym The symbol of the class to be completed. */ public void complete(Symbol sym) throws CompletionFailure { // Suppress some (recursive) MemberEnter invocations if (!completionEnabled) { // Re-install same completer for next time around and return. assert (sym.flags() & Flags.COMPOUND) == 0; sym.completer = this; return; } ClassSymbol c = (ClassSymbol)sym; ClassType ct = (ClassType)c.type; Env<AttrContext> env = enter.typeEnvs.get(c); JCClassDecl tree = (JCClassDecl)env.tree; boolean wasFirst = isFirst; isFirst = false; JavaFileObject prev = log.useSource(env.toplevel.sourcefile); try { // Save class environment for later member enter (2) processing. halfcompleted.append(env); // If this is a toplevel-class, make sure any preceding import // clauses have been seen. if (c.owner.kind == PCK) { memberEnter(env.toplevel, env.enclosing(JCTree.TOPLEVEL)); todo.append(env); } // Mark class as not yet attributed. c.flags_field |= UNATTRIBUTED; if (c.owner.kind == TYP) c.owner.complete(); // create an environment for evaluating the base clauses Env<AttrContext> baseEnv = baseEnv(tree, env); // Determine supertype. Type supertype = (tree.extending != null) ? attr.attribBase(tree.extending, baseEnv, true, false, true) : ((tree.mods.flags & Flags.ENUM) != 0 && !target.compilerBootstrap(c)) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, true, false, false) : (c.fullname == names.java_lang_Object) ? Type.noType : syms.objectType; ct.supertype_field = supertype; // Determine interfaces. ListBuffer<Type> interfaces = new ListBuffer<Type>(); Set<Type> interfaceSet = new HashSet<Type>(); List<JCExpression> interfaceTrees = tree.implementing; if ((tree.mods.flags & Flags.ENUM) != 0 && target.compilerBootstrap(c)) { // add interface Comparable<T> interfaceTrees = interfaceTrees.prepend(make.Type(new ClassType(syms.comparableType.getEnclosingType(), List.of(c.type), syms.comparableType.tsym))); // add interface Serializable interfaceTrees = interfaceTrees.prepend(make.Type(syms.serializableType)); } for (JCExpression iface : interfaceTrees) { Type i = attr.attribBase(iface, baseEnv, false, true, true); if (i.tag == CLASS) { interfaces.append(i); chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet); } } if ((c.flags_field & ANNOTATION) != 0) ct.interfaces_field = List.of(syms.annotationType); else ct.interfaces_field = interfaces.toList(); if (c.fullname == names.java_lang_Object) { if (tree.extending != null) { chk.checkNonCyclic(tree.extending.pos(), supertype); ct.supertype_field = Type.noType; } else if (tree.implementing.nonEmpty()) { chk.checkNonCyclic(tree.implementing.head.pos(), ct.interfaces_field.head); ct.interfaces_field = List.nil(); } } // Annotations. // In general, we cannot fully process annotations yet, but we // can attribute the annotation types and then check to see if the // @Deprecated annotation is present. attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); if (hasDeprecatedAnnotation(tree.mods.annotations)) c.flags_field |= DEPRECATED; annotateLater(tree.mods.annotations, baseEnv, c); attr.attribTypeVariables(tree.typarams, baseEnv); chk.checkNonCyclic(tree.pos(), c.type); // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && !TreeInfo.hasConstructors(tree.defs)) { List<Type> argtypes = List.nil(); List<Type> typarams = List.nil(); List<Type> thrown = List.nil(); long ctorFlags = 0; boolean based = false; if (c.name.len == 0) { JCNewClass nc = (JCNewClass)env.next.tree; if (nc.constructor != null) { Type superConstrType = types.memberType(c.type, nc.constructor); argtypes = superConstrType.getParameterTypes(); typarams = superConstrType.getTypeArguments(); ctorFlags = nc.constructor.flags() & VARARGS; if (nc.encl != null) { argtypes = argtypes.prepend(nc.encl.type); based = true; } thrown = superConstrType.getThrownTypes(); } } JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, typarams, argtypes, thrown, ctorFlags, based); tree.defs = tree.defs.prepend(constrDef); } // If this is a class, enter symbols for this and super into // current scope. if ((c.flags_field & INTERFACE) == 0) { VarSymbol thisSym = new VarSymbol(FINAL | HASINIT, names._this, c.type, c); thisSym.pos = Position.FIRSTPOS; env.info.scope.enter(thisSym); if (ct.supertype_field.tag == CLASS) { VarSymbol superSym = new VarSymbol(FINAL | HASINIT, names._super, ct.supertype_field, c); superSym.pos = Position.FIRSTPOS; env.info.scope.enter(superSym); } } // check that no package exists with same fully qualified name, // but admit classes in the unnamed package which have the same // name as a top-level package. if (checkClash && c.owner.kind == PCK && c.owner != syms.unnamedPackage && reader.packageExists(c.fullname)) { log.error(tree.pos, "clash.with.pkg.of.same.name", c); } } catch (CompletionFailure ex) { chk.completionError(tree.pos(), ex); } finally { log.useSource(prev); } // Enter all member fields and methods of a set of half completed // classes in a second phase. if (wasFirst) { try { while (halfcompleted.nonEmpty()) { finish(halfcompleted.next()); } } finally { isFirst = true; } // commit pending annotations annotate.flush(); } } private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) { Scope typaramScope = new Scope(tree.sym); if (tree.typarams != null) for (List<JCTypeParameter> typarams = tree.typarams; typarams.nonEmpty(); typarams = typarams.tail) typaramScope.enter(typarams.head.type.tsym); Env<AttrContext> outer = env.outer; // the base clause can't see members of this class Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(typaramScope)); localEnv.baseClause = true; localEnv.outer = outer; localEnv.info.isSelfCall = false; return localEnv; } /** Enter member fields and methods of a class * @param env the environment current for the class block. */ private void finish(Env<AttrContext> env) { JavaFileObject prev = log.useSource(env.toplevel.sourcefile); try { JCClassDecl tree = (JCClassDecl)env.tree; finishClass(tree, env); } finally { log.useSource(prev); } } /** Generate a base clause for an enum type. * @param pos The position for trees and diagnostics, if any * @param c The class symbol of the enum */ private JCExpression enumBase(int pos, ClassSymbol c) { JCExpression result = make.at(pos). TypeApply(make.QualIdent(syms.enumSym), List.<JCExpression>of(make.Type(c.type))); return result; }/* *************************************************************************** * tree building ****************************************************************************/ /** Generate default constructor for given class. For classes different * from java.lang.Object, this is: * * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown { * super(x_0, ..., x_n) * } * * or, if based == true: * * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown { * x_0.super(x_1, ..., x_n) * } * * @param make The tree factory. * @param c The class owning the default constructor. * @param argtypes The parameter types of the constructor. * @param thrown The thrown exceptions of the constructor. * @param based Is first parameter a this$n? */ JCTree DefaultConstructor(TreeMaker make, ClassSymbol c, List<Type> typarams, List<Type> argtypes, List<Type> thrown, long flags, boolean based) { List<JCVariableDecl> params = make.Params(argtypes, syms.noSymbol); List<JCStatement> stats = List.nil(); if (c.type != syms.objectType) stats = stats.prepend(SuperCall(make, typarams, params, based)); if ((c.flags() & ENUM) != 0 && (types.supertype(c.type).tsym == syms.enumSym || target.compilerBootstrap(c))) { // constructors of true enums are private flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR; } else flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR; if (c.name.len == 0) flags |= ANONCONSTR; JCTree result = make.MethodDef( make.Modifiers(flags), names.init, null, make.TypeParams(typarams), params, make.Types(thrown), make.Block(0, stats), null); return result; } /** Generate call to superclass constructor. This is: * * super(id_0, ..., id_n) * * or, if based == true * * id_0.super(id_1,...,id_n) * * where id_0, ..., id_n are the names of the given parameters. * * @param make The tree factory * @param params The parameters that need to be passed to super * @param typarams The type parameters that need to be passed to super * @param based Is first parameter a this$n? */ JCExpressionStatement SuperCall(TreeMaker make, List<Type> typarams, List<JCVariableDecl> params, boolean based) { JCExpression meth; if (based) { meth = make.Select(make.Ident(params.head), names._super); params = params.tail; } else { meth = make.Ident(names._super); } List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null; return make.Exec(make.Apply(typeargs, meth, make.Idents(params))); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?