1
3 package jminusminus;
4
5 import java.util.ArrayList;
6
7 import static jminusminus.CLConstants.*;
8
9
13 class JNewOp extends JExpression {
14 private Constructor constructor;
16
17 private ArrayList<JExpression> arguments;
19
20 private Type[] argTypes;
22
23
30 public JNewOp(int line, Type type, ArrayList<JExpression> arguments) {
31 super(line);
32 super.type = type;
33 this.arguments = arguments;
34 }
35
36
39 public JExpression analyze(Context context) {
40 type = type.resolve(context);
42
43 argTypes = new Type[arguments.size()];
45 for (int i = 0; i < arguments.size(); i++) {
46 arguments.set(i, (JExpression) arguments.get(i).analyze(context));
47 argTypes[i] = arguments.get(i).type();
48 }
49
50 if (type.isAbstract()) {
52 JAST.compilationUnit.reportSemanticError(line(),
53 "Cannot instantiate an abstract type: " + type.toString());
54 }
55
56 constructor = type.constructorFor(argTypes);
58
59 if (constructor == null) {
60 JAST.compilationUnit.reportSemanticError(line(),
61 "Cannot find constructor: " + Type.signatureFor(type.toString(), argTypes));
62 }
63 return this;
64 }
65
66
69 public void codegen(CLEmitter output) {
70 output.addReferenceInstruction(NEW, type.jvmName());
71 output.addNoArgInstruction(DUP);
72 for (JExpression argument : arguments) {
73 argument.codegen(output);
74 }
75 output.addMemberAccessInstruction(INVOKESPECIAL,
76 type.jvmName(),
77 "<init>",
78 constructor.toDescriptor());
79 }
80
81
84 public void toJSON(JSONElement json) {
85 JSONElement e = new JSONElement();
86 json.addChild("JNewOp:" + line, e);
87 e.addAttribute("type", type == null ? "" : type.toString());
88 if (arguments != null) {
89 for (JExpression argument : arguments) {
90 JSONElement e1 = new JSONElement();
91 e.addChild("Argument", e1);
92 argument.toJSON(e1);
93 }
94 }
95 }
96 }
97