|
@@ -17,6 +17,7 @@ import org.openzen.zenscript.codemodel.statement.Statement;
|
17
|
17
|
import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
|
18
|
18
|
|
19
|
19
|
import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
|
|
20
|
+import org.openzen.zenscript.javabytecode.compiler.JavaScriptFile;
|
20
|
21
|
import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
|
21
|
22
|
import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
|
22
|
23
|
import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
|
|
@@ -129,7 +130,7 @@ public class JavaCompiler {
|
129
|
130
|
}
|
130
|
131
|
|
131
|
132
|
private final JavaModule target;
|
132
|
|
- private final Map<String, JavaClassWriter> scriptBlocks = new HashMap<>();
|
|
133
|
+ private final Map<String, JavaScriptFile> scriptBlocks = new HashMap<>();
|
133
|
134
|
private final JavaClassWriter scriptsClassWriter;
|
134
|
135
|
private int generatedScriptBlockCounter = 0;
|
135
|
136
|
private boolean finished = false;
|
|
@@ -141,48 +142,27 @@ public class JavaCompiler {
|
141
|
142
|
public JavaCompiler(boolean debug) {
|
142
|
143
|
target = new JavaModule();
|
143
|
144
|
|
144
|
|
- scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
|
|
145
|
+ scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
|
145
|
146
|
scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
|
146
|
147
|
}
|
147
|
148
|
|
148
|
149
|
public void addDefinition(HighLevelDefinition definition) {
|
149
|
|
- // convert definition into java class
|
150
|
|
-
|
151
|
|
- final String methodName = definition.position.filename.substring(0, definition.position.filename.lastIndexOf('.')).replace("/", "_");
|
152
|
|
-
|
153
|
|
-
|
154
|
|
- if(!scriptBlocks.containsKey(methodName)) {
|
155
|
|
- JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
|
156
|
|
- scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, methodName, null, "java/lang/Object", null);
|
157
|
|
- scriptBlocks.put(methodName, scriptFileWriter);
|
158
|
|
- }
|
159
|
|
-
|
160
|
|
- target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptBlocks.get(methodName))));
|
161
|
|
-
|
|
150
|
+ String className = getClassName(definition.position.filename);
|
|
151
|
+ JavaScriptFile scriptFile = getScriptFile(className);
|
|
152
|
+ target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptFile.classWriter)));
|
162
|
153
|
}
|
163
|
154
|
|
164
|
155
|
public void addScriptBlock(ScriptBlock script) {
|
165
|
156
|
final SourceFile sourceFile = script.getTag(SourceFile.class);
|
166
|
|
- final String methodName;
|
167
|
|
- if (sourceFile == null) {
|
168
|
|
- methodName = "generatedBlock" + (generatedScriptBlockCounter++);
|
169
|
|
- } else {
|
170
|
|
- // TODO: remove special characters
|
171
|
|
- System.out.println("Writing script: " + sourceFile.filename);
|
172
|
|
- methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
|
173
|
|
- }
|
174
|
|
-
|
175
|
|
- if(!scriptBlocks.containsKey(methodName)) {
|
176
|
|
- JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
|
177
|
|
- scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, methodName, null, "java/lang/Object", null);
|
178
|
|
- scriptBlocks.put(methodName, scriptFileWriter);
|
179
|
|
- }
|
|
157
|
+ final String className = getClassName(sourceFile == null ? null : sourceFile.filename);
|
|
158
|
+ JavaScriptFile scriptFile = getScriptFile(className);
|
180
|
159
|
|
181
|
160
|
// convert scripts into methods (add them to a Scripts class?)
|
182
|
161
|
// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
|
183
|
|
- final JavaClassWriter visitor = scriptBlocks.get(methodName);
|
184
|
|
- visitor.hasRun = true;
|
185
|
|
- JavaMethodInfo method = new JavaMethodInfo(new JavaClassInfo(methodName), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
|
|
162
|
+ final JavaClassWriter visitor = scriptFile.classWriter;
|
|
163
|
+ JavaMethodInfo method = new JavaMethodInfo(new JavaClassInfo(className), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
|
|
164
|
+ scriptFile.scriptMethods.add(method);
|
|
165
|
+
|
186
|
166
|
final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(visitor, method, null, null));
|
187
|
167
|
statementVisitor.start();
|
188
|
168
|
for (Statement statement : script.statements) {
|
|
@@ -192,6 +172,26 @@ public class JavaCompiler {
|
192
|
172
|
statementVisitor.end();
|
193
|
173
|
}
|
194
|
174
|
|
|
175
|
+ private String getClassName(String filename) {
|
|
176
|
+ if (filename == null) {
|
|
177
|
+ return "generatedBlock" + (generatedScriptBlockCounter++);
|
|
178
|
+ } else {
|
|
179
|
+ // TODO: remove special characters
|
|
180
|
+ System.out.println("Writing script: " + filename);
|
|
181
|
+ return filename.substring(0, filename.lastIndexOf('.')).replace("/", "_");
|
|
182
|
+ }
|
|
183
|
+ }
|
|
184
|
+
|
|
185
|
+ private JavaScriptFile getScriptFile(String className) {
|
|
186
|
+ if (!scriptBlocks.containsKey(className)) {
|
|
187
|
+ JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
|
|
188
|
+ scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
|
|
189
|
+ scriptBlocks.put(className, new JavaScriptFile(scriptFileWriter));
|
|
190
|
+ }
|
|
191
|
+
|
|
192
|
+ return scriptBlocks.get(className);
|
|
193
|
+ }
|
|
194
|
+
|
195
|
195
|
public JavaModule finish() {
|
196
|
196
|
if (finished)
|
197
|
197
|
throw new IllegalStateException("Already finished!");
|
|
@@ -200,13 +200,12 @@ public class JavaCompiler {
|
200
|
200
|
JavaMethodInfo runMethod = new JavaMethodInfo(new JavaClassInfo("Scripts"), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
|
201
|
201
|
final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, runMethod, null, null);
|
202
|
202
|
runWriter.start();
|
203
|
|
- for (Map.Entry<String, JavaClassWriter> entry : scriptBlocks.entrySet()) {
|
204
|
|
- final String owner = entry.getKey();
|
205
|
|
- final JavaClassWriter classWriter = entry.getValue();
|
206
|
|
- if(classWriter.hasRun)
|
207
|
|
- runWriter.invokeStatic(owner, "run", "()V");
|
208
|
|
- classWriter.visitEnd();
|
209
|
|
- target.register(owner, classWriter.toByteArray());
|
|
203
|
+ for (Map.Entry<String, JavaScriptFile> entry : scriptBlocks.entrySet()) {
|
|
204
|
+ for (JavaMethodInfo method : entry.getValue().scriptMethods)
|
|
205
|
+ runWriter.invokeStatic(method);
|
|
206
|
+
|
|
207
|
+ entry.getValue().classWriter.visitEnd();
|
|
208
|
+ target.register(entry.getKey(), entry.getValue().classWriter.toByteArray());
|
210
|
209
|
}
|
211
|
210
|
runWriter.ret();
|
212
|
211
|
runWriter.end();
|