|
@@ -5,6 +5,7 @@ import org.objectweb.asm.Label;
|
5
|
5
|
import org.objectweb.asm.Type;
|
6
|
6
|
import org.openzen.zenscript.codemodel.FunctionParameter;
|
7
|
7
|
import org.openzen.zenscript.codemodel.HighLevelDefinition;
|
|
8
|
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
|
8
|
9
|
import org.openzen.zenscript.codemodel.member.*;
|
9
|
10
|
import org.openzen.zenscript.codemodel.type.StoredType;
|
10
|
11
|
import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
|
|
@@ -15,6 +16,9 @@ import org.openzen.zenscript.javashared.JavaCompiledModule;
|
15
|
16
|
import org.openzen.zenscript.javashared.JavaField;
|
16
|
17
|
import org.openzen.zenscript.javashared.JavaMethod;
|
17
|
18
|
|
|
19
|
+import java.util.ArrayList;
|
|
20
|
+import java.util.stream.Collectors;
|
|
21
|
+
|
18
|
22
|
public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
|
19
|
23
|
|
20
|
24
|
private final ClassWriter writer;
|
|
@@ -79,38 +83,76 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
|
79
|
83
|
if (!method.compile)
|
80
|
84
|
return null;
|
81
|
85
|
|
|
86
|
+ final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
|
|
87
|
+ expandedClass.type.extractTypeParameters(typeParameters);
|
82
|
88
|
|
83
|
|
- CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic());
|
|
89
|
+ CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic(), typeParameters);
|
84
|
90
|
|
85
|
91
|
final String expandedClassDescriptor = context.getDescriptor(expandedClass);
|
|
92
|
+ final String expandedClassSignature = context.getSignature(expandedClass);
|
86
|
93
|
final Label methodStart = new Label();
|
87
|
94
|
final Label methodEnd = new Label();
|
88
|
95
|
final String methodSignature;
|
|
96
|
+ final String methodDescriptor;
|
|
97
|
+
|
|
98
|
+
|
89
|
99
|
|
90
|
100
|
if (!isStatic) {
|
91
|
|
- methodSignature = "(" + expandedClassDescriptor + context.getMethodSignature(member.header).substring(1);
|
|
101
|
+ String methodSignature1 = context.getMethodSignature(member.header);
|
|
102
|
+
|
|
103
|
+ //Add the expanded type as first generic parameter to the list.
|
|
104
|
+ if(!typeParameters.isEmpty()){
|
|
105
|
+ final String collect = typeParameters.stream()
|
|
106
|
+ .map(t -> t.name + ":" + "Ljava/lang/Object;")
|
|
107
|
+ .collect(Collectors.joining("", "<", ""));
|
|
108
|
+ if(methodSignature1.startsWith("<")) {
|
|
109
|
+ methodSignature1 = collect + methodSignature1.substring(1);
|
|
110
|
+ } else {
|
|
111
|
+ methodSignature1 = collect + ">" + methodSignature1;
|
|
112
|
+ }
|
|
113
|
+ }
|
|
114
|
+
|
|
115
|
+ final StringBuilder typeParamSigBuilder = new StringBuilder();
|
|
116
|
+ final StringBuilder typeParamDescBuilder = new StringBuilder();
|
|
117
|
+ int i = 1;
|
|
118
|
+ for (TypeParameter typeParameter : typeParameters) {
|
|
119
|
+ typeParamSigBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
|
|
120
|
+ typeParamDescBuilder.append("Ljava/lang/Class;");
|
|
121
|
+ }
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+ final int index = methodSignature1.lastIndexOf('(') + 1;
|
|
125
|
+ methodSignature = methodSignature1.substring(0, index) + expandedClassSignature + typeParamSigBuilder.toString() + methodSignature1.substring(index);
|
|
126
|
+ methodDescriptor = "(" + expandedClassDescriptor + typeParamDescBuilder.toString() + context.getMethodDescriptor(member.header).substring(1);
|
92
|
127
|
} else {
|
93
|
128
|
methodSignature = context.getMethodSignature(member.header);
|
|
129
|
+ methodDescriptor = context.getMethodDescriptor(member.header);
|
94
|
130
|
}
|
95
|
131
|
|
96
|
132
|
|
97
|
|
- final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, method, definition, true, methodSignature, methodSignature, null);
|
|
133
|
+ final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, method, definition, true, methodSignature, methodDescriptor, null);
|
98
|
134
|
methodWriter.label(methodStart);
|
99
|
135
|
|
100
|
136
|
if (!isStatic) {
|
101
|
137
|
methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, Type.getType(expandedClassDescriptor));
|
102
|
138
|
methodWriter.nameParameter(0, "expandedObj");
|
103
|
|
- for (final FunctionParameter parameter : member.header.parameters) {
|
104
|
|
- methodWriter.nameParameter(0, parameter.name);
|
105
|
|
- methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
|
106
|
|
- }
|
107
|
|
- } else {
|
108
|
|
- for (final FunctionParameter parameter : member.header.parameters) {
|
109
|
|
- methodWriter.nameParameter(0, parameter.name);
|
110
|
|
- methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
|
|
139
|
+
|
|
140
|
+ for (TypeParameter typeParameter : typeParameters) {
|
|
141
|
+ methodWriter.nameParameter(0, "typeOf" + typeParameter.name);
|
|
142
|
+ methodWriter.nameVariable(javaModule.getTypeParameterInfo(typeParameter).parameterIndex, "typeOf" + typeParameter.name, methodStart, methodEnd, Type.getType(Class.class));
|
111
|
143
|
}
|
112
|
144
|
}
|
113
|
145
|
|
|
146
|
+ for (TypeParameter typeParameter : member.header.typeParameters) {
|
|
147
|
+ methodWriter.nameParameter(0, "typeOf" + typeParameter.name);
|
|
148
|
+ methodWriter.nameVariable(javaModule.getTypeParameterInfo(typeParameter).parameterIndex, "typeOf" + typeParameter.name, methodStart, methodEnd, Type.getType(Class.class));
|
|
149
|
+ }
|
|
150
|
+
|
|
151
|
+ for (final FunctionParameter parameter : member.header.parameters) {
|
|
152
|
+ methodWriter.nameParameter(0, parameter.name);
|
|
153
|
+ methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
|
|
154
|
+ }
|
|
155
|
+
|
114
|
156
|
|
115
|
157
|
{
|
116
|
158
|
final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
|
|
@@ -126,6 +168,69 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
|
126
|
168
|
|
127
|
169
|
@Override
|
128
|
170
|
public Void visitGetter(GetterMember member) {
|
|
171
|
+ final boolean isStatic = member.isStatic();
|
|
172
|
+ final StoredType returnType = member.getType();
|
|
173
|
+ final String descriptor;
|
|
174
|
+ final String signature;
|
|
175
|
+
|
|
176
|
+ final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
|
|
177
|
+ expandedClass.type.extractTypeParameters(typeParameters);
|
|
178
|
+
|
|
179
|
+ final String descMiddle, signatureMiddle, signatureStart;
|
|
180
|
+ if(typeParameters.isEmpty()) {
|
|
181
|
+ descMiddle = signatureMiddle = signatureStart = "";
|
|
182
|
+ } else {
|
|
183
|
+ final StringBuilder descMiddleBuilder = new StringBuilder();
|
|
184
|
+ final StringBuilder signatureMiddleBuilder = new StringBuilder();
|
|
185
|
+ final StringBuilder signatureStartBuilder = new StringBuilder("<");
|
|
186
|
+
|
|
187
|
+ for (TypeParameter typeParameter : typeParameters) {
|
|
188
|
+ descMiddleBuilder.append("Ljava/lang/Class;");
|
|
189
|
+ signatureMiddleBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
|
|
190
|
+ signatureStartBuilder.append(typeParameter.name).append(":Ljava/lang/Object;");
|
|
191
|
+ }
|
|
192
|
+
|
|
193
|
+ descMiddle = descMiddleBuilder.toString();
|
|
194
|
+ signatureMiddle = signatureMiddleBuilder.toString();
|
|
195
|
+ signatureStart = signatureStartBuilder.append(">").toString();
|
|
196
|
+ }
|
|
197
|
+
|
|
198
|
+ if (isStatic) {
|
|
199
|
+ descriptor = "(" + descMiddle + ")" + context.getDescriptor(returnType);
|
|
200
|
+ signature = signatureStart + "(" + signatureMiddle + ")" + context.getSignature(returnType);
|
|
201
|
+ } else {
|
|
202
|
+ descriptor = "(" + context.getDescriptor(expandedClass) + descMiddle + ")" + context.getDescriptor(returnType);
|
|
203
|
+ signature = signatureStart + "(" + context.getSignature(expandedClass) + signatureMiddle + ")" + context.getSignature(returnType);
|
|
204
|
+ }
|
|
205
|
+
|
|
206
|
+ final Label methodStart = new Label();
|
|
207
|
+ final Label methodEnd = new Label();
|
|
208
|
+
|
|
209
|
+ final JavaMethod method = context.getJavaMethod(member);
|
|
210
|
+ final JavaWriter methodWriter = new JavaWriter(member.position, this.writer, true, method, definition, true, signature, descriptor, new String[0]);
|
|
211
|
+
|
|
212
|
+ methodWriter.label(methodStart);
|
|
213
|
+
|
|
214
|
+ if (!isStatic) {
|
|
215
|
+ methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
|
|
216
|
+ methodWriter.nameParameter(0, "expandedObj");
|
|
217
|
+ }
|
|
218
|
+
|
|
219
|
+ int i = isStatic ? 0 : 1;
|
|
220
|
+ for (TypeParameter typeParameter : typeParameters) {
|
|
221
|
+ final String name = "typeOf" + typeParameter.name;
|
|
222
|
+ methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
|
|
223
|
+ methodWriter.nameParameter(0, name);
|
|
224
|
+ }
|
|
225
|
+
|
|
226
|
+ {
|
|
227
|
+ final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
|
|
228
|
+ statementVisitor.start();
|
|
229
|
+ member.body.accept(statementVisitor);
|
|
230
|
+ methodWriter.label(methodEnd);
|
|
231
|
+ statementVisitor.end();
|
|
232
|
+ }
|
|
233
|
+
|
129
|
234
|
return null;
|
130
|
235
|
}
|
131
|
236
|
|