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.FieldModel; import slangc.model.Named; import slangc.model.StorageSlot; import slangc.model.TypeModel; import slangc.model.UserTypeModel; import slangc.parser.Branch; import slangc.parser.ErrorType; import slangc.parser.Node; public class SuperReferenceExpression extends ExpressionModel implements ExpressionOwner { private String name; public SuperReferenceExpression(ExpressionOwner owner, Node source) { super(owner, source); name = UserTypeModel.plainName(((Branch)source).getSubnode(2)); //sourceFile.annotate(ErrorType.INTERNAL_ERROR, "Unrecognised expression (Internal error/TODO)"); } @Override public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + "> SuperReference expression '" + name + "'"); dumpResolved(reporter, indent + incr, incr); } public String getName() { return name; } @Override public TypeModel getExpectedResult(ExpressionModel e) { // TODO Auto-generated method stub return null; } @Override public ExpressionModel[] getSubexpressions() { return NO_SUBEXPRESSIONS; } @Override protected ExpressionResult resolveResult() { TypeModel superType = ((UserTypeModel) getOwner().getMethodOrField().getOwner()).getBaseClass(); if (superType.hasInnerType(name)) { return new ExpressionResult.PointsToType(superType.getInnerType(name)); } else if (superType.hasField(name, true)) { return new ExpressionResult.PointsToStorageSlot(superType.getField(name, true)); } else { getSource().annotate(ErrorType.INTERNAL_ERROR, "Can't find '" + name + "' within super-type " + superType); return ExpressionResult.INVALID; } } @Override public TypeSignature innerGenerate(BytecodeInstructionWriter w) { ExpressionResult.PointsToStorageSlot s = (ExpressionResult.PointsToStorageSlot)getResult(); StorageSlot slot = s.getSlot(); if (slot instanceof FieldModel) { FieldModel f = (FieldModel)slot; if (!f.isStatic()) { w.genThis(); } w.genLoad(f.getFieldSignature()); return f.getStorageType().getTypeSignature(); } else { w.genError("TODO: innerGenerate for " + Type.of(this) + " with slot " + slot); return null; } } @Override public void generateStore(BytecodeInstructionWriter w, TypeSignature storing) { ExpressionResult.PointsToStorageSlot s = (ExpressionResult.PointsToStorageSlot)getResult(); StorageSlot slot = s.getSlot(); if (slot instanceof FieldModel) { FieldModel f = (FieldModel)slot; if (!f.isStatic()) { w.genThis(); } w.genStore(f.getFieldSignature()); } else { w.genError("TODO: generateStore for " + Type.of(this) + " with slot " + slot); } } public TypeModel resolveType(Node n) { return super.resolveType(n); // TODO: Better support for interfaces } }