package slangc.model.expressions; import slangc.api.BytecodeInstructionWriter; import slangc.api.Reporter; import slangc.bytecode.TypeSignature; import slangc.model.ExpressionModel; import slangc.model.ExpressionOwner; import slangc.model.ExpressionResult; import slangc.model.TypeLevel; import slangc.model.TypeModel; import slangc.model.UserTypeModel; import slangc.parser.Branch; import slangc.parser.Node; public class OuterThisExpression extends ExpressionModel implements ExpressionOwner { private TypeModel leftHandSide; public OuterThisExpression(ExpressionOwner owner, Node source) { super(owner, source); Node t = ((Branch)source).getSubnode(0); leftHandSide = owner.resolveType(t);//ExpressionModel.construct(this, ((Branch)sourceFile).getSubnode(0)); } @Override public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + "> Outer this expression of " + leftHandSide); dumpResolved(reporter, indent + incr, incr); } @Override public TypeModel getExpectedResult(ExpressionModel e) { // TODO Auto-generated method stub return null; } public TypeModel getType() { return leftHandSide; } @Override public ExpressionModel[] getSubexpressions() { return NO_SUBEXPRESSIONS; } @Override protected ExpressionResult resolveResult() { // TODO Should probably check that the outer this actually makes sense first return new ExpressionResult.TypedValue(getType()); } public static TypeSignature generatePossibleOuterThis(BytecodeInstructionWriter w, UserTypeModel thisThis, TypeModel desiredOuter) { return generatePossibleOuterThis(w, thisThis, desiredOuter, false); } private static TypeSignature generatePossibleOuterThis(BytecodeInstructionWriter w, UserTypeModel thisThis, TypeModel desiredOuter, boolean alreadyRecursing) { if ((thisThis == desiredOuter || thisThis.inherits(desiredOuter)) && !alreadyRecursing) { w.genThis(); return thisThis.getTypeSignature(); } else if (thisThis.isNonStaticInnerType()) { TypeModel outer = thisThis.getOwner().getNearestType(); if (!alreadyRecursing) { w.genThis(); } w.genOuterThis(); if (outer == desiredOuter || outer.inherits(desiredOuter)) { return outer.getTypeSignature(); } else { return generatePossibleOuterThis(w, (UserTypeModel) outer, desiredOuter, true); } } else { w.genError("Bad outer this, can't get to " + desiredOuter + " from " + thisThis); return null; } } @Override public TypeSignature innerGenerate(BytecodeInstructionWriter w) { return generatePossibleOuterThis(w, (UserTypeModel)getMethodOrField().getOwner(), leftHandSide); } public TypeModel resolveType(Node n) { return super.resolveType(n); // TODO: Better support for interfaces } }