1
3 package jminusminus;
4
5 import java.util.ArrayList;
6 import static jminusminus.CLConstants.*;
7
8
12
13 class JConstructorDeclaration extends JMethodDeclaration implements JMember {
14
15
16 private boolean invokesConstructor;
17
18
19 JClassDeclaration definingClass;
20
21
38
39 public JConstructorDeclaration(int line, ArrayList<String> mods,
40 String name, ArrayList<JFormalParameter> params, JBlock body)
41
42 {
43 super(line, mods, name, Type.CONSTRUCTOR, params, body);
44 }
45
46
55
56 public void preAnalyze(Context context, CLEmitter partial) {
57 super.preAnalyze(context, partial);
58 if (isStatic) {
59 JAST.compilationUnit.reportSemanticError(line(),
60 "Constructor cannot be declared static");
61 } else if (isAbstract) {
62 JAST.compilationUnit.reportSemanticError(line(),
63 "Constructor cannot be declared abstract");
64 }
65 if (body.statements().size() > 0
66 && body.statements().get(0) instanceof JStatementExpression) {
67 JStatementExpression first = (JStatementExpression) body
68 .statements().get(0);
69 if (first.expr instanceof JSuperConstruction) {
70 ((JSuperConstruction) first.expr).markProperUseOfConstructor();
71 invokesConstructor = true;
72 } else if (first.expr instanceof JThisConstruction) {
73 ((JThisConstruction) first.expr).markProperUseOfConstructor();
74 invokesConstructor = true;
75 }
76 }
77 }
78
79
87
88 public JAST analyze(Context context) {
89 definingClass = (JClassDeclaration) context.classContext().definition();
91 return super.analyze(context);
92 }
93
94
103
104 public void partialCodegen(Context context, CLEmitter partial) {
105 partial.addMethod(mods, "<init>", descriptor, null, false);
106 if (!invokesConstructor) {
107 partial.addNoArgInstruction(ALOAD_0);
108 partial.addMemberAccessInstruction(INVOKESPECIAL,
109 ((JTypeDecl) context.classContext().definition())
110 .superType().jvmName(), "<init>", "()V");
111 }
112 partial.addNoArgInstruction(RETURN);
113 }
114
115
122
123 public void codegen(CLEmitter output) {
124 output.addMethod(mods, "<init>", descriptor, null, false);
125 if (!invokesConstructor) {
126 output.addNoArgInstruction(ALOAD_0);
127 output.addMemberAccessInstruction(INVOKESPECIAL,
128 ((JTypeDecl) context.classContext().definition())
129 .superType().jvmName(), "<init>", "()V");
130 }
131 for (JFieldDeclaration field : definingClass
133 .instanceFieldInitializations()) {
134 field.codegenInitializations(output);
135 }
136 body.codegen(output);
138 output.addNoArgInstruction(RETURN);
139 }
140
141
144
145 public void writeToStdOut(PrettyPrinter p) {
146 p.printf("<JConstructorDeclaration line=\"%d\" " + "name=\"%s\">\n",
147 line(), name);
148 p.indentRight();
149 if (context != null) {
150 context.writeToStdOut(p);
151 }
152 if (mods != null) {
153 p.println("<Modifiers>");
154 p.indentRight();
155 for (String mod : mods) {
156 p.printf("<Modifier name=\"%s\"/>\n", mod);
157 }
158 p.indentLeft();
159 p.println("</Modifiers>");
160 }
161 if (params != null) {
162 p.println("<FormalParameters>");
163 for (JFormalParameter param : params) {
164 p.indentRight();
165 param.writeToStdOut(p);
166 p.indentLeft();
167 }
168 p.println("</FormalParameters>");
169 }
170 if (body != null) {
171 p.println("<Body>");
172 p.indentRight();
173 body.writeToStdOut(p);
174 p.indentLeft();
175 p.println("</Body>");
176 }
177 p.indentLeft();
178 p.println("</JConstructorDeclaration>");
179 }
180
181 }
182