diff options
Diffstat (limited to 'src/main/java/io/devnulllabs/openjava/ptree/util/ExpansionApplier.java')
-rw-r--r-- | src/main/java/io/devnulllabs/openjava/ptree/util/ExpansionApplier.java | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/src/main/java/io/devnulllabs/openjava/ptree/util/ExpansionApplier.java b/src/main/java/io/devnulllabs/openjava/ptree/util/ExpansionApplier.java new file mode 100644 index 0000000..811cc32 --- /dev/null +++ b/src/main/java/io/devnulllabs/openjava/ptree/util/ExpansionApplier.java @@ -0,0 +1,457 @@ +/* + * ExpansionApplier.java + * + * comments here. + * + * @author Michiaki Tatsubori + * @version %VERSION% %DATE% + * @see java.lang.Object + * + * COPYRIGHT 1998 by Michiaki Tatsubori, ALL RIGHTS RESERVED. + */ +package io.devnulllabs.openjava.ptree.util; + +import io.devnulllabs.openjava.mop.Environment; +import io.devnulllabs.openjava.mop.OJClass; +import io.devnulllabs.openjava.ptree.AllocationExpression; +import io.devnulllabs.openjava.ptree.ArrayAccess; +import io.devnulllabs.openjava.ptree.ArrayAllocationExpression; +import io.devnulllabs.openjava.ptree.AssignmentExpression; +import io.devnulllabs.openjava.ptree.BinaryExpression; +import io.devnulllabs.openjava.ptree.CastExpression; +import io.devnulllabs.openjava.ptree.ClassLiteral; +import io.devnulllabs.openjava.ptree.ConditionalExpression; +import io.devnulllabs.openjava.ptree.Expression; +import io.devnulllabs.openjava.ptree.FieldAccess; +import io.devnulllabs.openjava.ptree.InstanceofExpression; +import io.devnulllabs.openjava.ptree.Literal; +import io.devnulllabs.openjava.ptree.MethodCall; +import io.devnulllabs.openjava.ptree.ParseTreeException; +import io.devnulllabs.openjava.ptree.SelfAccess; +import io.devnulllabs.openjava.ptree.Statement; +import io.devnulllabs.openjava.ptree.TypeName; +import io.devnulllabs.openjava.ptree.UnaryExpression; +import io.devnulllabs.openjava.ptree.Variable; +import io.devnulllabs.openjava.ptree.VariableDeclaration; +import io.devnulllabs.openjava.tools.DebugOut; + +/** + * The class <code>ExpansionApplier</code> is an evaluator of each + * objects of <code>ParseTree</code> family. Each methods in + * this class is invoked from the class <code>EvaluationShuttle</code>. + * <p> + * The method <code>evaluateDown()</code> is invoked before evaluating + * the children of the parse tree object, and <code>evaluateUp()</code> + * is invoked after the evaluation. + * <p> + * For a class <code>P</code> and a object <code>p</code> statically + * typed as P, the parts in source code each expantion will be applied + * are: + * <ul> + * <li>Allocation <code>new P()</code> + * <li>ArrayAllocation <code>new P[expr]</code> + * <li>MethodCall <code>P.m()</code>, <code>p.m()</code> + * <li>FieldRead <code>P.f</code>, <code>p.f</code> as a right side value + * <li>FieldWrite <code>P.f = expr</code>, <code>p.f = expr</code> + * <li>ArrayAccess <code>ap[expr]</code> for <code>P[] ap;</code> + * <li>Expression <code>p</code> + * </ul> + * in feature version: + * <ul> + * <li>CastExpression <code>(P) expr</code> including implicit cast + * <li>CastedExpression <code>(Q) p</code> including implicit cast + * </ul> + * + * @author Michiaki Tatsubori + * @version 1.0 + * @since $Id: ExpansionApplier.java,v 1.2 2003/02/19 02:55:00 tatsubori Exp $ + * @see io.devnulllabs.openjava.ptree.ParseTree + * @see io.devnulllabs.openjava.ptree.util.EvaluationShuttle + */ +public class ExpansionApplier extends VariableBinder { + public ExpansionApplier(Environment env) { + super(env); + } + + private OJClass getType(Expression p) throws ParseTreeException { + OJClass result = null; + try { + result = p.getType(getEnvironment()); + } catch (Exception e) { + e.printStackTrace(); + throw new ParseTreeException(e); + } + DebugOut.println("type eval - " + p + "\t: " + result); + if (result == null) { + System.err.println("cannot resolve the type of expression"); + System.err.println(p.getClass() + " : " + p); + System.err.println(getEnvironment()); + /*****DebugOut.println(getEnvironment().toString());*/ + if (p instanceof ArrayAccess) { + ArrayAccess aaexpr = (ArrayAccess) p; + Expression refexpr = aaexpr.getReferenceExpr(); + OJClass refexprtype = null; + OJClass comptype = null; + try { + refexprtype = refexpr.getType(getEnvironment()); + comptype = refexprtype.getComponentType(); + } catch (Exception ex) { + } + System.err.println( + refexpr + " : " + refexprtype + " : " + comptype); + } + } + return result; + } + + private OJClass getSelfType() throws ParseTreeException { + OJClass result; + try { + Environment env = getEnvironment(); + String selfname = env.currentClassName(); + result = env.lookupClass(selfname); + } catch (Exception ex) { + throw new ParseTreeException(ex); + } + return result; + } + + private OJClass getType(TypeName typename) throws ParseTreeException { + OJClass result = null; + try { + Environment env = getEnvironment(); + String qname = env.toQualifiedName(typename.toString()); + result = env.lookupClass(qname); + } catch (Exception ex) { + throw new ParseTreeException(ex); + } + DebugOut.println("type eval - class access : " + result); + if (result == null) { + System.err.println("unknown type for a type name : " + typename); + } + return result; + } + + private OJClass computeRefType(TypeName typename, Expression expr) + throws ParseTreeException { + if (typename != null) + return getType(typename); + if (expr != null) + return getType(expr); + return getSelfType(); + } + + public void visit(AssignmentExpression p) throws ParseTreeException { + Expression left = p.getLeft(); + if (!(left instanceof FieldAccess)) { + super.visit(p); + return; + } + FieldAccess fldac = (FieldAccess) left; + Expression refexpr = fldac.getReferenceExpr(); + TypeName reftype = fldac.getReferenceType(); + Expression value = p.getRight(); + /* custom version of visit() skipping the field */ + Expression newp; + newp = this.evaluateDown(p); + if (newp != p) { + p.replace(newp); + newp.accept(this); + return; + } + + if (refexpr != null) { + refexpr.accept(this); + } else if (reftype != null) { + reftype.accept(this); + } + value.accept(this); + + newp = this.evaluateUp(p); + if (newp != p) + p.replace(newp); + } + + /** + * Includes expandAllocation() and expandExpression(). + */ + public Expression evaluateUp(AllocationExpression p) + throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandAllocation(getEnvironment(), p); + if (newp != p) + return newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandArrayAccess() and expandExpression(). + */ + public Expression evaluateUp(ArrayAccess p) throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandArrayAccess(getEnvironment(), p); + if (newp != p) + return newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandArrayAllocation() and expandExpression(). + */ + public Expression evaluateUp(ArrayAllocationExpression p) + throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandArrayAllocation(getEnvironment(), p); + if (newp != p) + return newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandFieldWrite(), expandAssignmentExpression() + * and expandExpression(). + */ + public Expression evaluateUp(AssignmentExpression p) + throws ParseTreeException { + Expression left = p.getLeft(); + if (left instanceof FieldAccess) { + FieldAccess fldac = (FieldAccess) left; + OJClass reftype = + computeRefType( + fldac.getReferenceType(), + fldac.getReferenceExpr()); + if (reftype != getSelfType()) { + Expression newp = reftype.expandFieldWrite(getEnvironment(), p); + if (!(newp instanceof AssignmentExpression)) + return newp; + p = (AssignmentExpression) newp; + } + } + + OJClass type = getType(p); + if (type != getSelfType()) { + Expression newp = + type.expandAssignmentExpression(getEnvironment(), p); + if (!(newp instanceof AssignmentExpression)) + return newp; + p = (AssignmentExpression) newp; + type = getType(p); + } + if (type != getSelfType()) { + Expression newp = type.expandExpression(getEnvironment(), p); + if (!(newp instanceof AssignmentExpression)) + return newp; + p = (AssignmentExpression) newp; + } + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(BinaryExpression p) + throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandCastExpression(), expandCastedExpression() and + * expandExpression(). + */ + public Expression evaluateUp(CastExpression p) throws ParseTreeException { + OJClass type = getType(p); + OJClass orgType = getType(p.getExpression()); + Expression newp; + newp = orgType.expandCastedExpression(getEnvironment(), p); + if (newp != p) + return newp; + newp = type.expandCastExpression(getEnvironment(), p); + if (newp != p) + return newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(ClassLiteral p) throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(ConditionalExpression p) + throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandFieldRead() and expandExpression(). + * Not to be applied for itself. + */ + public Expression evaluateUp(FieldAccess p) throws ParseTreeException { + { + OJClass reftype = + computeRefType(p.getReferenceType(), p.getReferenceExpr()); + if (reftype != getSelfType()) { + Expression newp = reftype.expandFieldRead(getEnvironment(), p); + if (newp != p) + return newp; + } + } + { + OJClass type = getType(p); + Expression newp = type.expandExpression(getEnvironment(), p); + if (!(newp instanceof FieldAccess)) + return newp; + p = (FieldAccess) newp; + } + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(InstanceofExpression p) + throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(Literal p) throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandMethodCall() and expandExpression(). + */ + public Expression evaluateUp(MethodCall p) throws ParseTreeException { + { + OJClass reftype = + computeRefType(p.getReferenceType(), p.getReferenceExpr()); + if (reftype != getSelfType()) { + Expression newp = reftype.expandMethodCall(getEnvironment(), p); + if (newp != p) + return newp; + } + } + { + OJClass type = getType(p); + Expression newp = type.expandExpression(getEnvironment(), p); + if (!(newp instanceof MethodCall)) + return newp; + p = (MethodCall) newp; + } + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(SelfAccess p) throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandTypeName(). + */ + public TypeName evaluateUp(TypeName p) throws ParseTreeException { + OJClass type = getType(p); + TypeName newp; + newp = type.expandTypeName(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(UnaryExpression p) throws ParseTreeException { + OJClass type = getType(p); + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandExpression(). + */ + public Expression evaluateUp(Variable p) throws ParseTreeException { + OJClass type = getType(p); + + /* special ignorance for variable ? */ + if (type == null) + return p; + + Expression newp; + newp = type.expandExpression(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + + /** + * Includes expandVariableDeclaration(). + */ + public Statement evaluateUp(VariableDeclaration p) + throws ParseTreeException { + OJClass type = getType(p.getTypeSpecifier()); + Statement newp; + newp = type.expandVariableDeclaration(getEnvironment(), p); + if (newp != p) + return newp; + return super.evaluateUp(p); + } + +} |