package slangc.model.expressions; import slangc.api.BytecodeInstructionWriter; import slangc.api.Reporter; import slangc.bytecode.TypeSignature; import slangc.model.ClauseModel; import slangc.model.ExpressionModel; import slangc.model.ExpressionOwner; import slangc.model.ExpressionResult; import slangc.model.MethodModel; import slangc.model.TypeModel; import slangc.model.UserTypeModel; import slangc.model.clauses.Arguments; import slangc.parser.Branch; import slangc.parser.Node; public class ThisConstructorCallExpression extends ExpressionModel implements ExpressionOwner { private Arguments arguments; private boolean approvedLocation = false; public ThisConstructorCallExpression(ExpressionOwner owner, Node source) { super(owner, source); arguments = (Arguments)ClauseModel.construct(this, ((Branch)source).getSubnode(1)); //sourceFile.annotate(ErrorType.INTERNAL_ERROR, "Unrecognised expression (Internal error/TODO)"); } @Override public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + "> This constructor call of:"); dumpResolved(reporter, indent + incr, incr); arguments.dump(reporter, indent + incr, incr); } @Override public TypeModel getExpectedResult(ExpressionModel e) { // TODO Auto-generated method stub return null; } public Arguments getArguments() { return arguments; } @Override public ExpressionModel[] getSubexpressions() { return arguments.getSubexpressions(); } @Override protected ExpressionResult resolveResult() { targetMethod = bestTargetMethod(((UserTypeModel)getMethodOrField().getOwner()).getInstanceConstructors(), arguments); // Super/this constructor calls shouldn't be used within expressions // so they can be assumed to return void even though logically they kind-of // return the object they create return ExpressionResult.VOID; } private MethodModel targetMethod = null; @Override public boolean hasTargetMethod() { return true; } @Override public MethodModel getTargetMethod() { // TODO Auto-generated method stub return targetMethod; } @Override public TypeSignature innerGenerate(BytecodeInstructionWriter w) { if (!isApprovedLocation()) { w.genError("Constructors can't be called in this context"); } //w.genThis(); arguments.generate(w, getTargetMethod(), true); w.genNestedConstructorCall(getTargetMethod().getMethodSignature()); return TypeSignature.VOID; } public boolean isApprovedLocation() { return approvedLocation; } public void setApprovedLocation(boolean approvedLocation) { this.approvedLocation = approvedLocation; } public TypeModel resolveType(Node n) { return super.resolveType(n); // TODO: Better support for interfaces } }