1
3 package jminusminus;
4
5 import java.util.ArrayList;
6 import static jminusminus.CLConstants.*;
7
8
11
12 class JThisConstruction extends JExpression {
13
14
15 private ArrayList<JExpression> arguments;
16
17
18 private Constructor constructor;
19
20
21 private Type[] argTypes;
22
23
27 private boolean properUseOfConstructor = false;
28
29
38
39 protected JThisConstruction(int line, ArrayList<JExpression> arguments) {
40 super(line);
41 this.arguments = arguments;
42 }
43
44
48
49 public void markProperUseOfConstructor() {
50 properUseOfConstructor = true;
51 }
52
53
63
64 public JExpression analyze(Context context) {
65 type = Type.VOID;
66
67 argTypes = new Type[arguments.size()];
70 for (int i = 0; i < arguments.size(); i++) {
71 arguments.set(i, (JExpression) arguments.get(i).analyze(context));
72 argTypes[i] = arguments.get(i).type();
73 }
74
75 if (!properUseOfConstructor) {
76 JAST.compilationUnit.reportSemanticError(line(), "this"
77 + Type.argTypesAsString(argTypes)
78 + " must be first statement in the constructor's body.");
79 return this;
80 }
81
82 constructor = ((JTypeDecl) context.classContext.definition())
84 .thisType().constructorFor(argTypes);
85
86 if (constructor == null) {
87 JAST.compilationUnit.reportSemanticError(line(),
88 "No such constructor: this"
89 + Type.argTypesAsString(argTypes));
90
91 }
92 return this;
93 }
94
95
103
104 public void codegen(CLEmitter output) {
105 output.addNoArgInstruction(ALOAD_0); for (JExpression argument : arguments) {
107 argument.codegen(output);
108 }
109 output.addMemberAccessInstruction(INVOKESPECIAL, constructor
110 .declaringType().jvmName(), "<init>", constructor
111 .toDescriptor());
112 }
113
114
117
118 public void writeToStdOut(PrettyPrinter p) {
119 p.printf("<JThisConstruction line=\"%d\"/>\n", line());
120 p.indentRight();
121 if (arguments != null) {
122 p.println("<Arguments>");
123 for (JExpression argument : arguments) {
124 p.indentRight();
125 p.println("<Argument>");
126 p.indentRight();
127 argument.writeToStdOut(p);
128 p.indentLeft();
129 p.println("</Argument>");
130 p.indentLeft();
131 }
132 p.println("</Arguments>");
133 }
134 p.indentLeft();
135 p.println("</JThisConstruction>");
136 }
137
138 }
139