attr.java
来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,568 行 · 第 1/5 页
JAVA
1,568 行
/* * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.comp;import java.util.*;import java.util.Set;import javax.lang.model.element.ElementKind;import javax.tools.JavaFileObject;import com.sun.tools.javac.code.*;import com.sun.tools.javac.jvm.*;import com.sun.tools.javac.tree.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;import com.sun.tools.javac.util.List;import com.sun.tools.javac.jvm.Target;import com.sun.tools.javac.code.Symbol.*;import com.sun.tools.javac.tree.JCTree.*;import com.sun.tools.javac.code.Type.*;import com.sun.source.tree.IdentifierTree;import com.sun.source.tree.MemberSelectTree;import com.sun.source.tree.TreeVisitor;import com.sun.source.util.SimpleTreeVisitor;import static com.sun.tools.javac.code.Flags.*;import static com.sun.tools.javac.code.Kinds.*;import static com.sun.tools.javac.code.TypeTags.*;/** This is the main context-dependent analysis phase in GJC. It * encompasses name resolution, type checking and constant folding as * subtasks. Some subtasks involve auxiliary classes. * @see Check * @see Resolve * @see ConstFold * @see Infer * * <p><b>This is NOT part of any API supported by Sun Microsystems. If * you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice.</b> */public class Attr extends JCTree.Visitor { protected static final Context.Key<Attr> attrKey = new Context.Key<Attr>(); final Name.Table names; final Log log; final Symtab syms; final Resolve rs; final Check chk; final MemberEnter memberEnter; final TreeMaker make; final ConstFold cfolder; final Enter enter; final Target target; final Types types; final Annotate annotate; public static Attr instance(Context context) { Attr instance = context.get(attrKey); if (instance == null) instance = new Attr(context); return instance; } protected Attr(Context context) { context.put(attrKey, this); names = Name.Table.instance(context); log = Log.instance(context); syms = Symtab.instance(context); rs = Resolve.instance(context); chk = Check.instance(context); memberEnter = MemberEnter.instance(context); make = TreeMaker.instance(context); enter = Enter.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); types = Types.instance(context); annotate = Annotate.instance(context); Options options = Options.instance(context); Source source = Source.instance(context); allowGenerics = source.allowGenerics(); allowVarargs = source.allowVarargs(); allowEnums = source.allowEnums(); allowBoxing = source.allowBoxing(); allowCovariantReturns = source.allowCovariantReturns(); allowAnonOuterThis = source.allowAnonOuterThis(); relax = (options.get("-retrofit") != null || options.get("-relax") != null); useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; } /** Switch: relax some constraints for retrofit mode. */ boolean relax; /** Switch: support generics? */ boolean allowGenerics; /** Switch: allow variable-arity methods. */ boolean allowVarargs; /** Switch: support enums? */ boolean allowEnums; /** Switch: support boxing and unboxing? */ boolean allowBoxing; /** Switch: support covariant result types? */ boolean allowCovariantReturns; /** Switch: allow references to surrounding object from anonymous * objects during constructor call? */ boolean allowAnonOuterThis; /** * Switch: warn about use of variable before declaration? * RFE: 6425594 */ boolean useBeforeDeclarationWarning; /** Check kind and type of given tree against protokind and prototype. * If check succeeds, store type in tree and return it. * If check fails, store errType in tree and return it. * No checks are performed if the prototype is a method type. * Its not necessary in this case since we know that kind and type * are correct. * * @param tree The tree whose kind and type is checked * @param owntype The computed type of the tree * @param ownkind The computed kind of the tree * @param pkind The expected kind (or: protokind) of the tree * @param pt The expected type (or: prototype) of the tree */ Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) { if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) { if ((ownkind & ~pkind) == 0) { owntype = chk.checkType(tree.pos(), owntype, pt); } else { log.error(tree.pos(), "unexpected.type", Resolve.kindNames(pkind), Resolve.kindName(ownkind)); owntype = syms.errType; } } tree.type = owntype; return owntype; } /** Is given blank final variable assignable, i.e. in a scope where it * may be assigned to even though it is final? * @param v The blank final variable. * @param env The current environment. */ boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) { Symbol owner = env.info.scope.owner; // owner refers to the innermost variable, method or // initializer block declaration at this point. return v.owner == owner || ((owner.name == names.init || // i.e. we are in a constructor owner.kind == VAR || // i.e. we are in a variable initializer (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block && v.owner == owner.owner && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env)); } /** Check that variable can be assigned to. * @param pos The current source code position. * @param v The assigned varaible * @param base If the variable is referred to in a Select, the part * to the left of the `.', null otherwise. * @param env The current environment. */ void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) { if ((v.flags() & FINAL) != 0 && ((v.flags() & HASINIT) != 0 || !((base == null || (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) && isAssignableAsBlankFinal(v, env)))) { log.error(pos, "cant.assign.val.to.final.var", v); } } /** Does tree represent a static reference to an identifier? * It is assumed that tree is either a SELECT or an IDENT. * We have to weed out selects from non-type names here. * @param tree The candidate tree. */ boolean isStaticReference(JCTree tree) { if (tree.getTag() == JCTree.SELECT) { Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected); if (lsym == null || lsym.kind != TYP) { return false; } } return true; } /** Is this symbol a type? */ static boolean isType(Symbol sym) { return sym != null && sym.kind == TYP; } /** The current `this' symbol. * @param env The current environment. */ Symbol thisSym(DiagnosticPosition pos, Env<AttrContext> env) { return rs.resolveSelf(pos, env, env.enclClass.sym, names._this); } /** Attribute a parsed identifier. * @param tree Parsed identifier name * @param topLevel The toplevel to use */ public Symbol attribIdent(JCTree tree, JCCompilationUnit topLevel) { Env<AttrContext> localEnv = enter.topLevelEnv(topLevel); localEnv.enclClass = make.ClassDef(make.Modifiers(0), syms.errSymbol.name, null, null, null, null); localEnv.enclClass.sym = syms.errSymbol; return tree.accept(identAttributer, localEnv); } // where private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer(); private class IdentAttributer extends SimpleTreeVisitor<Symbol,Env<AttrContext>> { @Override public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) { Symbol site = visit(node.getExpression(), env); if (site.kind == ERR) return site; Name name = (Name)node.getIdentifier(); if (site.kind == PCK) { env.toplevel.packge = (PackageSymbol)site; return rs.findIdentInPackage(env, (TypeSymbol)site, name, TYP | PCK); } else { env.enclClass.sym = (ClassSymbol)site; return rs.findMemberType(env, site.asType(), name, (TypeSymbol)site); } } @Override public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) { return rs.findIdent(env, (Name)node.getName(), TYP | PCK); } } public Type coerce(Type etype, Type ttype) { return cfolder.coerce(etype, ttype); } public Type attribType(JCTree node, TypeSymbol sym) { Env<AttrContext> env = enter.typeEnvs.get(sym); Env<AttrContext> localEnv = env.dup(node, env.info.dup()); return attribTree(node, localEnv, Kinds.TYP, Type.noType); } public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) { breakTree = tree; JavaFileObject prev = log.useSource(null); try { attribExpr(expr, env); } catch (BreakAttr b) { return b.env; } finally { breakTree = null; log.useSource(prev); } return env; } public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) { breakTree = tree; JavaFileObject prev = log.useSource(null); try {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?