1
3 package jminusminus;
4
5 import java.util.ArrayList;
6
7 import static jminusminus.CLConstants.*;
8
9
12 class JThisConstruction extends JExpression {
13 private ArrayList<JExpression> arguments;
15
16 private Constructor constructor;
18
19 private Type[] argTypes;
21
22 private boolean properUseOfConstructor;
24
25
31 protected JThisConstruction(int line, ArrayList<JExpression> arguments) {
32 super(line);
33 this.arguments = arguments;
34 properUseOfConstructor = false;
35 }
36
37
40 public void markProperUseOfConstructor() {
41 properUseOfConstructor = true;
42 }
43
44
47 public JExpression analyze(Context context) {
48 type = Type.VOID;
49
50 argTypes = new Type[arguments.size()];
52 for (int i = 0; i < arguments.size(); i++) {
53 arguments.set(i, (JExpression) arguments.get(i).analyze(context));
54 argTypes[i] = arguments.get(i).type();
55 }
56
57 if (!properUseOfConstructor) {
58 JAST.compilationUnit.reportSemanticError(line(),
59 "this" + Type.argTypesAsString(argTypes)
60 + " must be first statement in the constructor's body");
61 return this;
62 }
63
64 constructor =
66 ((JTypeDecl) context.classContext.definition()).thisType().constructorFor(argTypes);
67
68 if (constructor == null) {
69 JAST.compilationUnit.reportSemanticError(line(),
70 "No such constructor: this" + Type.argTypesAsString(argTypes));
71
72 }
73 return this;
74 }
75
76
79 public void codegen(CLEmitter output) {
80 output.addNoArgInstruction(ALOAD_0); for (JExpression argument : arguments) {
82 argument.codegen(output);
83 }
84 output.addMemberAccessInstruction(INVOKESPECIAL, constructor.declaringType().jvmName(),
85 "<init>", constructor.toDescriptor());
86 }
87
88
91 public void toJSON(JSONElement json) {
92 JSONElement e = new JSONElement();
93 json.addChild("JThisConstruction:" + line, e);
94 if (arguments != null) {
95 for (JExpression argument : arguments) {
96 JSONElement e1 = new JSONElement();
97 e.addChild("Argument", e1);
98 argument.toJSON(e1);
99 }
100 }
101 }
102 }
103