Browse Source

- Continued implementation of interfaces in the bytecode compiler.

- Added support to have a native method both as operator and named method
Stan Hebben 5 years ago
parent
commit
aab7cc69f1

+ 2
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java View File

3984
 
3984
 
3985
 		if (methodInfo.kind == JavaMethod.Kind.STATIC) {
3985
 		if (methodInfo.kind == JavaMethod.Kind.STATIC) {
3986
 			getJavaWriter().invokeStatic(methodInfo);
3986
 			getJavaWriter().invokeStatic(methodInfo);
3987
+		} else if (methodInfo.kind == JavaMethod.Kind.INTERFACE) {
3988
+			getJavaWriter().invokeInterface(methodInfo);
3987
 		} else if (methodInfo.kind == JavaMethod.Kind.COMPILED) {
3989
 		} else if (methodInfo.kind == JavaMethod.Kind.COMPILED) {
3988
 			Objects.requireNonNull(methodInfo.translation).translate(expression, this);
3990
 			Objects.requireNonNull(methodInfo.translation).translate(expression, this);
3989
 		} else {
3991
 		} else {

+ 19
- 7
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java View File

17
 import org.openzen.zenscript.javashared.JavaClass;
17
 import org.openzen.zenscript.javashared.JavaClass;
18
 import org.openzen.zenscript.javashared.JavaCompiledModule;
18
 import org.openzen.zenscript.javashared.JavaCompiledModule;
19
 import org.openzen.zenscript.javashared.JavaField;
19
 import org.openzen.zenscript.javashared.JavaField;
20
+import org.openzen.zenscript.javashared.JavaImplementation;
20
 import org.openzen.zenscript.javashared.JavaMethod;
21
 import org.openzen.zenscript.javashared.JavaMethod;
21
 
22
 
22
 public class JavaMemberVisitor implements MemberVisitor<Void> {
23
 public class JavaMemberVisitor implements MemberVisitor<Void> {
116
 		final Label constructorEnd = new Label();
117
 		final Label constructorEnd = new Label();
117
 		final JavaWriter destructorWriter = new JavaWriter(member.position, writer, method, definition, null, null);
118
 		final JavaWriter destructorWriter = new JavaWriter(member.position, writer, method, definition, null, null);
118
 		destructorWriter.label(constructorStart);
119
 		destructorWriter.label(constructorStart);
119
-
120
+		
120
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, destructorWriter);
121
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, destructorWriter);
121
         statementVisitor.start();
122
         statementVisitor.start();
122
 		// TODO: destruction of members (to be done when memory tags are implemented)
123
 		// TODO: destruction of members (to be done when memory tags are implemented)
132
 
133
 
133
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.getEffectiveModifiers());
134
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.getEffectiveModifiers());
134
         final JavaMethod method = context.getJavaMethod(member);
135
         final JavaMethod method = context.getJavaMethod(member);
135
-
136
-		final Label methodStart = new Label();
137
-		final Label methodEnd = new Label();
138
-	    final JavaWriter methodWriter = new JavaWriter(member.position, writer, method, definition, context.getMethodSignature(member.header), null);
139
-
140
-        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
136
+		
137
+		final JavaWriter methodWriter = new JavaWriter(member.position, writer, method, definition, context.getMethodSignature(member.header), null);
141
 
138
 
142
 		if (!isAbstract) {
139
 		if (!isAbstract) {
140
+			if (method.isAbstract() || method.cls.kind == JavaClass.Kind.INTERFACE)
141
+				throw new IllegalArgumentException();
142
+			
143
+			final Label methodStart = new Label();
144
+			final Label methodEnd = new Label();
145
+		
146
+			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
147
+
143
 			statementVisitor.start();
148
 			statementVisitor.start();
144
 			member.body.accept(statementVisitor);
149
 			member.body.accept(statementVisitor);
145
 			methodWriter.label(methodEnd);
150
 			methodWriter.label(methodEnd);
180
 
185
 
181
 	@Override
186
 	@Override
182
 	public Void visitImplementation(ImplementationMember member) {
187
 	public Void visitImplementation(ImplementationMember member) {
188
+		JavaImplementation implementation = context.getJavaImplementation(member);
189
+		if (implementation.inline) {
190
+			for (IDefinitionMember imember : member.members)
191
+				imember.accept(this);
192
+		} else {
193
+			throw new UnsupportedOperationException("Non-inline interface implementations not yet available");
194
+		}
183
 		return null;
195
 		return null;
184
 	}
196
 	}
185
 
197
 

+ 24
- 4
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java View File

39
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
39
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
40
 import org.openzen.zenscript.codemodel.member.FieldMember;
40
 import org.openzen.zenscript.codemodel.member.FieldMember;
41
 import org.openzen.zenscript.codemodel.member.GetterMember;
41
 import org.openzen.zenscript.codemodel.member.GetterMember;
42
+import org.openzen.zenscript.codemodel.member.ImplementationMember;
42
 import org.openzen.zenscript.codemodel.member.MethodMember;
43
 import org.openzen.zenscript.codemodel.member.MethodMember;
43
 import org.openzen.zenscript.codemodel.member.OperatorMember;
44
 import org.openzen.zenscript.codemodel.member.OperatorMember;
44
 import org.openzen.zenscript.codemodel.member.SetterMember;
45
 import org.openzen.zenscript.codemodel.member.SetterMember;
56
 import org.openzen.zenscript.javashared.JavaClass;
57
 import org.openzen.zenscript.javashared.JavaClass;
57
 import org.openzen.zenscript.javashared.JavaCompiledModule;
58
 import org.openzen.zenscript.javashared.JavaCompiledModule;
58
 import org.openzen.zenscript.javashared.JavaField;
59
 import org.openzen.zenscript.javashared.JavaField;
60
+import org.openzen.zenscript.javashared.JavaImplementation;
59
 import org.openzen.zenscript.javashared.JavaMethod;
61
 import org.openzen.zenscript.javashared.JavaMethod;
60
 import stdlib.Strings;
62
 import stdlib.Strings;
61
 
63
 
207
 		return methodMember.ref(registry.getForDefinition(definition).stored());
209
 		return methodMember.ref(registry.getForDefinition(definition).stored());
208
 	}
210
 	}
209
 	
211
 	
212
+	private boolean isInBasePackage(String className) {
213
+		return className.startsWith(basePackage + ".");
214
+	}
215
+	
210
 	private ZSPackage getPackage(String className) {
216
 	private ZSPackage getPackage(String className) {
211
 		if (!className.contains("."))
217
 		if (!className.contains("."))
212
 			return pkg;
218
 			return pkg;
246
 				TypeID type = loadType(bound);
252
 				TypeID type = loadType(bound);
247
 				parameter.addBound(new ParameterTypeBound(CodePosition.NATIVE, type));
253
 				parameter.addBound(new ParameterTypeBound(CodePosition.NATIVE, type));
248
 			}
254
 			}
255
+			typeParameters[i] = parameter;
249
 		}
256
 		}
250
 		
257
 		
251
 		HighLevelDefinition definition;
258
 		HighLevelDefinition definition;
263
 		} else {
270
 		} else {
264
 			definition = new ClassDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC);
271
 			definition = new ClassDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC);
265
 			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
272
 			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
273
+			
274
+			if (cls.getSuperclass() != null && shouldLoadClass(cls.getSuperclass())) {
275
+				definition.setSuperType(loadType(cls.getSuperclass(), false, false));
276
+			}
277
+		}
278
+		
279
+		for (Class<?> iface : cls.getInterfaces()) {
280
+			if (shouldLoadClass(iface)) {
281
+				TypeID type = loadType(iface, false, false);
282
+				ImplementationMember member = new ImplementationMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC, type);
283
+				definition.members.add(member);
284
+				compiled.setImplementationInfo(member, new JavaImplementation(true, javaClass));
285
+			}
266
 		}
286
 		}
267
 		
287
 		
268
 		definition.typeParameters = typeParameters;
288
 		definition.typeParameters = typeParameters;
318
 				GetterMember member = asGetter(definition, method, getter);
338
 				GetterMember member = asGetter(definition, method, getter);
319
 				definition.addMember(member);
339
 				definition.addMember(member);
320
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.getType()));
340
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.getType()));
321
-				continue;
322
 			}
341
 			}
323
 			
342
 			
324
 			ZenCodeType.Setter setter = method.getAnnotation(ZenCodeType.Setter.class);
343
 			ZenCodeType.Setter setter = method.getAnnotation(ZenCodeType.Setter.class);
326
 				SetterMember member = asSetter(definition, method, setter);
345
 				SetterMember member = asSetter(definition, method, setter);
327
 				definition.addMember(member);
346
 				definition.addMember(member);
328
 				compiled.setMethodInfo(member, getMethod(javaClass, method, BasicTypeID.VOID.stored));
347
 				compiled.setMethodInfo(member, getMethod(javaClass, method, BasicTypeID.VOID.stored));
329
-				continue;
330
 			}
348
 			}
331
 			
349
 			
332
 			ZenCodeType.Operator operator = method.getAnnotation(ZenCodeType.Operator.class);
350
 			ZenCodeType.Operator operator = method.getAnnotation(ZenCodeType.Operator.class);
334
 				OperatorMember member = asOperator(definition, method, operator);
352
 				OperatorMember member = asOperator(definition, method, operator);
335
 				definition.addMember(member);
353
 				definition.addMember(member);
336
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
354
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
337
-				continue;
338
 			}
355
 			}
339
 			
356
 			
340
 			ZenCodeType.Caster caster = method.getAnnotation(ZenCodeType.Caster.class);
357
 			ZenCodeType.Caster caster = method.getAnnotation(ZenCodeType.Caster.class);
342
 				CasterMember member = asCaster(definition, method, caster);
359
 				CasterMember member = asCaster(definition, method, caster);
343
 				definition.addMember(member);
360
 				definition.addMember(member);
344
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.toType));
361
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.toType));
345
-				continue;
346
 			}
362
 			}
347
 			
363
 			
348
 			/*if (!annotated) {
364
 			/*if (!annotated) {
355
 		return definition;
371
 		return definition;
356
 	}
372
 	}
357
 	
373
 	
374
+	private boolean shouldLoadClass(Class<?> cls) {
375
+		return isInBasePackage(cls.getName());
376
+	}
377
+	
358
 	private boolean isGetterName(String name) {
378
 	private boolean isGetterName(String name) {
359
 		return name.startsWith("get") || name.startsWith("is") || name.startsWith("has");
379
 		return name.startsWith("get") || name.startsWith("is") || name.startsWith("has");
360
 	}
380
 	}

+ 5
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java View File

18
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
18
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
19
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
19
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
20
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
20
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
21
+import org.openzen.zenscript.codemodel.member.ImplementationMember;
21
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
22
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
22
 import org.openzen.zenscript.codemodel.member.ref.VariantOptionRef;
23
 import org.openzen.zenscript.codemodel.member.ref.VariantOptionRef;
23
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
24
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
184
 		return getJavaVariantOption(member.getOption());
185
 		return getJavaVariantOption(member.getOption());
185
 	}
186
 	}
186
 	
187
 	
188
+	public JavaImplementation getJavaImplementation(ImplementationMember member) {
189
+		return getJavaModule(member.definition.module).getImplementationInfo(member);
190
+	}
191
+	
187
 	public void useShared() {
192
 	public void useShared() {
188
 		if (useShared)
193
 		if (useShared)
189
 			return;
194
 			return;

+ 9
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaMethod.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.javashared;
6
 package org.openzen.zenscript.javashared;
7
 
7
 
8
+import org.openzen.zenscript.codemodel.Modifiers;
9
+
8
 /**
10
 /**
9
  *
11
  *
10
  * @author Hoofdgebruiker
12
  * @author Hoofdgebruiker
60
 	public JavaMethod(JavaClass cls, Kind kind, String name, boolean compile, String descriptor, int modifiers, boolean genericResult, boolean[] typeParameterArguments) {
62
 	public JavaMethod(JavaClass cls, Kind kind, String name, boolean compile, String descriptor, int modifiers, boolean genericResult, boolean[] typeParameterArguments) {
61
 		if (descriptor.contains("<")) // fix signature bug
63
 		if (descriptor.contains("<")) // fix signature bug
62
 			throw new IllegalArgumentException("Invalid descriptor!");
64
 			throw new IllegalArgumentException("Invalid descriptor!");
65
+		if (cls.isInterface() && !JavaModifiers.isStatic(modifiers))
66
+			kind = Kind.INTERFACE;
63
 		
67
 		
64
 		this.cls = cls;
68
 		this.cls = cls;
65
 		this.kind = kind;
69
 		this.kind = kind;
99
 		return result.toString();
103
 		return result.toString();
100
 	}
104
 	}
101
 	
105
 	
106
+	public boolean isAbstract() {
107
+		return (modifiers & Modifiers.ABSTRACT) > 0;
108
+	}
109
+	
102
 	public enum Kind {
110
 	public enum Kind {
103
 		STATIC,
111
 		STATIC,
104
 		STATICINIT,
112
 		STATICINIT,
105
 		INSTANCE,
113
 		INSTANCE,
114
+		INTERFACE,
106
 		EXPANSION,
115
 		EXPANSION,
107
 		CONSTRUCTOR,
116
 		CONSTRUCTOR,
108
 		COMPILED
117
 		COMPILED

+ 4
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaModifiers.java View File

53
 		return out;
53
 		return out;
54
 	}
54
 	}
55
 	
55
 	
56
+	public static boolean isStatic(int modifiers) {
57
+		return (modifiers & STATIC) > 0;
58
+	}
59
+	
56
 	private JavaModifiers() {}
60
 	private JavaModifiers() {}
57
 }
61
 }

+ 4
- 2
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java View File

8
 import org.openzen.zenscript.javashared.JavaNativeClass;
8
 import org.openzen.zenscript.javashared.JavaNativeClass;
9
 import org.openzen.zencode.shared.StringExpansion;
9
 import org.openzen.zencode.shared.StringExpansion;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
11
+import org.openzen.zenscript.codemodel.Modifiers;
11
 import org.openzen.zenscript.codemodel.OperatorType;
12
 import org.openzen.zenscript.codemodel.OperatorType;
12
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
13
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
13
 import org.openzen.zenscript.codemodel.member.CallerMember;
14
 import org.openzen.zenscript.codemodel.member.CallerMember;
296
 		if (nativeTag != null && nativeClass != null)
297
 		if (nativeTag != null && nativeClass != null)
297
 			method = nativeClass.getMethod(nativeTag.value);
298
 			method = nativeClass.getMethod(nativeTag.value);
298
 		
299
 		
300
+		int modifiers = cls.kind == JavaClass.Kind.INTERFACE ? JavaModifiers.ABSTRACT : 0;
299
 		if (member.getOverrides() != null) {
301
 		if (member.getOverrides() != null) {
300
 			DefinitionMemberRef base = member.getOverrides();
302
 			DefinitionMemberRef base = member.getOverrides();
301
 			
303
 			
307
 					baseMethod.name,
309
 					baseMethod.name,
308
 					true,
310
 					true,
309
 					context.getMethodDescriptor(header),
311
 					context.getMethodDescriptor(header),
310
-					JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
312
+					modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
311
 					header.getReturnType().type instanceof GenericTypeID,
313
 					header.getReturnType().type instanceof GenericTypeID,
312
 					header.useTypeParameters());
314
 					header.useTypeParameters());
313
 		} else if (method == null) {
315
 		} else if (method == null) {
317
 					name,
319
 					name,
318
 					true,
320
 					true,
319
 					context.getMethodDescriptor(header),
321
 					context.getMethodDescriptor(header),
320
-					JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
322
+					modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
321
 					header.getReturnType().type instanceof GenericTypeID,
323
 					header.getReturnType().type instanceof GenericTypeID,
322
 					header.useTypeParameters());
324
 					header.useTypeParameters());
323
 		}
325
 		}

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedEmptyFunctionBody.java View File

24
 	
24
 	
25
 	@Override
25
 	@Override
26
 	public Statement compile(StatementScope scope, FunctionHeader header) {
26
 	public Statement compile(StatementScope scope, FunctionHeader header) {
27
-		return new EmptyStatement(position);
27
+		return null;
28
 	}
28
 	}
29
 }
29
 }

+ 8
- 0
ScriptingExample/scripts/integration.zs View File

13
 	//	=> "key " + key;
13
 	//	=> "key " + key;
14
 }
14
 }
15
 
15
 
16
+class TestImplementation {
17
+	public implements TestInterface {
18
+		interfaceMethod() => "TestImplementation";
19
+	}
20
+}
21
+
16
 val testInstance = new TestOperators();
22
 val testInstance = new TestOperators();
17
 //testInstance("something");
23
 //testInstance("something");
18
 
24
 
24
 
30
 
25
 println(<test string>);
31
 println(<test string>);
26
 println(<test string>.name);
32
 println(<test string>.name);
33
+println(<test string>.interfaceMethod());
34
+println(new TestImplementation().interfaceMethod());
27
 
35
 
28
 var diamond = <item:minecraft:diamond>;
36
 var diamond = <item:minecraft:diamond>;
29
 var dirt = <item:minecraft:dirt>;
37
 var dirt = <item:minecraft:dirt>;

+ 17
- 0
ScriptingExample/scripts/interfaces.zs View File

1
+public interface MyInterface {
2
+	interfaceMethod() as string;
3
+}
4
+
5
+public class MyClass {
6
+	val name as string;
7
+	
8
+	public this(name as string) {
9
+		this.name = name;
10
+	}
11
+
12
+	public implements MyInterface {
13
+		interfaceMethod() => "InterfaceMethod " + name;
14
+	}
15
+}
16
+
17
+println(new MyClass("hello").interfaceMethod());

+ 1
- 0
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java View File

25
 		JavaNativeModule example = scriptingEngine.createNativeModule("example", "org.openzen.zenscript.scriptingexample");
25
 		JavaNativeModule example = scriptingEngine.createNativeModule("example", "org.openzen.zenscript.scriptingexample");
26
 		example.addGlobals(Globals.class);
26
 		example.addGlobals(Globals.class);
27
 		example.addClass(TestClass.class);
27
 		example.addClass(TestClass.class);
28
+		example.addClass(TestInterface.class);
28
 		scriptingEngine.registerNativeProvided(example);
29
 		scriptingEngine.registerNativeProvided(example);
29
 		
30
 		
30
 		File inputDirectory = new File("scripts");
31
 		File inputDirectory = new File("scripts");

+ 6
- 3
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestClass.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.scriptingexample;
6
 package org.openzen.zenscript.scriptingexample;
7
 
7
 
8
-import org.openzen.zencode.java.ZenCodeType;
9
-
10
 /**
8
 /**
11
  *
9
  *
12
  * @author Hoofdgebruiker
10
  * @author Hoofdgebruiker
13
  */
11
  */
14
-public class TestClass implements ZenCodeType {
12
+public class TestClass implements TestInterface {
15
 	private final String name;
13
 	private final String name;
16
 	
14
 	
17
 	@Constructor
15
 	@Constructor
39
 	public String toString() {
37
 	public String toString() {
40
 		return name;
38
 		return name;
41
 	}
39
 	}
40
+
41
+	@Override
42
+	public String interfaceMethod() {
43
+		return "Interface method of " + name;
44
+	}
42
 }
45
 }

Loading…
Cancel
Save