slcom/slangc/model/expressions/OuterThisExpression.sauce

85 lines
2.8 KiB
Plaintext

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
}
}