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

📄 lower.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	    if (e.sym.kind == TYP &&		e.sym.name == names.empty &&		(e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym;	return makeEmptyClass(STATIC | SYNTHETIC, clazz);    }    /** Return symbol for "class$" method. If there is no method definition     *  for class$, construct one as follows:     *     *    class class$(String x0) {     *      try {     *        return Class.forName(x0);     *      } catch (ClassNotFoundException x1) {     *        throw new NoClassDefFoundError(x1.getMessage());     *      }     *    }     */    private MethodSymbol classDollarSym(DiagnosticPosition pos) {	ClassSymbol outerCacheClass = outerCacheClass();	MethodSymbol classDollarSym =	    (MethodSymbol)lookupSynthetic(classDollar,					  outerCacheClass.members());	if (classDollarSym == null) {	    classDollarSym = new MethodSymbol(		STATIC | SYNTHETIC,		classDollar,		new MethodType(		    List.of(syms.stringType),		    types.erasure(syms.classType),		    List.<Type>nil(),		    syms.methodClass),		outerCacheClass);	    enterSynthetic(pos, classDollarSym, outerCacheClass.members());	    JCMethodDecl md = make.MethodDef(classDollarSym, null);	    try {		md.body = classDollarSymBody(pos, md);	    } catch (CompletionFailure ex) {		md.body = make.Block(0, List.<JCStatement>nil());		chk.completionError(pos, ex);	    }            JCClassDecl outerCacheClassDef = classDef(outerCacheClass);            outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(md);	}	return classDollarSym;    }    /** Generate code for class$(String name). */    JCBlock classDollarSymBody(DiagnosticPosition pos, JCMethodDecl md) {	MethodSymbol classDollarSym = md.sym;	ClassSymbol outerCacheClass = (ClassSymbol)classDollarSym.owner;	JCBlock returnResult;	// in 1.4.2 and above, we use	// Class.forName(String name, boolean init, ClassLoader loader);	// which requires we cache the current loader in cl$	if (target.classLiteralsNoInit()) {	    // clsym = "private static ClassLoader cl$"	    VarSymbol clsym = new VarSymbol(STATIC|SYNTHETIC,					    names.fromString("cl" + target.syntheticNameChar()),					    syms.classLoaderType,					    outerCacheClass);	    enterSynthetic(pos, clsym, outerCacheClass.members());	    // emit "private static ClassLoader cl$;"	    JCVariableDecl cldef = make.VarDef(clsym, null);	    JCClassDecl outerCacheClassDef = classDef(outerCacheClass);	    outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(cldef);	    // newcache := "new cache$1[0]"	    JCNewArray newcache = make.		NewArray(make.Type(outerCacheClass.type),			 List.<JCExpression>of(make.Literal(INT, 0).setType(syms.intType)),			 null);	    newcache.type = new ArrayType(types.erasure(outerCacheClass.type),					  syms.arrayClass);	    // forNameSym := java.lang.Class.forName(	    //     String s,boolean init,ClassLoader loader)	    Symbol forNameSym = lookupMethod(make_pos, names.forName,					     types.erasure(syms.classType),					     List.of(syms.stringType,						     syms.booleanType,						     syms.classLoaderType));	    // clvalue := "(cl$ == null) ?	    // $newcache.getClass().getComponentType().getClassLoader() : cl$"	    JCExpression clvalue =		make.Conditional(		    makeBinary(JCTree.EQ, make.Ident(clsym), makeNull()),		    make.Assign(			make.Ident(clsym),			makeCall(			    makeCall(makeCall(newcache,					      names.getClass,					      List.<JCExpression>nil()),				     names.getComponentType,				     List.<JCExpression>nil()),			    names.getClassLoader,			    List.<JCExpression>nil())).setType(syms.classLoaderType),		    make.Ident(clsym)).setType(syms.classLoaderType);					    // returnResult := "{ return Class.forName(param1, false, cl$); }"	    List<JCExpression> args = List.of(make.Ident(md.params.head.sym),					      makeLit(syms.booleanType, 0),					      clvalue);	    returnResult = make.		Block(0, List.<JCStatement>of(make.			      Call(make. // return				   App(make.				       Ident(forNameSym), args))));	} else {	    // forNameSym := java.lang.Class.forName(String s)	    Symbol forNameSym = lookupMethod(make_pos,					     names.forName,					     types.erasure(syms.classType),					     List.of(syms.stringType));	    // returnResult := "{ return Class.forName(param1); }"	    returnResult = make.		Block(0, List.of(make.			  Call(make. // return			      App(make.				  QualIdent(forNameSym),				  List.<JCExpression>of(make.							Ident(md.params.							      head.sym))))));	}	// catchParam := ClassNotFoundException e1	VarSymbol catchParam =	    new VarSymbol(0, make.paramName(1),			  syms.classNotFoundExceptionType,			  classDollarSym);	JCStatement rethrow;	if (target.hasInitCause()) {	    // rethrow = "throw new NoClassDefFoundError().initCause(e);	    JCTree throwExpr =		makeCall(makeNewClass(syms.noClassDefFoundErrorType,				      List.<JCExpression>nil()),			 names.initCause,			 List.<JCExpression>of(make.Ident(catchParam)));	    rethrow = make.Throw(throwExpr);	} else {	    // getMessageSym := ClassNotFoundException.getMessage()	    Symbol getMessageSym = lookupMethod(make_pos,						names.getMessage,						syms.classNotFoundExceptionType,						List.<Type>nil());	    // rethrow = "throw new NoClassDefFoundError(e.getMessage());"	    rethrow = make.		Throw(makeNewClass(syms.noClassDefFoundErrorType,			  List.<JCExpression>of(make.App(make.Select(make.Ident(catchParam),								     getMessageSym),							 List.<JCExpression>nil()))));	}	// rethrowStmt := "( $rethrow )"	JCBlock rethrowStmt = make.Block(0, List.of(rethrow));	// catchBlock := "catch ($catchParam) $rethrowStmt"	JCCatch catchBlock = make.Catch(make.VarDef(catchParam, null),				      rethrowStmt);	// tryCatch := "try $returnResult $catchBlock"	JCStatement tryCatch = make.Try(returnResult,					List.of(catchBlock), null);	return make.Block(0, List.of(tryCatch));    }    // where        /** Create an attributed tree of the form left.name(). */        private JCMethodInvocation makeCall(JCExpression left, Name name, List<JCExpression> args) {	    assert left.type != null;	    Symbol funcsym = lookupMethod(make_pos, name, left.type,					  TreeInfo.types(args));	    return make.App(make.Select(left, funcsym), args);	}    /** The Name Of The variable to cache T.class values.     *  @param sig      The signature of type T.     */    private Name cacheName(String sig) {	StringBuffer buf = new StringBuffer();	if (sig.startsWith("[")) {	    buf = buf.append("array");	    while (sig.startsWith("[")) {		buf = buf.append(target.syntheticNameChar());		sig = sig.substring(1);	    }	    if (sig.startsWith("L")) {		sig = sig.substring(0, sig.length() - 1);	    }	} else {	    buf = buf.append("class" + target.syntheticNameChar());	}	buf = buf.append(sig.replace('.', target.syntheticNameChar()));	return names.fromString(buf.toString());    }    /** The variable symbol that caches T.class values.     *  If none exists yet, create a definition.     *  @param sig      The signature of type T.     *  @param pos	The position to report diagnostics, if any.     */    private VarSymbol cacheSym(DiagnosticPosition pos, String sig) {	ClassSymbol outerCacheClass = outerCacheClass();	Name cname = cacheName(sig);	VarSymbol cacheSym =	    (VarSymbol)lookupSynthetic(cname, outerCacheClass.members());	if (cacheSym == null) {	    cacheSym = new VarSymbol(		STATIC | SYNTHETIC, cname, types.erasure(syms.classType), outerCacheClass);	    enterSynthetic(pos, cacheSym, outerCacheClass.members());	    JCVariableDecl cacheDef = make.VarDef(cacheSym, null);            JCClassDecl outerCacheClassDef = classDef(outerCacheClass);            outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(cacheDef);	}	return cacheSym;    }    /** The tree simulating a T.class expression.     *  @param clazz      The tree identifying type T.     */    private JCExpression classOf(JCTree clazz) {	return classOfType(clazz.type, clazz.pos());    }    private JCExpression classOfType(Type type, DiagnosticPosition pos) {	switch (type.tag) {	case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:	case DOUBLE: case BOOLEAN: case VOID:	    // replace with <BoxedClass>.TYPE	    ClassSymbol c = types.boxedClass(type);	    Symbol typeSym =		rs.access(		    rs.findIdentInType(attrEnv, c.type, names.TYPE, VAR),		    pos, c.type, names.TYPE, true);	    if (typeSym.kind == VAR)		((VarSymbol)typeSym).getConstValue(); // ensure initializer is evaluated	    return make.QualIdent(typeSym);	case CLASS: case ARRAY:	    if (target.hasClassLiterals()) {		VarSymbol sym = new VarSymbol(			STATIC | PUBLIC | FINAL, names._class,			syms.classType, type.tsym);		return make_at(pos).Select(make.Type(type), sym);	    }	    // replace with <cache == null ? cache = class$(tsig) : cache>	    // where	    //  - <tsig>  is the type signature of T,	    //  - <cache> is the cache variable for tsig.	    String sig =		writer.xClassName(type).toString().replace('/', '.');	    Symbol cs = cacheSym(pos, sig);	    return make_at(pos).Conditional(		makeBinary(JCTree.EQ, make.Ident(cs), makeNull()),		make.Assign(		    make.Ident(cs),		    make.App(			make.Ident(classDollarSym(pos)),			List.<JCExpression>of(make.Literal(CLASS, sig)					      .setType(syms.stringType))))		.setType(types.erasure(syms.classType)),		make.Ident(cs)).setType(types.erasure(syms.classType));	default:	    throw new AssertionError();	}    }/************************************************************************** * Code for enabling/disabling assertions. *************************************************************************/    // This code is not particularly robust if the user has    // previously declared a member named '$assertionsDisabled'.    // The same faulty idiom also appears in the translation of    // class literals above.  We should report an error if a    // previous declaration is not synthetic.    private JCExpression assertFlagTest(DiagnosticPosition pos) {	// Outermost class may be either true class or an interface.	ClassSymbol outermostClass = outermostClassDef.sym;	// note that this is a class, as an interface can't contain a statement.	ClassSymbol container = currentClass;	VarSymbol assertDisabledSym =	    (VarSymbol)lookupSynthetic(dollarAssertionsDisabled,				       container.members());	if (assertDisabledSym == null) {	    assertDisabledSym =		new VarSymbol(STATIC | FINAL | SYNTHETIC,			      dollarAssertionsDisabled,			      syms.booleanType,			      container);	    enterSynthetic(pos, assertDisabledSym, container.members());	    Symbol desiredAssertionStatusSym = lookupMethod(pos,							    names.desiredAssertionStatus,							    types.erasure(syms.classType),							    List.<Type>nil());	    JCClassDecl containerDef = classDef(container);	    make_at(containerDef.pos());	    JCExpression notStatus = makeUnary(JCTree.NOT, make.App(make.Select(                    classOfType(types.erasure(outermostClass.type),				containerDef.pos()),		    desiredAssertionStatusSym)));	    JCVariableDecl assertDisabledDef = make.VarDef(assertDisabledSym,						   notStatus);	    containerDef.defs = containerDef.defs.prepend(assertDisabledDef);	}	make_at(pos);	return makeUnary(JCTree.NOT, make.Ident(assertDisabledSym));    }/************************************************************************** * Building blocks for let expressions *************************************************************************/    interface TreeBuilder {	JCTree build(JCTree arg);    }    /** Construct an expression using the builder, with the given rval     *  expression as an argument to the builder.  However, the rval     *  expression must be computed only once, even if used multiple     *  times in the result of the builder.  We do that by     *  constructing a "let" expression that saves the rvalue into a     *  temporary variable and then uses the temporary variable in     *  place of the expression built by the builder.  The complete     *  resulting expression is of the form     *  <pre>     *    (let <b>TYPE</b> <b>TEMP</b> = <b>RVAL</b>;     *     in (<b>BUILDER</b>(<b>TEMP</b>)))     *  </pre>     *  where <code><b>TEMP</b></code> is a newly declared variable     *  in the let expression.     */    JCTree abstractRval(JCTree rval, Type type, TreeBuilder builder) {	rval = TreeInfo.skipParens(rval);	switch (rval.getTag()) {	case JCTree.LITERAL:	    return builder.build(rval);	case JCTree.IDENT:	    JCIdent id = (JCIdent) rval;	    if ((id.sym.flags() & FINAL) != 0 && id.sym.owner.kind == MTH)		return builder.build(rval);	}	VarSymbol var =	    new VarSymbol(FINAL|SYNTHETIC,			  Name.fromString(names,					  target.syntheticNameChar()					  + "" + rval.hashCode()),				      type,				      currentMethodSym);	JCVariableDecl def = make.VarDef(var, (JCExpression)rval); // XXX cast	JCTree built = builder.build(make.Ident(var));	JCTree res = make.LetExpr(def, built);	res.type = built.type;	return res;    }    // same as above, with the type of the temporary variable computed    JCTr

⌨️ 快捷键说明

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