1
3 package jminusminus;
4
5 import java.util.ArrayList;
6
7 import static jminusminus.CLConstants.*;
8
9
12 class JSuperConstruction 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 JSuperConstruction(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 "super" + Type.argTypesAsString(argTypes)
60 + " must be first statement in the constructor's body");
61 return this;
62 }
63
64 Type superClass = ((JTypeDecl) context.classContext.definition()).thisType().superClass();
66 if (superClass == null) {
67 JAST.compilationUnit.reportSemanticError(line,
68 ((JTypeDecl) context.classContext.definition()).thisType() +
69 " has no super class");
70 }
71 constructor = superClass.constructorFor(argTypes);
72 if (constructor == null) {
73 JAST.compilationUnit.reportSemanticError(line(),
74 "No such constructor: super" + Type.argTypesAsString(argTypes));
75 }
76
77 return this;
78 }
79
80
83 public void codegen(CLEmitter output) {
84 output.addNoArgInstruction(ALOAD_0); for (JExpression argument : arguments) {
86 argument.codegen(output);
87 }
88 output.addMemberAccessInstruction(INVOKESPECIAL, constructor.declaringType().jvmName(),
89 "<init>", constructor.toDescriptor());
90 }
91
92
95 public void toJSON(JSONElement json) {
96 JSONElement e = new JSONElement();
97 json.addChild("JSuperConstruction:" + line, e);
98 if (arguments != null) {
99 for (JExpression argument : arguments) {
100 JSONElement e1 = new JSONElement();
101 e.addChild("Argument", e1);
102 argument.toJSON(e1);
103 }
104 }
105 }
106 }
107