⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lower.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     */    class EnumMapping {        EnumMapping(DiagnosticPosition pos, TypeSymbol forEnum) {            this.forEnum = forEnum;            this.values = new LinkedHashMap<VarSymbol,Integer>();            this.pos = pos;            Name varName = names                .fromString(target.syntheticNameChar() +                            "SwitchMap" +                            target.syntheticNameChar() +                            writer.xClassName(forEnum.type).toString()                            .replace('/', '.')                            .replace('.', target.syntheticNameChar()));            ClassSymbol outerCacheClass = outerCacheClass();            this.mapVar = new VarSymbol(STATIC | SYNTHETIC | FINAL,                                        varName,                                        new ArrayType(syms.intType, syms.arrayClass),                                        outerCacheClass);            enterSynthetic(pos, mapVar, outerCacheClass.members());        }        DiagnosticPosition pos = null;        // the next value to use        int next = 1; // 0 (unused map elements) go to the default label        // the enum for which this is a map        final TypeSymbol forEnum;        // the field containing the map        final VarSymbol mapVar;        // the mapped values        final Map<VarSymbol,Integer> values;        JCLiteral forConstant(VarSymbol v) {            Integer result = values.get(v);            if (result == null)                values.put(v, result = next++);            return make.Literal(result);        }        // generate the field initializer for the map        void translate() {            make.at(pos.getStartPosition());            JCClassDecl owner = classDef((ClassSymbol)mapVar.owner);            // synthetic static final int[] $SwitchMap$Color = new int[Color.values().length];            MethodSymbol valuesMethod = lookupMethod(pos,                                                     names.values,                                                     forEnum.type,                                                     List.<Type>nil());            JCExpression size = make // Color.values().length                .Select(make.App(make.QualIdent(valuesMethod)),                        syms.lengthVar);            JCExpression mapVarInit = make                .NewArray(make.Type(syms.intType), List.of(size), null)                .setType(new ArrayType(syms.intType, syms.arrayClass));            // try { $SwitchMap$Color[red.ordinal()] = 1; } catch (java.lang.NoSuchFieldError ex) {}            ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();            Symbol ordinalMethod = lookupMethod(pos,                                                names.ordinal,                                                forEnum.type,                                                List.<Type>nil());            List<JCCatch> catcher = List.<JCCatch>nil()                .prepend(make.Catch(make.VarDef(new VarSymbol(PARAMETER, names.ex,                                                              syms.noSuchFieldErrorType,                                                              syms.noSymbol),                                                null),                                    make.Block(0, List.<JCStatement>nil())));            for (Map.Entry<VarSymbol,Integer> e : values.entrySet()) {                VarSymbol enumerator = e.getKey();                Integer mappedValue = e.getValue();                JCExpression assign = make                    .Assign(make.Indexed(mapVar,                                         make.App(make.Select(make.QualIdent(enumerator),                                                              ordinalMethod))),                            make.Literal(mappedValue))                    .setType(syms.intType);                JCStatement exec = make.Exec(assign);                JCStatement _try = make.Try(make.Block(0, List.of(exec)), catcher, null);                stmts.append(_try);            }            owner.defs = owner.defs                .prepend(make.Block(STATIC, stmts.toList()))                .prepend(make.VarDef(mapVar, mapVarInit));        }    }/************************************************************************** * Tree building blocks *************************************************************************/      /** Equivalent to make.at(pos.getStartPosition()) with side effect of caching     *  pos as make_pos, for use in diagnostics.     **/    TreeMaker make_at(DiagnosticPosition pos) {        make_pos = pos;        return make.at(pos);    }    /** Make an attributed tree representing a literal. This will be an     *  Ident node in the case of boolean literals, a Literal node in all     *  other cases.     *  @param type       The literal's type.     *  @param value      The literal's value.     */    JCExpression makeLit(Type type, Object value) {	return make.Literal(type.tag, value).setType(type.constType(value));    }        /** Make an attributed tree representing null.     */    JCExpression makeNull() {        return makeLit(syms.botType, null);    }    /** Make an attributed class instance creation expression.     *  @param ctype    The class type.     *  @param args     The constructor arguments.     */    JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {	JCNewClass tree = make.NewClass(null,	    null, make.QualIdent(ctype.tsym), args, null);	tree.constructor = rs.resolveConstructor(	    make_pos, attrEnv, ctype, TreeInfo.types(args), null, false, false);	tree.type = ctype;	return tree;    }    /** Make an attributed unary expression.     *  @param optag    The operators tree tag.     *  @param arg      The operator's argument.     */    JCUnary makeUnary(int optag, JCExpression arg) {	JCUnary tree = make.Unary(optag, arg);	tree.operator = rs.resolveUnaryOperator(	    make_pos, optag, attrEnv, arg.type);	tree.type = tree.operator.type.getReturnType();	return tree;    }    /** Make an attributed binary expression.     *  @param optag    The operators tree tag.     *  @param lhs      The operator's left argument.     *  @param rhs      The operator's right argument.     */    JCBinary makeBinary(int optag, JCExpression lhs, JCExpression rhs) {	JCBinary tree = make.Binary(optag, lhs, rhs);	tree.operator = rs.resolveBinaryOperator(	    make_pos, optag, attrEnv, lhs.type, rhs.type);	tree.type = tree.operator.type.getReturnType();	return tree;    }    /** Make an attributed assignop expression.     *  @param optag    The operators tree tag.     *  @param lhs      The operator's left argument.     *  @param rhs      The operator's right argument.     */    JCAssignOp makeAssignop(int optag, JCTree lhs, JCTree rhs) {	JCAssignOp tree = make.Assignop(optag, lhs, rhs);	tree.operator = rs.resolveBinaryOperator(	    make_pos, tree.getTag() - JCTree.ASGOffset, attrEnv, lhs.type, rhs.type);	tree.type = lhs.type;	return tree;    }    /** Convert tree into string object, unless it has already a     *  reference type..     */    JCExpression makeString(JCExpression tree) {        if (tree.type.tag >= CLASS) {	    return tree;	} else {	    Symbol valueOfSym = lookupMethod(tree.pos(),					     names.valueOf,					     syms.stringType,					     List.of(tree.type));	    return make.App(make.QualIdent(valueOfSym), List.of(tree));	}    }    /** Create an empty anonymous class definition and enter and complete     *  its symbol. Return the class definition's symbol.     *  and create     *  @param flags    The class symbol's flags     *  @param owner    The class symbol's owner     */    ClassSymbol makeEmptyClass(long flags, ClassSymbol owner) {	// Create class symbol.	ClassSymbol c = reader.defineClass(names.empty, owner);	c.flatname = chk.localClassName(c);	c.sourcefile = owner.sourcefile;	c.completer = null;	c.members_field = new Scope(c);	c.flags_field = flags;	ClassType ctype = (ClassType) c.type;	ctype.supertype_field = syms.objectType;	ctype.interfaces_field = List.nil();	JCClassDecl odef = classDef(owner);	// Enter class symbol in owner scope and compiled table.	enterSynthetic(odef.pos(), c, owner.members());	chk.compiled.put(c.flatname, c);	// Create class definition tree.	JCClassDecl cdef = make.ClassDef(            make.Modifiers(flags), names.empty,	    List.<JCTypeParameter>nil(),	    null, List.<JCExpression>nil(), List.<JCTree>nil());	cdef.sym = c;	cdef.type = c.type;	// Append class definition tree to owner's definitions.	odef.defs = odef.defs.prepend(cdef);	return c;    }/************************************************************************** * Symbol manipulation utilities *************************************************************************/    /** Report a conflict between a user symbol and a synthetic symbol.     */    private void duplicateError(DiagnosticPosition pos, Symbol sym) {        if (!sym.type.isErroneous()) {	    log.error(pos, "synthetic.name.conflict", sym, sym.location());	}    }    /** Enter a synthetic symbol in a given scope, but complain if there was already one there.     *  @param pos           Position for error reporting.     *  @param sym           The symbol.     *  @param s             The scope.     */    private void enterSynthetic(DiagnosticPosition pos, Symbol sym, Scope s) {        if (sym.name != names.error && sym.name != names.empty) {	    for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {		if (sym != e.sym && sym.kind == e.sym.kind) {		    // VM allows methods and variables with differing types		    if ((sym.kind & (MTH|VAR)) != 0 &&			!types.erasure(sym.type).equals(types.erasure(e.sym.type)))			continue;		    duplicateError(pos, e.sym);		    break;		}	    }	}	s.enter(sym);    }    /** Look up a synthetic name in a given scope.     *  @param scope	    The scope.     *  @param name	    The name.     */    private Symbol lookupSynthetic(Name name, Scope s) {	Symbol sym = s.lookup(name).sym;	return (sym==null || (sym.flags()&SYNTHETIC)==0) ? null : sym;    }    /** Look up a method in a given scope.     */    private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {	return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, null);    }    /** Look up a constructor.     */    private MethodSymbol lookupConstructor(DiagnosticPosition pos, Type qual, List<Type> args) {	return rs.resolveInternalConstructor(pos, attrEnv, qual, args, null);    }    /** Look up a field.     */    private VarSymbol lookupField(DiagnosticPosition pos, Type qual, Name name) {	return rs.resolveInternalField(pos, attrEnv, qual, name);    }/************************************************************************** * Access methods *************************************************************************/    /** Access codes for dereferencing, assignment,     *  and pre/post increment/decrement.     *  Access codes for assignment operations are determined by method accessCode     *  below.     *     *  All access codes for accesses to the current class are even.     *  If a member of the superclass should be accessed instead (because     *  access was via a qualified super), add one to the corresponding code     *  for the current class, making the number odd.     *  This numbering scheme is used by the backend to decide whether     *  to issue an invokevirtual or invokespecial call.     *     *  @see Gen.visitSelect(Select tree)     */    private static final int        DEREFcode = 0,	ASSIGNcode = 2,	PREINCcode = 4,	PREDECcode = 6,	POSTINCcode = 8,	POSTDECcode = 10,	FIRSTASGOPcode = 12;    /** Number of access codes     */    private static final int NCODES = accessCode(ByteCodes.lushrl) + 2;    /** A mapping from symbols to their access numbers.     */    private Map<Symbol,Integer> accessNums;    /** A mapping from symbols to an array of access symbols, indexed by     *  access code.     */    private Map<Symbol,MethodSymbol[]> accessSyms;    /** A mapping from (constructor) symbols to access constructor symbols.     */    private Map<Symbol,MethodSymbol> accessConstrs;    /** A queue for all accessed symbols.     */    private ListBuffer<Symbol> accessed;    /** Map bytecode of binary operation to access code of corresponding     *  assignment operation. This is always an even number.     */    private static int accessCode(int bytecode) {	if (ByteCodes.iadd <= bytecode && bytecode <= ByteCodes.lxor)	    return (bytecode - iadd) * 2 + FIRSTASGOPcode;	else if (bytecode == ByteCodes.string_add)	    return (ByteCodes.lxor + 1 - iadd) * 2 + FIRSTASGOPcode;	else if (ByteCodes.ishll <= bytecode && bytecode <= ByteCodes.lushrl)	    return (bytecode - ishll + ByteCodes.lxor + 2 - iadd) * 2 + FIRSTASGOPcode;	else	    return -1;    }    /** return access code for identifier,     *  @param tree     The tree representing the identifier use.     *  @param enclOp   The closest enclosing operation node of tree,     *                  null if tree is not a subtree of an operation.     */    private static int accessCode(JCTree tree, JCTree enclOp) {	if (enclOp == null)	    return DEREFcode;	else if (enclOp.getTag() == JCTree.ASSIGN &&		 tree == TreeInfo.skipParens(((JCAssign) enclOp).lhs))	    return ASSIGNcode;	else if (JCTree.PREINC <= enclOp.getTag() && enclOp.getTag() <= JCTree.POSTDEC &&		 tree == TreeInfo.skipParens(((JCUnary) enclOp).arg))	    return (enclOp.getTag() - JCTree.PREINC) * 2 + PREINCcode;	else if (JCTree.BITOR_ASG <= enclOp.getTag() && enclOp.getTag() <= JCTree.MOD_ASG &&		 tree == TreeInfo.skipParens(((JCAssignOp) enclOp).lhs))	    return accessCode(((OperatorSymbol) ((JCAssignOp) enclOp).operator).opcode);	else	    return DEREFcode;    }    /** Return binary operator that corresponds to given access code.     */    private OperatorSymbol binaryAccessOperator(int acode) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -