Procházet zdrojové kódy

- Fix crash when performing access checks between script and class

- Fix default constructor not working properly
- Fix integration classes without exposed constructor being instantiable if they have a default (non-exposed) constructor
- Fix extern methods failing validation
Stan Hebben před 6 roky
rodič
revize
dd11f65c31

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/AccessScope.java Zobrazit soubor

@@ -23,6 +23,8 @@ public final class AccessScope {
23 23
 	public boolean hasAccessTo(AccessScope other, int access) {
24 24
 		if (Modifiers.isPublic(access))
25 25
 			return true;
26
+		if (definition == null)
27
+			return false;
26 28
 		if (definition == other.definition || definition.isOuterOf(other.definition) || other.definition.isOuterOf(definition))
27 29
 			return true;
28 30
 		if (Modifiers.isPrivate(access))

+ 26
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/ClassDefinition.java Zobrazit soubor

@@ -6,8 +6,16 @@
6 6
 package org.openzen.zenscript.codemodel.definition;
7 7
 
8 8
 import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zenscript.codemodel.FunctionHeader;
9 10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
+import org.openzen.zenscript.codemodel.Modifiers;
10 12
 import org.openzen.zenscript.codemodel.Module;
13
+import org.openzen.zenscript.codemodel.member.ConstructorMember;
14
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
15
+import org.openzen.zenscript.codemodel.scope.TypeScope;
16
+import org.openzen.zenscript.codemodel.statement.BlockStatement;
17
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
18
+import org.openzen.zenscript.codemodel.type.member.BuiltinID;
11 19
 
12 20
 /**
13 21
  *
@@ -21,6 +29,24 @@ public class ClassDefinition extends HighLevelDefinition {
21 29
 	public ClassDefinition(CodePosition position, Module module, ZSPackage pkg, String name, int modifiers, HighLevelDefinition outerDefinition) {
22 30
 		super(position, module, pkg, name, modifiers, outerDefinition);
23 31
 	}
32
+	
33
+	@Override
34
+	public void normalize(TypeScope scope) {
35
+		super.normalize(scope);
36
+		
37
+		boolean hasConstructor = false;
38
+		for (IDefinitionMember member : members) {
39
+			if (member instanceof ConstructorMember) {
40
+				hasConstructor = true;
41
+				break;
42
+			}
43
+		}
44
+		
45
+		if (!hasConstructor) {
46
+			ConstructorMember constructor = new ConstructorMember(position, this, Modifiers.PUBLIC | Modifiers.EXTERN, new FunctionHeader(BasicTypeID.VOID), BuiltinID.CLASS_DEFAULT_CONSTRUCTOR);
47
+			addMember(constructor);
48
+		}
49
+	}
24 50
 
25 51
 	@Override
26 52
 	public <T> T accept(DefinitionVisitor<T> visitor) {

+ 5
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java Zobrazit soubor

@@ -57,7 +57,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
57 57
 
58 58
     @Override
59 59
     public Void visitConstructor(ConstructorMember member) {
60
-        final boolean isEnum = definition instanceof EnumDefinition;
60
+		final boolean isEnum = definition instanceof EnumDefinition;
61 61
         final JavaMethod method = context.getJavaMethod(member);
62 62
 
63 63
         final Label constructorStart = new Label();
@@ -93,7 +93,10 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
93 93
 			}
94 94
         }
95 95
 
96
-		member.body.accept(statementVisitor);
96
+		if (member.body != null) {
97
+			member.body.accept(statementVisitor);
98
+		}
99
+		
97 100
 		constructorWriter.label(constructorEnd);
98 101
 		statementVisitor.end();
99 102
 		return null;

+ 21
- 1
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java Zobrazit soubor

@@ -49,6 +49,7 @@ import org.openzen.zenscript.codemodel.type.ISymbol;
49 49
 import org.openzen.zenscript.codemodel.type.StoredType;
50 50
 import org.openzen.zenscript.codemodel.type.StringTypeID;
51 51
 import org.openzen.zenscript.codemodel.type.TypeID;
52
+import org.openzen.zenscript.codemodel.type.member.BuiltinID;
52 53
 import org.openzen.zenscript.codemodel.type.member.TypeMembers;
53 54
 import org.openzen.zenscript.codemodel.type.storage.AutoStorageTag;
54 55
 import org.openzen.zenscript.javashared.JavaClass;
@@ -76,12 +77,23 @@ public class JavaNativeModule {
76 77
 	
77 78
 	public final Map<String, ISymbol> globals = new HashMap<>();
78 79
 	
79
-	public JavaNativeModule(ZSPackage pkg, String name, String basePackage, GlobalTypeRegistry registry, boolean allowNonAnnotated) {
80
+	public JavaNativeModule(
81
+			ZSPackage pkg,
82
+			String name,
83
+			String basePackage,
84
+			GlobalTypeRegistry registry,
85
+			boolean allowNonAnnotated,
86
+			JavaNativeModule[] dependencies)
87
+	{
80 88
 		this.pkg = pkg;
81 89
 		this.basePackage = basePackage;
82 90
 		module = new Module(name);
83 91
 		this.registry = registry;
84 92
 		
93
+		for (JavaNativeModule dependency : dependencies) {
94
+			definitionByClass.putAll(dependency.definitionByClass);
95
+		}
96
+		
85 97
 		this.allowNonAnnonated = allowNonAnnotated;
86 98
 		compiled = new JavaCompiledModule(module);
87 99
 		
@@ -262,15 +274,23 @@ public class JavaNativeModule {
262 274
 			compiled.setFieldInfo(member, new JavaField(javaClass, field.getName(), getDescriptor(field.getType())));
263 275
 		}
264 276
 		
277
+		boolean hasConstructor = false;
265 278
 		for (java.lang.reflect.Constructor constructor : cls.getConstructors()) {
266 279
 			ZenCodeType.Constructor constructorAnnotation = (ZenCodeType.Constructor)constructor.getAnnotation(ZenCodeType.Constructor.class);
267 280
 			if (constructorAnnotation != null || !annotated) {
268 281
 				ConstructorMember member = asConstructor(definition, constructor);
269 282
 				definition.addMember(member);
270 283
 				compiled.setMethodInfo(member, getMethod(javaClass, constructor));
284
+				hasConstructor = true;
271 285
 			}
272 286
 		}
273 287
 		
288
+		if (!hasConstructor) {
289
+			// no constructor! make a private constructor so the compiler doesn't add one
290
+			ConstructorMember member = new ConstructorMember(CodePosition.BUILTIN, definition, Modifiers.PRIVATE, new FunctionHeader(BasicTypeID.VOID), BuiltinID.CLASS_DEFAULT_CONSTRUCTOR);
291
+			definition.addMember(member);
292
+		}
293
+		
274 294
 		for (Method method : cls.getDeclaredMethods()) {
275 295
 			ZenCodeType.Method methodAnnotation = method.getAnnotation(ZenCodeType.Method.class);
276 296
 			if (methodAnnotation != null) {

+ 1
- 1
JavaIntegration/src/main/java/org/openzen/zencode/java/ScriptingEngine.java Zobrazit soubor

@@ -63,7 +63,7 @@ public class ScriptingEngine {
63 63
 	
64 64
 	public JavaNativeModule createNativeModule(String name, String basePackage, JavaNativeModule... dependencies) {
65 65
 		ZSPackage testPackage = new ZSPackage(space.rootPackage, name);
66
-		return new JavaNativeModule(testPackage, name, basePackage, registry, false);
66
+		return new JavaNativeModule(testPackage, name, basePackage, registry, false, dependencies);
67 67
 	}
68 68
 	
69 69
 	public void registerNativeProvided(JavaNativeModule module) throws CompileException {

+ 4
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaCompiledModule.java Zobrazit soubor

@@ -9,11 +9,13 @@ import java.util.HashMap;
9 9
 import java.util.Map;
10 10
 import org.openzen.zenscript.codemodel.FunctionParameter;
11 11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
+import org.openzen.zenscript.codemodel.Modifiers;
12 13
 import org.openzen.zenscript.codemodel.Module;
13 14
 import org.openzen.zenscript.codemodel.definition.VariantDefinition;
14 15
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
15 16
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
16 17
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
18
+import org.openzen.zenscript.codemodel.type.member.BuiltinID;
17 19
 
18 20
 /**
19 21
  *
@@ -125,6 +127,8 @@ public class JavaCompiledModule {
125 127
 	
126 128
 	public JavaMethod getMethodInfo(IDefinitionMember member) {
127 129
 		JavaMethod method = methods.get(member);
130
+		if (member.getBuiltin() == BuiltinID.CLASS_DEFAULT_CONSTRUCTOR) // TODO: handle this differently
131
+			return new JavaMethod(getClassInfo(member.getDefinition()), JavaMethod.Kind.CONSTRUCTOR, "<init>", true, "()V", Modifiers.PUBLIC, false);
128 132
 		if (method == null)
129 133
 			throw new IllegalStateException("Missing method info for method " + member.getDefinition().name + "." + member.describe());
130 134
 		

+ 12
- 0
ScriptingExample/scripts/integration.zs Zobrazit soubor

@@ -3,3 +3,15 @@ import example.TestClass;
3 3
 val instance = new TestClass("Instance");
4 4
 println("Name: " + instance.name);
5 5
 instance.dump();
6
+
7
+class TestOperators {
8
+	public (name as string) as void {
9
+		println("MyTestClass: " + name);
10
+	}
11
+	
12
+	//.(key as string) as string
13
+	//	=> "key " + key;
14
+}
15
+
16
+val testInstance = new TestOperators();
17
+//testInstance("something");

+ 1
- 0
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java Zobrazit soubor

@@ -21,6 +21,7 @@ import org.openzen.zenscript.parser.expression.ParsedExpressionString;
21 21
 public class Main {
22 22
 	public static void main(String[] args) throws CompileException, ParseException, IOException {
23 23
 		ScriptingEngine scriptingEngine = new ScriptingEngine();
24
+		scriptingEngine.debug = true;
24 25
 		
25 26
 		JavaNativeModule example = scriptingEngine.createNativeModule("example", "org.openzen.zenscript.scriptingexample");
26 27
 		example.addGlobals(Globals.class);

+ 5
- 3
Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionMemberValidator.java Zobrazit soubor

@@ -119,9 +119,11 @@ public class DefinitionMemberValidator implements MemberVisitor<Void> {
119 119
 		constructors.add(member.header);
120 120
 		ValidationUtils.validateHeader(validator, member.position, member.header, member.getAccessScope());
121 121
 		
122
-		if (member.body == null && !member.isExtern()) {
123
-			validator.logError(ValidationLogEntry.Code.BODY_REQUIRED, member.position, "Constructors must have a body");
124
-			return null;
122
+		if (member.body == null) {
123
+			if (!member.isExtern()) {
124
+				validator.logError(ValidationLogEntry.Code.BODY_REQUIRED, member.position, "Constructors must have a body");
125
+				return null;
126
+			}
125 127
 		} else {
126 128
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header, member.getAccessScope()));
127 129
 			member.body.accept(statementValidator);

Loading…
Zrušit
Uložit