Browse Source

Merge remote-tracking branch 'kindlich/development' into development

Stan Hebben 4 years ago
parent
commit
35e4f8585a
100 changed files with 4724 additions and 2353 deletions
  1. 2
    0
      .gitignore
  2. 11
    4
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java
  3. 4
    3
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/StatementFormatter.java
  4. 1
    1
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/TypeFormatter.java
  5. 67
    9
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  6. 91
    85
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java
  7. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java
  8. 20
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/Modifiers.java
  9. 20
    14
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/SemanticModule.java
  10. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/annotations/NativeAnnotationDefinition.java
  11. 4
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/annotations/NativeDefinitionAnnotation.java
  12. 12
    6
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java
  13. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/Expression.java
  14. 28
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/TypeParameter.java
  15. 29
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ref/FunctionalMemberRef.java
  16. 6
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialGlobalExpression.java
  17. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialMemberGroupExpression.java
  18. 17
    8
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/FileScope.java
  19. 29
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/BlockStatement.java
  20. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/DoWhileStatement.java
  21. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/ForeachStatement.java
  22. 20
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/IfStatement.java
  23. 2
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/ReturnStatement.java
  24. 28
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/SwitchStatement.java
  25. 11
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/TryCatchStatement.java
  26. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/WhileStatement.java
  27. 16
    14
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  28. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java
  29. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java
  30. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java
  31. 70
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TagRemovingTypeVisitor.java
  32. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  33. 36
    16
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberGroup.java
  34. 88
    43
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java
  35. 2
    1
      CompilerShared/src/main/java/org/openzen/zenscript/compiler/Target.java
  36. 37
    23
      Constructor/src/main/java/org/openzen/zenscript/constructor/ConstructorRegistry.java
  37. 2
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java
  38. 4
    2
      Constructor/src/main/java/org/openzen/zenscript/constructor/ModuleLoader.java
  39. 4
    3
      Constructor/src/main/java/org/openzen/zenscript/constructor/ParsedModule.java
  40. 4
    2
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java
  41. 3
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/ModuleReference.java
  42. 2
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceModule.java
  43. 9
    7
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceModuleReference.java
  44. 2
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/directory/DirectorySourceModule.java
  45. 43
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/logging/EmptyModuleLogger.java
  46. 6
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/logging/ModuleLogger.java
  47. 4
    2
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalModule.java
  48. 16
    28
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java
  49. 80
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/logging/LocalModuleLogger.java
  50. 57
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/logging/LocalValidatorLogger.java
  51. 5
    0
      JavaAnnotations/src/main/java/org/openzen/zencode/java/StorageTagType.java
  52. 11
    0
      JavaAnnotations/src/main/java/org/openzen/zencode/java/ZenCodeStorageTag.java
  53. 3
    1
      JavaAnnotations/src/main/java/org/openzen/zencode/java/ZenCodeType.java
  54. 3
    2
      JavaBytecodeCompiler/build.gradle
  55. 4
    3
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeContext.java
  56. 15
    5
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeModule.java
  57. 22
    15
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeRunUnit.java
  58. 77
    50
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java
  59. 4
    4
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/ArrayInitializerHelper.java
  60. 48
    5
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java
  61. 0
    1
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaBoxingTypeVisitor.java
  62. 399
    171
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  63. 58
    18
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachWriter.java
  64. 9
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaNonPushingExpressionVisitor.java
  65. 34
    8
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java
  66. 137
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaUnboxingTypeVisitor.java
  67. 1134
    1106
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
  68. 69
    37
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java
  69. 216
    14
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaExpansionMemberVisitor.java
  70. 154
    14
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java
  71. 0
    0
      JavaIntegration/StdLibs.jar
  72. 10
    11
      JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeLoader.java
  73. 682
    316
      JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java
  74. 68
    58
      JavaIntegration/src/main/java/org/openzen/zencode/java/ScriptingEngine.java
  75. 7
    0
      JavaIntegration/src/main/java/org/openzen/zencode/java/logger/ScriptingEngineLogger.java
  76. 83
    0
      JavaIntegration/src/main/java/org/openzen/zencode/java/logger/ScriptingEngineStreamLogger.java
  77. 3
    3
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaClass.java
  78. 2
    0
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaCompileSpace.java
  79. 12
    0
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaCompiledModule.java
  80. 57
    7
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java
  81. 0
    113
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaDefaultExpressionTypeVisitor.java
  82. 6
    1
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaField.java
  83. 18
    0
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaFunctionalInterfaceStorageTag.java
  84. 1
    1
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaMethod.java
  85. 85
    3
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeGenericVisitor.java
  86. 5
    0
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeParameterInfo.java
  87. 2
    1
      JavaShared/src/main/java/org/openzen/zenscript/javashared/SimpleJavaCompileSpace.java
  88. 30
    17
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareClassMethodVisitor.java
  89. 11
    10
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionMemberVisitor.java
  90. 18
    11
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionVisitor.java
  91. 37
    14
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareExpansionMethodVisitor.java
  92. 3
    2
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceCompiler.java
  93. 3
    2
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceContext.java
  94. 6
    6
      Parser/src/main/java/org/openzen/zenscript/lexer/CompiledDFA.java
  95. 23
    21
      Parser/src/main/java/org/openzen/zenscript/lexer/DFA.java
  96. 7
    7
      Parser/src/main/java/org/openzen/zenscript/lexer/NFA.java
  97. 3
    2
      Parser/src/main/java/org/openzen/zenscript/lexer/TokenParser.java
  98. 124
    0
      Parser/src/main/java/org/openzen/zenscript/parser/EscapableBracketParser.java
  99. 88
    0
      Parser/src/main/java/org/openzen/zenscript/parser/FolderPackage.java
  100. 0
    0
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java

+ 2
- 0
.gitignore View File

@@ -2,3 +2,5 @@
2 2
 .nb-gradle
3 3
 build
4 4
 *.class
5
+
6
+out/

+ 11
- 4
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java View File

@@ -178,9 +178,16 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
178 178
 				}
179 179
 				case INDEXGET: {
180 180
 					StringBuilder result = new StringBuilder();
181
-					result.append(expression.target);
181
+                    if(expression.target instanceof GetLocalVariableExpression) {
182
+                        result.append(((GetLocalVariableExpression) expression.target).variable.name);
183
+                    } else if(expression.target instanceof GetFunctionParameterExpression) {
184
+                        result.append(((GetFunctionParameterExpression) expression.target).parameter.name);
185
+                    } else {
186
+                        result.append(expression.target);
187
+                    }
182 188
 					result.append("[");
183
-					for (int i = 0; i < expression.arguments.arguments.length - 1; i++) {
189
+					//why -1?
190
+					for (int i = 0; i < expression.arguments.arguments.length; i++) {
184 191
 						if (i > 0)
185 192
 							result.append(", ");
186 193
 						
@@ -366,12 +373,12 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
366 373
 
367 374
 	@Override
368 375
 	public ExpressionString visitConstantDouble(ConstantDoubleExpression expression) {
369
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
376
+	    return new ExpressionString(Double.toString(expression.value), ZenScriptOperator.PRIMARY);
370 377
 	}
371 378
 
372 379
 	@Override
373 380
 	public ExpressionString visitConstantFloat(ConstantFloatExpression expression) {
374
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
381
+        return new ExpressionString(Float.toString(expression.value), ZenScriptOperator.PRIMARY);
375 382
 	}
376 383
 
377 384
 	@Override

+ 4
- 3
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/StatementFormatter.java View File

@@ -132,8 +132,8 @@ public class StatementFormatter implements StatementVisitor<Void> {
132 132
 	public Void visitExpression(ExpressionStatement statement) {
133 133
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
134 134
 		beginSingleLine(whitespace);
135
-		output.append(statement.expression.accept(expressionFormatter).value)
136
-			  .append(";");
135
+        String value = statement.expression.accept(expressionFormatter).value;
136
+        output.append(value).append(";");
137 137
 		endSingleLine(whitespace);
138 138
 		return null;
139 139
 	}
@@ -278,7 +278,8 @@ public class StatementFormatter implements StatementVisitor<Void> {
278 278
 		}
279 279
 		if (statement.initializer != null) {
280 280
 			output.append(" = ");
281
-			output.append(statement.initializer.accept(expressionFormatter).value);
281
+            String value = statement.initializer.accept(expressionFormatter).value;
282
+            output.append(value);
282 283
 		}
283 284
 		output.append(";");
284 285
 		endSingleLine(whitespace);

+ 1
- 1
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/TypeFormatter.java View File

@@ -90,7 +90,7 @@ public class TypeFormatter implements TypeVisitor<String>, GenericParameterBound
90 90
 	@Override
91 91
 	public String visitDefinition(DefinitionTypeID definition) {
92 92
 		String importedName = importer.importDefinition(definition.definition);
93
-		if (definition.typeArguments == null)
93
+		if (definition.typeArguments == null || definition.typeArguments.length == 0)
94 94
 			return importedName;
95 95
 		
96 96
 		StringBuilder result = new StringBuilder();

+ 67
- 9
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

@@ -5,12 +5,13 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel;
7 7
 
8
-import java.util.Arrays;
9
-import java.util.Map;
8
+import java.util.*;
9
+
10 10
 import org.openzen.zencode.shared.CodePosition;
11 11
 import org.openzen.zenscript.codemodel.expression.CallArguments;
12 12
 import org.openzen.zenscript.codemodel.expression.Expression;
13 13
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
14
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
14 15
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
15 16
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
16 17
 import org.openzen.zenscript.codemodel.scope.TypeScope;
@@ -165,7 +166,11 @@ public class FunctionHeader {
165 166
 	
166 167
 	public FunctionParameter getParameter(boolean isVariadic, int index) {
167 168
 		if (isVariadic && index >= parameters.length - 1) {
168
-			return parameters[parameters.length - 1];
169
+			final FunctionParameter parameter = parameters[parameters.length - 1];
170
+			if(parameter.type.type instanceof ArrayTypeID) {
171
+				return new FunctionParameter(((ArrayTypeID) parameter.type.type).elementType, parameter.name);
172
+			}
173
+			return parameter;
169 174
 		} else {
170 175
 			return parameters[index];
171 176
 		}
@@ -234,12 +239,13 @@ public class FunctionHeader {
234 239
 			return false;
235 240
 		
236 241
 		FunctionHeader header = fillGenericArguments(position, scope, arguments.typeArguments);
237
-		for (int i = 0; i < header.parameters.length; i++) {
238
-			if (!arguments.arguments[i].type.equals(header.parameters[i].type))
239
-				return false;
240
-		}
241
-		
242
-		return true;
242
+        final boolean variadicCall = header.isVariadicCall(arguments, scope);
243
+        for(int i = 0; i < arguments.arguments.length; i++) {
244
+            if(!arguments.arguments[i].type.equals(header.getParameterType(variadicCall, i)))
245
+                return false;
246
+        }
247
+        
248
+        return true;
243 249
 	}
244 250
 	
245 251
 	public boolean matchesImplicitly(CodePosition position, CallArguments arguments, TypeScope scope) {
@@ -247,6 +253,19 @@ public class FunctionHeader {
247 253
 			return false;
248 254
 		
249 255
 		FunctionHeader header = fillGenericArguments(position, scope, arguments.typeArguments);
256
+		if(isVariadic()) {
257
+		    boolean matches = true;
258
+            for (int i = 0; i < arguments.arguments.length; i++) {
259
+                if (!scope.getTypeMembers(arguments.arguments[i].type).canCastImplicit(header.getParameterType(true, i))) {
260
+                    matches = false;
261
+                    break;
262
+                }
263
+            }
264
+            if(matches) {
265
+                return true;
266
+            }
267
+        }
268
+		
250 269
 		for (int i = 0; i < arguments.arguments.length; i++) {
251 270
 			if (!scope.getTypeMembers(arguments.arguments[i].type).canCastImplicit(header.parameters[i].type))
252 271
 				return false;
@@ -514,4 +533,43 @@ public class FunctionHeader {
514 533
 	public boolean accepts(int arguments) {
515 534
 		return arguments >= this.minParameters && arguments <= this.maxParameters;
516 535
 	}
536
+    
537
+    @Override
538
+    public boolean equals(Object o) {
539
+        if(this == o)
540
+            return true;
541
+        if(o == null || getClass() != o.getClass())
542
+            return false;
543
+        
544
+        FunctionHeader that = (FunctionHeader) o;
545
+        
546
+        if(minParameters != that.minParameters)
547
+            return false;
548
+        if(maxParameters != that.maxParameters)
549
+            return false;
550
+        if(hasUnknowns != that.hasUnknowns)
551
+            return false;
552
+        if(!Arrays.equals(typeParameters, that.typeParameters))
553
+            return false;
554
+        if(!returnType.equals(that.returnType))
555
+            return false;
556
+        if(!Arrays.equals(parameters, that.parameters))
557
+            return false;
558
+        if(!Objects.equals(thrownType, that.thrownType))
559
+            return false;
560
+        return Objects.equals(storage, that.storage);
561
+    }
562
+    
563
+    @Override
564
+    public int hashCode() {
565
+        int result = Arrays.hashCode(typeParameters);
566
+        result = 31 * result + returnType.hashCode();
567
+        result = 31 * result + Arrays.hashCode(parameters);
568
+        result = 31 * result + (thrownType != null ? thrownType.hashCode() : 0);
569
+        result = 31 * result + (storage != null ? storage.hashCode() : 0);
570
+        result = 31 * result + minParameters;
571
+        result = 31 * result + maxParameters;
572
+        result = 31 * result + (hasUnknowns ? 1 : 0);
573
+        return result;
574
+    }
517 575
 }

+ 91
- 85
CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java View File

@@ -5,94 +5,100 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel;
7 7
 
8
-import java.util.Collections;
9
-import java.util.HashMap;
10
-import java.util.Map;
11
-import org.openzen.zencode.shared.CodePosition;
12
-import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
-import org.openzen.zenscript.codemodel.type.GenericTypeID;
14
-import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
15
-import org.openzen.zenscript.codemodel.type.StoredType;
8
+import org.openzen.zencode.shared.*;
9
+import org.openzen.zenscript.codemodel.generic.*;
10
+import org.openzen.zenscript.codemodel.type.*;
11
+
12
+import java.util.*;
16 13
 
17 14
 /**
18
- *
19 15
  * @author Hoofdgebruiker
20 16
  */
21 17
 public class GenericMapper {
22
-	public static final GenericMapper EMPTY = new GenericMapper(CodePosition.BUILTIN, null, Collections.emptyMap());
23
-	
24
-	public final CodePosition position;
25
-	public final GlobalTypeRegistry registry;
26
-	private final Map<TypeParameter, StoredType> mapping;
27
-	
28
-	public GenericMapper(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
29
-		if (mapping == null)
30
-			throw new IllegalArgumentException();
31
-		
32
-		this.position = position;
33
-		this.registry = registry;
34
-		this.mapping = mapping;
35
-	}
36
-	
37
-	public Map<TypeParameter, StoredType> getMapping() {
38
-		return mapping;
39
-	}
40
-	
41
-	public StoredType map(StoredType original) {
42
-		return mapping.isEmpty() ? original : original.instance(this);
43
-	}
44
-	
45
-	public StoredType[] map(StoredType[] original) {
46
-		if (mapping.isEmpty() || original.length == 0)
47
-			return original;
48
-		
49
-		StoredType[] mapped = new StoredType[original.length];
50
-		for (int i = 0; i < original.length; i++)
51
-			mapped[i] = original[i].instance(this);
52
-		return mapped;
53
-	}
54
-	
55
-	public StoredType map(GenericTypeID type) {
56
-		//if (!mapping.containsKey(type.parameter))
57
-		//	throw new IllegalStateException("No mapping found for type " + type);
58
-		
59
-		return mapping.containsKey(type.parameter) ? mapping.get(type.parameter) : type.stored();
60
-	}
61
-	
62
-	public FunctionHeader map(FunctionHeader original) {
63
-		return mapping.isEmpty() ? original : original.withGenericArguments(this);
64
-	}
65
-	
66
-	public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
67
-		Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
68
-		resultMap.putAll(mapping);
69
-		return new GenericMapper(position, registry, resultMap);
70
-	}
71
-	
72
-	public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, TypeParameter[] parameters) {
73
-		Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
74
-		for (TypeParameter parameter : parameters)
75
-			resultMap.put(parameter, new StoredType(registry.getGeneric(parameter), null));
76
-		return new GenericMapper(position, registry, resultMap);
77
-	}
78
-	
79
-	@Override
80
-	public String toString() {
81
-		if (mapping.isEmpty())
82
-			return "{}";
83
-		
84
-		StringBuilder result = new StringBuilder();
85
-		result.append('{');
86
-		boolean first = true;
87
-		for (Map.Entry<TypeParameter, StoredType> entry : mapping.entrySet()) {
88
-			if (first) {
89
-				first = false;
90
-			} else {
91
-				result.append(", ");
92
-			}
93
-			result.append(entry.getKey().toString()).append(": ").append(entry.getValue());
94
-		}
95
-		result.append('}');
96
-		return result.toString();
97
-	}
18
+    
19
+    public static final GenericMapper EMPTY = new GenericMapper(CodePosition.BUILTIN, null, Collections
20
+            .emptyMap());
21
+    
22
+    public final CodePosition position;
23
+    public final GlobalTypeRegistry registry;
24
+    private final Map<TypeParameter, StoredType> mapping;
25
+    
26
+    public GenericMapper(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
27
+        if(mapping == null)
28
+            throw new IllegalArgumentException();
29
+        
30
+        this.position = position;
31
+        this.registry = registry;
32
+        this.mapping = mapping;
33
+    }
34
+    
35
+    public Map<TypeParameter, StoredType> getMapping() {
36
+        return mapping;
37
+    }
38
+    
39
+    public StoredType map(StoredType original) {
40
+        return mapping.isEmpty() ? original : original.instance(this);
41
+    }
42
+    
43
+    public StoredType[] map(StoredType[] original) {
44
+        if(mapping.isEmpty() || original.length == 0)
45
+            return original;
46
+        
47
+        StoredType[] mapped = new StoredType[original.length];
48
+        for(int i = 0; i < original.length; i++)
49
+            mapped[i] = original[i].instance(this);
50
+        return mapped;
51
+    }
52
+    
53
+    public StoredType map(GenericTypeID type) {
54
+        //if (!mapping.containsKey(type.parameter))
55
+        //	throw new IllegalStateException("No mapping found for type " + type);
56
+        
57
+        return mapping.containsKey(type.parameter) ? mapping.get(type.parameter) : type.stored();
58
+    }
59
+    
60
+    public FunctionHeader map(FunctionHeader original) {
61
+        return mapping.isEmpty() ? original : original.withGenericArguments(this);
62
+    }
63
+    
64
+    public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
65
+        Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
66
+        mapping.forEach((typeParameter, storedType) -> {
67
+            if(resultMap.containsKey(typeParameter)) {
68
+                if(storedType.type instanceof GenericTypeID && ((GenericTypeID) storedType.type).parameter == typeParameter) {
69
+                    return;
70
+                }
71
+            }
72
+            resultMap.put(typeParameter, storedType);
73
+        });
74
+        
75
+        return new GenericMapper(position, registry, resultMap);
76
+    }
77
+    
78
+    public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, TypeParameter[] parameters) {
79
+        Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
80
+        for(TypeParameter parameter : parameters)
81
+            resultMap.put(parameter, new StoredType(registry.getGeneric(parameter), null));
82
+        return new GenericMapper(position, registry, resultMap);
83
+    }
84
+    
85
+    @Override
86
+    public String toString() {
87
+        if(mapping.isEmpty())
88
+            return "{}";
89
+        
90
+        StringBuilder result = new StringBuilder();
91
+        result.append('{');
92
+        boolean first = true;
93
+        for(Map.Entry<TypeParameter, StoredType> entry : mapping.entrySet()) {
94
+            if(first) {
95
+                first = false;
96
+            } else {
97
+                result.append(", ");
98
+            }
99
+            result.append(entry.getKey().toString()).append(": ").append(entry.getValue());
100
+        }
101
+        result.append('}');
102
+        return result.toString();
103
+    }
98 104
 }

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java View File

@@ -196,7 +196,7 @@ public abstract class HighLevelDefinition extends Taggable {
196 196
 		}
197 197
 		
198 198
 		if (isDestructible() && destructor == null && !(this instanceof ExpansionDefinition)) {
199
-			System.out.println("Added destructor to " + position);
199
+			//System.out.println("Added destructor to " + position);
200 200
 			destructor = new DestructorMember(position, this, Modifiers.PUBLIC);
201 201
 			members.add(destructor);
202 202
 		}

+ 20
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/Modifiers.java View File

@@ -81,4 +81,24 @@ public class Modifiers {
81 81
 	public static boolean hasAccess(int modifiers) {
82 82
 		return (modifiers & (PRIVATE | PUBLIC | PROTECTED | INTERNAL)) > 0;
83 83
 	}
84
+    
85
+    public static String describe(int modifiers) {
86
+        StringBuilder builder = new StringBuilder();
87
+        if (isPublic(modifiers)) {
88
+            builder.append("public");
89
+        } else if (isPrivate(modifiers)) {
90
+            builder.append("private");
91
+        } else if (isProtected(modifiers)) {
92
+            builder.append("protected");
93
+        }
94
+        if (isAbstract(modifiers)) {
95
+            builder.append(" abstract");
96
+        } else if (isFinal(modifiers)) {
97
+            builder.append(" final");
98
+        } else if (isStatic(modifiers)) {
99
+            builder.append(" static");
100
+        }
101
+        return builder.toString();
102
+    }
103
+    
84 104
 }

+ 20
- 14
CodeModel/src/main/java/org/openzen/zenscript/codemodel/SemanticModule.java View File

@@ -9,6 +9,8 @@ import java.util.ArrayList;
9 9
 import java.util.HashMap;
10 10
 import java.util.List;
11 11
 import java.util.Map;
12
+
13
+import org.openzen.zencode.shared.logging.*;
12 14
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
13 15
 import org.openzen.zenscript.codemodel.annotations.AnnotationProcessor;
14 16
 import org.openzen.zenscript.codemodel.context.ModuleContext;
@@ -43,20 +45,22 @@ public class SemanticModule {
43 45
 	public final List<ExpansionDefinition> expansions;
44 46
 	public final AnnotationDefinition[] annotations;
45 47
 	public final StorageType[] storageTypes;
48
+	public final IZSLogger logger;
46 49
 	
47 50
 	public SemanticModule(
48
-			Module module,
49
-			SemanticModule[] dependencies,
50
-			FunctionParameter[] parameters,
51
-			State state,
52
-			ZSPackage rootPackage,
53
-			ZSPackage modulePackage,
54
-			PackageDefinitions definitions,
55
-			List<ScriptBlock> scripts,
56
-			GlobalTypeRegistry registry,
57
-			List<ExpansionDefinition> expansions,
58
-			AnnotationDefinition[] annotations,
59
-			StorageType[] storageTypes)
51
+	        Module module,
52
+            SemanticModule[] dependencies,
53
+            FunctionParameter[] parameters,
54
+            State state,
55
+            ZSPackage rootPackage,
56
+            ZSPackage modulePackage,
57
+            PackageDefinitions definitions,
58
+            List<ScriptBlock> scripts,
59
+            GlobalTypeRegistry registry,
60
+            List<ExpansionDefinition> expansions,
61
+            AnnotationDefinition[] annotations,
62
+            StorageType[] storageTypes,
63
+            IZSLogger logger)
60 64
 	{
61 65
 		this.name = module.name;
62 66
 		this.module = module;
@@ -73,7 +77,8 @@ public class SemanticModule {
73 77
 		this.expansions = expansions;
74 78
 		this.annotations = annotations;
75 79
 		this.storageTypes = storageTypes;
76
-	}
80
+        this.logger = logger;
81
+    }
77 82
 	
78 83
 	public boolean isValid() {
79 84
 		return state != State.INVALID;
@@ -108,7 +113,8 @@ public class SemanticModule {
108 113
 				registry,
109 114
 				expansions,
110 115
 				annotations,
111
-				storageTypes);
116
+				storageTypes,
117
+                logger);
112 118
 	}
113 119
 	
114 120
 	public ModuleContext getContext() {

+ 4
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/annotations/NativeAnnotationDefinition.java View File

@@ -5,8 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.annotations;
7 7
 
8
-import java.util.Collections;
9
-import java.util.List;
10 8
 import org.openzen.zencode.shared.CodePosition;
11 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
12 10
 import org.openzen.zenscript.codemodel.FunctionParameter;
@@ -24,6 +22,9 @@ import org.openzen.zenscript.codemodel.statement.Statement;
24 22
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
25 23
 import org.openzen.zenscript.codemodel.type.StringTypeID;
26 24
 
25
+import java.util.Collections;
26
+import java.util.List;
27
+
27 28
 /**
28 29
  *
29 30
  * @author Hoofdgebruiker
@@ -31,7 +32,7 @@ import org.openzen.zenscript.codemodel.type.StringTypeID;
31 32
 public class NativeAnnotationDefinition implements AnnotationDefinition {
32 33
 	public static final NativeAnnotationDefinition INSTANCE = new NativeAnnotationDefinition();
33 34
 	
34
-	private static final List<FunctionHeader> INITIALIZERS = Collections.singletonList(
35
+	private final List<FunctionHeader> INITIALIZERS = Collections.singletonList(
35 36
 			new FunctionHeader(BasicTypeID.VOID, StringTypeID.UNIQUE));
36 37
 	
37 38
 	private NativeAnnotationDefinition() {}

+ 4
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/annotations/NativeDefinitionAnnotation.java View File

@@ -40,4 +40,8 @@ public class NativeDefinitionAnnotation implements DefinitionAnnotation {
40 40
 	public void serialize(CodeSerializationOutput output, HighLevelDefinition definition, TypeContext context) {
41 41
 		output.writeString(identifier);
42 42
 	}
43
+
44
+	public String getIdentifier() {
45
+		return identifier;
46
+	}
43 47
 }

+ 12
- 6
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java View File

@@ -8,9 +8,9 @@ package org.openzen.zenscript.codemodel.expression;
8 8
 import java.util.Arrays;
9 9
 import org.openzen.zencode.shared.CodePosition;
10 10
 import org.openzen.zencode.shared.CompileExceptionCode;
11
-import org.openzen.zenscript.codemodel.FunctionHeader;
11
+import org.openzen.zenscript.codemodel.*;
12 12
 import org.openzen.zenscript.codemodel.scope.TypeScope;
13
-import org.openzen.zenscript.codemodel.type.StoredType;
13
+import org.openzen.zenscript.codemodel.type.*;
14 14
 
15 15
 /**
16 16
  *
@@ -64,10 +64,16 @@ public class CallArguments {
64 64
 		if (arguments.length < header.parameters.length) {
65 65
 			Expression[] newArguments = Arrays.copyOf(arguments, header.parameters.length);
66 66
 			for (int i = arguments.length; i < header.parameters.length; i++) {
67
-				if (header.parameters[i].defaultValue == null)
68
-					newArguments[i] = new InvalidExpression(position, header.parameters[i].type, CompileExceptionCode.MISSING_PARAMETER, "Parameter missing and no default value specified");
69
-				else
70
-					newArguments[i] = header.parameters[i].defaultValue;
67
+                final FunctionParameter parameter = header.parameters[i];
68
+                if (parameter.defaultValue == null) {
69
+				    if(parameter.variadic) {
70
+				        newArguments[i] = new ArrayExpression(position, Expression.NONE, parameter.type);
71
+                    } else {
72
+                        newArguments[i] = new InvalidExpression(position, parameter.type, CompileExceptionCode.MISSING_PARAMETER, "Parameter missing and no default value specified");
73
+                    }
74
+                } else {
75
+                    newArguments[i] = parameter.defaultValue;
76
+                }
71 77
 			}
72 78
 			result = new CallArguments(typeArguments, newArguments);
73 79
 		}

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/Expression.java View File

@@ -122,11 +122,11 @@ public abstract class Expression implements IPartialExpression {
122 122
 	}
123 123
 	
124 124
 	@Override
125
-	public IPartialExpression getMember(CodePosition position, TypeScope scope, List<StoredType> hints, GenericName name) {
125
+	public IPartialExpression getMember(CodePosition position, TypeScope scope, List<StoredType> hints, GenericName name) throws CompileException {
126 126
 		TypeMembers members = scope.getTypeMembers(type);
127 127
 		IPartialExpression result = members.getMemberExpression(position, scope, this, name, false);
128 128
 		if (result == null)
129
-			System.out.println("No such member: " + name.name);
129
+		    throw new CompileException(position, CompileExceptionCode.NO_SUCH_MEMBER, "No such member: " + name.name);
130 130
 		return result;
131 131
 	}
132 132
 	

+ 28
- 4
CodeModel/src/main/java/org/openzen/zenscript/codemodel/generic/TypeParameter.java View File

@@ -5,8 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.generic;
7 7
 
8
-import java.util.ArrayList;
9
-import java.util.List;
8
+import java.util.*;
9
+
10 10
 import org.openzen.zencode.shared.CodePosition;
11 11
 import org.openzen.zencode.shared.Taggable;
12 12
 import org.openzen.zenscript.codemodel.type.TypeID;
@@ -60,8 +60,32 @@ public class TypeParameter extends Taggable {
60 60
 		}
61 61
 		return result.toString();
62 62
 	}
63
-	
64
-	@Override
63
+    
64
+    @Override
65
+    public boolean equals(Object o) {
66
+        if(this == o)
67
+            return true;
68
+        if(o == null || getClass() != o.getClass())
69
+            return false;
70
+        
71
+        TypeParameter that = (TypeParameter) o;
72
+        
73
+        if(!name.equals(that.name))
74
+            return false;
75
+        if(!Objects.equals(storage, that.storage))
76
+            return false;
77
+        return bounds.equals(that.bounds);
78
+    }
79
+    
80
+    @Override
81
+    public int hashCode() {
82
+        int result = name.hashCode();
83
+        result = 31 * result + (storage != null ? storage.hashCode() : 0);
84
+        result = 31 * result + bounds.hashCode();
85
+        return result;
86
+    }
87
+    
88
+    @Override
65 89
 	public String toString() {
66 90
 		return name + "@" + position.toShortString();
67 91
 	}

+ 29
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ref/FunctionalMemberRef.java View File

@@ -26,6 +26,8 @@ import org.openzen.zenscript.codemodel.type.StoredType;
26 26
 import org.openzen.zenscript.codemodel.type.TypeID;
27 27
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
28 28
 
29
+import java.util.*;
30
+
29 31
 /**
30 32
  *
31 33
  * @author Hoofdgebruiker
@@ -150,4 +152,31 @@ public class FunctionalMemberRef implements DefinitionMemberRef {
150 152
 	public Expression callStatic(CodePosition position, TypeID target, FunctionHeader instancedHeader, CallArguments arguments, TypeScope scope) {
151 153
 		return new CallStaticExpression(position, target, this, instancedHeader, arguments);
152 154
 	}
155
+    
156
+    @Override
157
+    public boolean equals(Object o) {
158
+        if(this == o)
159
+            return true;
160
+        if(o == null || getClass() != o.getClass())
161
+            return false;
162
+        
163
+        FunctionalMemberRef that = (FunctionalMemberRef) o;
164
+        
165
+        if(!target.equals(that.target))
166
+            return false;
167
+        if(!header.equals(that.header))
168
+            return false;
169
+        if(!type.equals(that.type))
170
+            return false;
171
+        return Objects.equals(mapper, that.mapper);
172
+    }
173
+    
174
+    @Override
175
+    public int hashCode() {
176
+        int result = target.hashCode();
177
+        result = 31 * result + header.hashCode();
178
+        result = 31 * result + type.hashCode();
179
+        result = 31 * result + (mapper != null ? mapper.hashCode() : 0);
180
+        return result;
181
+    }
153 182
 }

+ 6
- 4
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialGlobalExpression.java View File

@@ -9,10 +9,7 @@ import java.util.List;
9 9
 import org.openzen.zencode.shared.CodePosition;
10 10
 import org.openzen.zencode.shared.CompileException;
11 11
 import org.openzen.zenscript.codemodel.FunctionHeader;
12
-import org.openzen.zenscript.codemodel.expression.CallArguments;
13
-import org.openzen.zenscript.codemodel.expression.Expression;
14
-import org.openzen.zenscript.codemodel.expression.GlobalCallExpression;
15
-import org.openzen.zenscript.codemodel.expression.GlobalExpression;
12
+import org.openzen.zenscript.codemodel.expression.*;
16 13
 import org.openzen.zenscript.codemodel.scope.TypeScope;
17 14
 import org.openzen.zenscript.codemodel.GenericName;
18 15
 import org.openzen.zenscript.codemodel.type.StoredType;
@@ -63,4 +60,9 @@ public class PartialGlobalExpression implements IPartialExpression {
63 60
 	public StoredType[] getTypeArguments() {
64 61
 		return typeArguments;
65 62
 	}
63
+
64
+	@Override
65
+	public IPartialExpression capture(CodePosition position, LambdaClosure closure) {
66
+		return this;
67
+	}
66 68
 }

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialMemberGroupExpression.java View File

@@ -100,8 +100,8 @@ public class PartialMemberGroupExpression implements IPartialExpression {
100 100
 				// ignore this here
101 101
 			}
102 102
 		}
103
-		if (results.isEmpty())
104
-			System.out.println("!");
103
+		//if (results.isEmpty())
104
+		//	System.out.println("!");
105 105
 		return results;
106 106
 	}
107 107
 

+ 17
- 8
CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/FileScope.java View File

@@ -5,24 +5,21 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.scope;
7 7
 
8
-import java.util.Collections;
9
-import java.util.List;
10
-import java.util.Map;
11 8
 import org.openzen.zencode.shared.CodePosition;
12 9
 import org.openzen.zencode.shared.CompileException;
13 10
 import org.openzen.zencode.shared.CompileExceptionCode;
14
-import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
15 11
 import org.openzen.zenscript.codemodel.FunctionHeader;
16 12
 import org.openzen.zenscript.codemodel.GenericMapper;
13
+import org.openzen.zenscript.codemodel.GenericName;
14
+import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
17 15
 import org.openzen.zenscript.codemodel.context.TypeResolutionContext;
18 16
 import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
17
+import org.openzen.zenscript.codemodel.definition.ZSPackage;
18
+import org.openzen.zenscript.codemodel.expression.InvalidExpression;
19 19
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
20 20
 import org.openzen.zenscript.codemodel.partial.PartialGlobalExpression;
21 21
 import org.openzen.zenscript.codemodel.partial.PartialTypeExpression;
22 22
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
23
-import org.openzen.zenscript.codemodel.GenericName;
24
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
25
-import org.openzen.zenscript.codemodel.expression.InvalidExpression;
26 23
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
27 24
 import org.openzen.zenscript.codemodel.type.ISymbol;
28 25
 import org.openzen.zenscript.codemodel.type.StoredType;
@@ -32,6 +29,10 @@ import org.openzen.zenscript.codemodel.type.member.TypeMemberPreparer;
32 29
 import org.openzen.zenscript.codemodel.type.storage.StaticExpressionStorageTag;
33 30
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
34 31
 
32
+import java.util.Collections;
33
+import java.util.List;
34
+import java.util.Map;
35
+
35 36
 /**
36 37
  *
37 38
  * @author Hoofdgebruiker
@@ -42,7 +43,15 @@ public class FileScope extends BaseScope {
42 43
 	private final LocalMemberCache memberCache;
43 44
 	private final Map<String, ISymbol> globals;
44 45
 	private final TypeMemberPreparer preparer;
45
-	
46
+
47
+	public FileScope(
48
+			TypeResolutionContext context,
49
+			List<ExpansionDefinition> expansions,
50
+			Map<String, ISymbol> globals) {
51
+		this(context, expansions, globals, member -> {
52
+		});
53
+	}
54
+
46 55
 	public FileScope(
47 56
 			TypeResolutionContext context,
48 57
 			List<ExpansionDefinition> expansions,

+ 29
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/BlockStatement.java View File

@@ -5,12 +5,20 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.statement;
7 7
 
8
+import java.util.Arrays;
9
+import java.util.List;
10
+import java.util.Objects;
8 11
 import java.util.function.Consumer;
12
+import java.util.stream.Collectors;
13
+
9 14
 import org.openzen.zencode.shared.CodePosition;
15
+import org.openzen.zencode.shared.CompileException;
16
+import org.openzen.zencode.shared.CompileExceptionCode;
10 17
 import org.openzen.zencode.shared.ConcatMap;
11 18
 import org.openzen.zenscript.codemodel.expression.Expression;
12 19
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
13 20
 import org.openzen.zenscript.codemodel.scope.TypeScope;
21
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
14 22
 import org.openzen.zenscript.codemodel.type.StoredType;
15 23
 
16 24
 /**
@@ -84,4 +92,25 @@ public class BlockStatement extends Statement {
84 92
 			normalized[i++] = statement.normalize(scope, modified);
85 93
 		return new BlockStatement(position, normalized);
86 94
 	}
95
+
96
+	@Override
97
+	public StoredType getReturnType() {
98
+		final List<StoredType> collect = Arrays.stream(statements)
99
+				.map(Statement::getReturnType)
100
+				.filter(Objects::nonNull)
101
+				.distinct()
102
+				.collect(Collectors.toList());
103
+		if(collect.isEmpty())
104
+			return super.getReturnType();
105
+		if(collect.size() == 1)
106
+			return collect.get(0);
107
+
108
+		final long count = collect.stream().map(s -> s.type).distinct().count();
109
+		if(count == 1L)
110
+			return collect.get(0);
111
+
112
+		else
113
+			//TODO make this real?
114
+			throw new IllegalStateException("More than one possible storedType: " + count);
115
+	}
87 116
 }

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/DoWhileStatement.java View File

@@ -11,6 +11,7 @@ import org.openzen.zencode.shared.ConcatMap;
11 11
 import org.openzen.zenscript.codemodel.expression.Expression;
12 12
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
13 13
 import org.openzen.zenscript.codemodel.scope.TypeScope;
14
+import org.openzen.zenscript.codemodel.type.StoredType;
14 15
 
15 16
 /**
16 17
  *
@@ -72,4 +73,9 @@ public class DoWhileStatement extends LoopStatement {
72 73
 		result.content = content.normalize(scope, modified.concat(this, result));
73 74
 		return result;
74 75
 	}
76
+
77
+	@Override
78
+	public StoredType getReturnType() {
79
+		return content.getReturnType();
80
+	}
75 81
 }

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/ForeachStatement.java View File

@@ -12,6 +12,7 @@ import org.openzen.zenscript.codemodel.expression.Expression;
12 12
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
13 13
 import org.openzen.zenscript.codemodel.member.ref.IteratorMemberRef;
14 14
 import org.openzen.zenscript.codemodel.scope.TypeScope;
15
+import org.openzen.zenscript.codemodel.type.StoredType;
15 16
 
16 17
 /**
17 18
  *
@@ -77,4 +78,9 @@ public class ForeachStatement extends LoopStatement {
77 78
 		result.content = content.normalize(scope, modified.concat(this, result));
78 79
 		return result;
79 80
 	}
81
+
82
+	@Override
83
+	public StoredType getReturnType() {
84
+		return content.getReturnType();
85
+	}
80 86
 }

+ 20
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/IfStatement.java View File

@@ -83,4 +83,24 @@ public class IfStatement extends Statement {
83 83
 				onThen.normalize(scope, modified),
84 84
 				onElse == null ? null : onElse.normalize(scope, modified));
85 85
 	}
86
+
87
+	@Override
88
+	public StoredType getReturnType() {
89
+		final StoredType thenType = onThen.getReturnType();
90
+		if(onElse == null)
91
+			return thenType;
92
+		final StoredType elseType = onElse.getReturnType();
93
+		if(thenType == elseType)
94
+			return thenType;
95
+
96
+		if(thenType == null)
97
+			return elseType;
98
+		if(elseType == null)
99
+			return thenType;
100
+
101
+		if(thenType.type != elseType.type)
102
+			//TODO make this real?
103
+			throw new IllegalStateException("If and Else return different things?!?");
104
+		return thenType;
105
+	}
86 106
 }

+ 2
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/ReturnStatement.java View File

@@ -11,6 +11,7 @@ import org.openzen.zencode.shared.ConcatMap;
11 11
 import org.openzen.zenscript.codemodel.expression.Expression;
12 12
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
13 13
 import org.openzen.zenscript.codemodel.scope.TypeScope;
14
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
14 15
 import org.openzen.zenscript.codemodel.type.StoredType;
15 16
 
16 17
 /**
@@ -28,7 +29,7 @@ public class ReturnStatement extends Statement {
28 29
 	
29 30
 	@Override
30 31
 	public StoredType getReturnType() {
31
-		return value.type;
32
+		return value != null ? value.type : BasicTypeID.VOID.stored();
32 33
 	}
33 34
 	
34 35
 	@Override

+ 28
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/SwitchStatement.java View File

@@ -6,13 +6,18 @@
6 6
 package org.openzen.zenscript.codemodel.statement;
7 7
 
8 8
 import java.util.ArrayList;
9
+import java.util.Arrays;
9 10
 import java.util.List;
11
+import java.util.Objects;
10 12
 import java.util.function.Consumer;
13
+import java.util.stream.Collectors;
14
+
11 15
 import org.openzen.zencode.shared.CodePosition;
12 16
 import org.openzen.zencode.shared.ConcatMap;
13 17
 import org.openzen.zenscript.codemodel.expression.Expression;
14 18
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
15 19
 import org.openzen.zenscript.codemodel.scope.TypeScope;
20
+import org.openzen.zenscript.codemodel.type.StoredType;
16 21
 
17 22
 /**
18 23
  *
@@ -78,4 +83,27 @@ public class SwitchStatement extends LoopStatement {
78 83
 		}
79 84
 		return result;
80 85
 	}
86
+
87
+	@Override
88
+	public StoredType getReturnType() {
89
+		//return super.getReturnType();
90
+		final List<StoredType> collect = cases.stream()
91
+				.flatMap(aCase -> Arrays.stream(aCase.statements))
92
+				.map(Statement::getReturnType)
93
+				.filter(Objects::nonNull)
94
+				.collect(Collectors.toList());
95
+
96
+		if(collect.isEmpty())
97
+			return null;
98
+
99
+		if(collect.size() == 1)
100
+			return collect.get(0);
101
+
102
+		final long c = collect.stream().map(s -> s.type).distinct().count();
103
+		if(c == 1)
104
+			return collect.get(0);
105
+		else
106
+			//TODO make this real
107
+			throw new IllegalStateException("Too many possible types: " + c);
108
+	}
81 109
 }

+ 11
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/TryCatchStatement.java View File

@@ -12,6 +12,7 @@ import org.openzen.zencode.shared.CodePosition;
12 12
 import org.openzen.zencode.shared.ConcatMap;
13 13
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
14 14
 import org.openzen.zenscript.codemodel.scope.TypeScope;
15
+import org.openzen.zenscript.codemodel.type.StoredType;
15 16
 
16 17
 /**
17 18
  *
@@ -89,4 +90,14 @@ public class TryCatchStatement extends Statement {
89 90
 		Statement tFinallyClause = finallyClause == null ? null : finallyClause.normalize(scope, modified);
90 91
 		return new TryCatchStatement(position, tResource, tContent, tCatchClauses, tFinallyClause);
91 92
 	}
93
+
94
+	@Override
95
+	public StoredType getReturnType() {
96
+		if(finallyClause != null && finallyClause.getReturnType() != null)
97
+			return finallyClause.getReturnType();
98
+
99
+		final StoredType contentType = content.getReturnType();
100
+		//TODO check catch clauses and do stuff I guess?
101
+		return contentType;
102
+	}
92 103
 }

+ 6
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/WhileStatement.java View File

@@ -11,6 +11,7 @@ import org.openzen.zencode.shared.ConcatMap;
11 11
 import org.openzen.zenscript.codemodel.expression.Expression;
12 12
 import org.openzen.zenscript.codemodel.expression.ExpressionTransformer;
13 13
 import org.openzen.zenscript.codemodel.scope.TypeScope;
14
+import org.openzen.zenscript.codemodel.type.StoredType;
14 15
 
15 16
 /**
16 17
  *
@@ -72,4 +73,9 @@ public class WhileStatement extends LoopStatement {
72 73
 		result.content = content.normalize(scope, modified.concat(this, result));
73 74
 		return result;
74 75
 	}
76
+
77
+	@Override
78
+	public StoredType getReturnType() {
79
+		return content.getReturnType();
80
+	}
75 81
 }

+ 16
- 14
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java View File

@@ -5,14 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.type;
7 7
 
8
-import org.openzen.zenscript.codemodel.GenericName;
9
-import java.util.Arrays;
10
-import java.util.HashMap;
11
-import java.util.List;
12
-import java.util.Map;
13
-import java.util.Objects;
14
-import java.util.Set;
15 8
 import org.openzen.zenscript.codemodel.GenericMapper;
9
+import org.openzen.zenscript.codemodel.GenericName;
16 10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
17 11
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
18 12
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
@@ -21,6 +15,13 @@ import org.openzen.zenscript.codemodel.definition.VariantDefinition;
21 15
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
22 16
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
23 17
 
18
+import java.util.Arrays;
19
+import java.util.HashMap;
20
+import java.util.List;
21
+import java.util.Map;
22
+import java.util.Objects;
23
+import java.util.Set;
24
+
24 25
 /**
25 26
  *
26 27
  * @author Hoofdgebruiker
@@ -42,7 +43,7 @@ public class DefinitionTypeID implements TypeID {
42 43
 		if (typeArguments == null)
43 44
 			throw new NullPointerException("typeParameters cannot be null");
44 45
 		if (typeArguments.length != definition.getNumberOfGenericParameters())
45
-			throw new IllegalArgumentException("Wrong number of type parameters!");
46
+			throw new IllegalArgumentException("Wrong number of type parameters! " + definition.name + " expected: " + definition.getNumberOfGenericParameters() + " got: " + typeArguments.length);
46 47
 		if (definition.isInnerDefinition() && !definition.isStatic() && outer == null)
47 48
 			throw new IllegalArgumentException("Inner definition requires outer instance");
48 49
 		if ((!definition.isInnerDefinition() || definition.isStatic()) && outer != null)
@@ -100,12 +101,13 @@ public class DefinitionTypeID implements TypeID {
100 101
 		DefinitionTypeID current = this;
101 102
 		do {
102 103
 			if (current.typeArguments != null) {
103
-				if (current.definition.typeParameters == null)
104
-					System.out.println("Type parameters but no generic parameters");
105
-				else
106
-					for (int i = 0; i < current.typeArguments.length; i++)
107
-						mapping.put(current.definition.typeParameters[i], current.typeArguments[i]);
108
-			}
104
+                if(current.definition.typeParameters != null) {
105
+                    for (int i = 0; i < current.typeArguments.length; i++)
106
+                        mapping.put(current.definition.typeParameters[i], current.typeArguments[i]);
107
+                }//else {
108
+                //    System.out.println("Type parameters but no generic parameters");
109
+                //}
110
+            }
109 111
 
110 112
 			current = current.outer;
111 113
 		} while (current != null && !current.definition.isStatic());

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java View File

@@ -116,7 +116,7 @@ public class GenericTypeID implements TypeID {
116 116
 			return false;
117 117
 		}
118 118
 		final GenericTypeID other = (GenericTypeID) obj;
119
-		return this.parameter == other.parameter;
119
+		return this.parameter.equals(other.parameter);
120 120
 	}
121 121
 	
122 122
 	@Override

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.type;
7 7
 
8
+import java.util.Collection;
8 9
 import java.util.HashMap;
9 10
 import java.util.Map;
10 11
 import org.openzen.zenscript.codemodel.FunctionHeader;
@@ -110,4 +111,8 @@ public class GlobalTypeRegistry {
110 111
 			return id;
111 112
 		}
112 113
 	}
114
+
115
+	public Collection<DefinitionTypeID> getDefinitions() {
116
+		return definitionTypes.keySet();
117
+	}
113 118
 }

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java View File

@@ -124,4 +124,9 @@ public class OptionalTypeID implements TypeID {
124 124
 	public String toString(StorageTag storage) {
125 125
 		return baseType.toString(storage) + '?';
126 126
 	}
127
+    
128
+    @Override
129
+    public boolean isGeneric() {
130
+        return baseType.isGeneric();
131
+    }
127 132
 }

+ 70
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TagRemovingTypeVisitor.java View File

@@ -0,0 +1,70 @@
1
+package org.openzen.zenscript.codemodel.type.member;
2
+
3
+import org.openzen.zenscript.codemodel.type.*;
4
+
5
+import java.util.Arrays;
6
+
7
+public class TagRemovingTypeVisitor implements TypeVisitor<StoredType> {
8
+    
9
+    private final LocalMemberCache cache;
10
+    
11
+    public TagRemovingTypeVisitor(LocalMemberCache cache) {
12
+        
13
+        this.cache = cache;
14
+    }
15
+    
16
+    @Override
17
+    public StoredType visitBasic(BasicTypeID basic) {
18
+        return basic.stored;
19
+    }
20
+    
21
+    @Override
22
+    public StoredType visitString(StringTypeID string) {
23
+        return string.stored();
24
+    }
25
+    
26
+    @Override
27
+    public StoredType visitArray(ArrayTypeID array) {
28
+        return new ArrayTypeID(cache.getRegistry(), array.elementType.type.accept(this), array.dimension).stored();
29
+    }
30
+    
31
+    @Override
32
+    public StoredType visitAssoc(AssocTypeID assoc) {
33
+        return new AssocTypeID(cache.getRegistry(), assoc.keyType.type.accept(this), assoc.valueType.type.accept(this)).stored();
34
+    }
35
+    
36
+    @Override
37
+    public StoredType visitGenericMap(GenericMapTypeID map) {
38
+        return new GenericMapTypeID(cache.getRegistry(), map.value.type.accept(this), map.key).stored();
39
+    }
40
+    
41
+    @Override
42
+    public StoredType visitIterator(IteratorTypeID iterator) {
43
+        return new IteratorTypeID(cache.getRegistry(), Arrays.stream(iterator.iteratorTypes).map(storedType -> storedType.type).map(typeID -> typeID.accept(this)).toArray(StoredType[]::new)).stored();
44
+    }
45
+    
46
+    @Override
47
+    public StoredType visitFunction(FunctionTypeID function) {
48
+        return function.stored();
49
+    }
50
+    
51
+    @Override
52
+    public StoredType visitDefinition(DefinitionTypeID definition) {
53
+        return definition.stored();
54
+    }
55
+    
56
+    @Override
57
+    public StoredType visitGeneric(GenericTypeID generic) {
58
+        return generic.stored();
59
+    }
60
+    
61
+    @Override
62
+    public StoredType visitRange(RangeTypeID range) {
63
+        return new RangeTypeID(cache.getRegistry(), range.baseType.type.accept(this)).stored;
64
+    }
65
+    
66
+    @Override
67
+    public StoredType visitOptional(OptionalTypeID type) {
68
+        return new OptionalTypeID(cache.getRegistry(), type.baseType.accept(this).type).stored();
69
+    }
70
+}

+ 3
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java View File

@@ -530,6 +530,9 @@ public class TypeMemberBuilder implements TypeVisitorWithContext<Void, Void, Run
530 530
 		if (definitionType.superType != null) {
531 531
 			cache.get(definitionType.superType.stored(type.getSpecifiedStorage()))
532 532
 					.copyMembersTo(members, TypeMemberPriority.INHERITED);
533
+		} else if(definition.getSuperType() != null) {
534
+			cache.get(definition.getSuperType().stored(type.getSpecifiedStorage()))
535
+					.copyMembersTo(members, TypeMemberPriority.INHERITED);
533 536
 		} else {
534 537
 			getter(definition, OBJECT_HASHCODE, "objectHashCode", INT.stored);
535 538
 		}

+ 36
- 16
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberGroup.java View File

@@ -5,26 +5,23 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.type.member;
7 7
 
8
-import java.util.ArrayList;
9
-import java.util.List;
10
-import java.util.Map;
11 8
 import org.openzen.zencode.shared.CodePosition;
12 9
 import org.openzen.zencode.shared.CompileException;
13 10
 import org.openzen.zencode.shared.CompileExceptionCode;
11
+import org.openzen.zenscript.codemodel.CompareType;
12
+import org.openzen.zenscript.codemodel.FunctionHeader;
14 13
 import org.openzen.zenscript.codemodel.expression.CallArguments;
14
+import org.openzen.zenscript.codemodel.expression.ConstExpression;
15 15
 import org.openzen.zenscript.codemodel.expression.Expression;
16 16
 import org.openzen.zenscript.codemodel.expression.GetFieldExpression;
17 17
 import org.openzen.zenscript.codemodel.expression.GetStaticFieldExpression;
18
+import org.openzen.zenscript.codemodel.expression.InvalidExpression;
19
+import org.openzen.zenscript.codemodel.expression.PostCallExpression;
18 20
 import org.openzen.zenscript.codemodel.expression.SetFieldExpression;
19 21
 import org.openzen.zenscript.codemodel.expression.SetStaticFieldExpression;
20 22
 import org.openzen.zenscript.codemodel.expression.SetterExpression;
21 23
 import org.openzen.zenscript.codemodel.expression.StaticSetterExpression;
22 24
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
23
-import org.openzen.zenscript.codemodel.CompareType;
24
-import org.openzen.zenscript.codemodel.FunctionHeader;
25
-import org.openzen.zenscript.codemodel.expression.ConstExpression;
26
-import org.openzen.zenscript.codemodel.expression.InvalidExpression;
27
-import org.openzen.zenscript.codemodel.expression.PostCallExpression;
28 25
 import org.openzen.zenscript.codemodel.member.FunctionalMember;
29 26
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
30 27
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
@@ -35,6 +32,10 @@ import org.openzen.zenscript.codemodel.scope.TypeScope;
35 32
 import org.openzen.zenscript.codemodel.type.StoredType;
36 33
 import org.openzen.zenscript.codemodel.type.TypeID;
37 34
 
35
+import java.util.ArrayList;
36
+import java.util.List;
37
+import java.util.Map;
38
+
38 39
 /**
39 40
  *
40 41
  * @author Hoofdgebruiker
@@ -335,17 +336,30 @@ public class TypeMemberGroup {
335 336
 	
336 337
 	public FunctionalMemberRef selectMethod(CodePosition position, TypeScope scope, CallArguments arguments, boolean allowNonStatic, boolean allowStatic) throws CompileException {
337 338
 		// try to match with exact types
339
+        List<TypeMember<FunctionalMemberRef>> possibleMethods = new ArrayList<>();
338 340
 		for (TypeMember<FunctionalMemberRef> method : methods) {
339 341
 			if (!(method.member.isStatic() ? allowStatic : allowNonStatic))
340 342
 				continue;
341 343
 			
342 344
 			FunctionHeader header = method.member.getHeader().instanceForCall(position, scope.getTypeRegistry(), arguments);
343 345
 			if (header.matchesExactly(position, arguments, scope))
344
-				return method.member;
346
+			    possibleMethods.add(method);
345 347
 		}
346
-		
348
+        if (!possibleMethods.isEmpty()) {
349
+            TypeMember<FunctionalMemberRef> selectedMethod = null;
350
+            for (TypeMember<FunctionalMemberRef> method : possibleMethods) {
351
+                if (selectedMethod == null) {
352
+                    selectedMethod = method;
353
+                    continue;
354
+                }
355
+                
356
+                selectedMethod = selectedMethod.resolve(method);
357
+            }
358
+            if (selectedMethod != null)
359
+                return selectedMethod.member;
360
+        }
347 361
 		// try to match with approximate types
348
-		FunctionalMemberRef selected = null;
362
+		TypeMember<FunctionalMemberRef> selected = null;
349 363
 		for (TypeMember<FunctionalMemberRef> method : methods) {
350 364
 			if (!(method.member.isStatic() ? allowStatic : allowNonStatic))
351 365
 				continue;
@@ -358,15 +372,21 @@ public class TypeMemberGroup {
358 372
 			if (!header.matchesImplicitly(position, arguments, scope))
359 373
 				continue;
360 374
 			
361
-			if (selected != null) {
375
+			if (selected == null) {
376
+				selected = method;
377
+			} else if (selected.member.equals(method.member)) {
378
+                selected = selected.resolve(method);
379
+            } else if(selected.priority == method.priority){
362 380
 				StringBuilder explanation = new StringBuilder();
363
-				FunctionHeader selectedHeader = selected.getHeader().instanceForCall(position, scope.getTypeRegistry(), arguments);
381
+				FunctionHeader selectedHeader = selected.member.getHeader().instanceForCall(position, scope.getTypeRegistry(), arguments);
364 382
 				explanation.append("Function A: ").append(selectedHeader.toString()).append("\n");
365 383
 				explanation.append("Function B: ").append(header.toString());
366 384
 				throw new CompileException(position, CompileExceptionCode.CALL_AMBIGUOUS, "Ambiguous call; multiple methods match:\n" + explanation.toString());
385
+			} else {
386
+				//For example:
387
+				//Child overrides parent: Priority.Specified vs. Priority.Inherited
388
+				selected = selected.resolve(method);
367 389
 			}
368
-			
369
-			selected = method.member;
370 390
 		}
371 391
 		
372 392
 		if (selected == null) {
@@ -389,7 +409,7 @@ public class TypeMemberGroup {
389 409
 			throw new CompileException(position, CompileExceptionCode.CALL_NO_VALID_METHOD, "No matching method found for " + name + ":\n" + message.toString());
390 410
 		}
391 411
 		
392
-		return selected;
412
+		return selected.member;
393 413
 	}
394 414
 	
395 415
 	public FunctionalMemberRef getOverride(CodePosition position, TypeScope scope, FunctionalMember member) throws CompileException {

+ 88
- 43
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java View File

@@ -5,50 +5,22 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.type.member;
7 7
 
8
-import java.util.ArrayList;
9
-import java.util.HashMap;
10
-import java.util.List;
11
-import java.util.Map;
12
-import java.util.Set;
13 8
 import org.openzen.zencode.shared.CodePosition;
14 9
 import org.openzen.zencode.shared.CompileException;
15 10
 import org.openzen.zencode.shared.CompileExceptionCode;
16 11
 import org.openzen.zenscript.codemodel.CompareType;
12
+import org.openzen.zenscript.codemodel.GenericName;
17 13
 import org.openzen.zenscript.codemodel.OperatorType;
18
-import org.openzen.zenscript.codemodel.expression.CallArguments;
19
-import org.openzen.zenscript.codemodel.expression.CheckNullExpression;
20
-import org.openzen.zenscript.codemodel.expression.Expression;
21
-import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
22
-import org.openzen.zenscript.codemodel.expression.InvalidExpression;
23
-import org.openzen.zenscript.codemodel.expression.NullExpression;
24
-import org.openzen.zenscript.codemodel.expression.StorageCastExpression;
25
-import org.openzen.zenscript.codemodel.expression.SupertypeCastExpression;
26
-import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
14
+import org.openzen.zenscript.codemodel.expression.*;
27 15
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
28 16
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
29 17
 import org.openzen.zenscript.codemodel.member.InnerDefinition;
30
-import org.openzen.zenscript.codemodel.member.ref.CasterMemberRef;
31
-import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
32
-import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
33
-import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
34
-import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
35
-import org.openzen.zenscript.codemodel.member.ref.GetterMemberRef;
36
-import org.openzen.zenscript.codemodel.member.ref.ImplementationMemberRef;
37
-import org.openzen.zenscript.codemodel.member.ref.IteratorMemberRef;
38
-import org.openzen.zenscript.codemodel.member.ref.SetterMemberRef;
39
-import org.openzen.zenscript.codemodel.member.ref.VariantOptionRef;
40
-import org.openzen.zenscript.codemodel.partial.IPartialExpression;
41
-import org.openzen.zenscript.codemodel.partial.PartialMemberGroupExpression;
42
-import org.openzen.zenscript.codemodel.partial.PartialStaticMemberGroupExpression;
43
-import org.openzen.zenscript.codemodel.partial.PartialTypeExpression;
44
-import org.openzen.zenscript.codemodel.partial.PartialVariantOptionExpression;
45
-import org.openzen.zenscript.codemodel.type.BasicTypeID;
46
-import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
47
-import org.openzen.zenscript.codemodel.GenericName;
48
-import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
18
+import org.openzen.zenscript.codemodel.member.ref.*;
19
+import org.openzen.zenscript.codemodel.partial.*;
49 20
 import org.openzen.zenscript.codemodel.scope.TypeScope;
50
-import org.openzen.zenscript.codemodel.type.StoredType;
51
-import org.openzen.zenscript.codemodel.type.TypeID;
21
+import org.openzen.zenscript.codemodel.type.*;
22
+
23
+import java.util.*;
52 24
 
53 25
 /**
54 26
  *
@@ -84,6 +56,36 @@ public final class TypeMembers {
84 56
 	
85 57
 	public boolean extendsOrImplements(TypeID other) {
86 58
 		other = other.getNormalized();
59
+		checkBoundaries:
60
+		if(this.type.type instanceof DefinitionTypeID && other instanceof DefinitionTypeID) {
61
+			DefinitionTypeID thisTypeId = (DefinitionTypeID) this.type.type;
62
+			DefinitionTypeID otherTypeId = (DefinitionTypeID) other;
63
+
64
+			if(thisTypeId.definition != otherTypeId.definition){
65
+				break checkBoundaries;
66
+			}
67
+
68
+			if(thisTypeId.definition.typeParameters.length != otherTypeId.typeArguments.length){
69
+				break checkBoundaries;
70
+			}
71
+
72
+			for (int i = 0; i < thisTypeId.definition.typeParameters.length; i++) {
73
+				final TypeID type = otherTypeId.typeArguments[i].type;
74
+				if (type == BasicTypeID.UNDETERMINED) {
75
+					continue;
76
+				}
77
+				if (type instanceof InvalidTypeID && ((InvalidTypeID) type).code == CompileExceptionCode.TYPE_ARGUMENTS_NOT_INFERRABLE) {
78
+					continue;
79
+				}
80
+				if (thisTypeId.definition.typeParameters[i].matches(cache, type)) {
81
+					continue;
82
+				}
83
+				break checkBoundaries;
84
+			}
85
+			return true;
86
+		}
87
+
88
+
87 89
 		TypeID superType = type.type.getSuperType(cache.getRegistry());
88 90
 		if (superType != null) {
89 91
 			if (superType == other)
@@ -121,7 +123,9 @@ public final class TypeMembers {
121 123
 	
122 124
 	public void copyMembersTo(TypeMembers other, TypeMemberPriority priority) {
123 125
 		other.casters.addAll(casters);
124
-		other.iterators.addAll(iterators);
126
+        for(TypeMember<IteratorMemberRef> iterator : iterators) {
127
+            other.addIterator(iterator.member, priority);
128
+        }
125 129
 		
126 130
 		for (Map.Entry<String, EnumConstantMember> entry : enumMembers.entrySet())
127 131
 			other.addEnumMember(entry.getValue(), priority);
@@ -172,7 +176,27 @@ public final class TypeMembers {
172 176
 			return other;
173 177
 		if (cache.get(other).canCastImplicit(type))
174 178
 			return type;
175
-		
179
+
180
+
181
+		for (TypeMember<ImplementationMemberRef> implementation : this.implementations) {
182
+			final StoredType union = cache.get(implementation.member.implementsType).union(other);
183
+			if(union != null)
184
+				return union;
185
+		}
186
+
187
+		if(this.type.type instanceof ArrayTypeID && other.type instanceof ArrayTypeID) {
188
+			ArrayTypeID thisArray = (ArrayTypeID) this.type.type;
189
+			ArrayTypeID otherArray = (ArrayTypeID) other.type;
190
+
191
+			if(thisArray.dimension == otherArray.dimension) {
192
+				final StoredType union = cache.get(thisArray.elementType).union(otherArray.elementType);
193
+				if(union != null) {
194
+					return getTypeRegistry().getArray(union, thisArray.dimension).stored();
195
+				}
196
+			}
197
+		}
198
+
199
+
176 200
 		return null;
177 201
 	}
178 202
 	
@@ -410,17 +434,33 @@ public final class TypeMembers {
410 434
 			return true;
411 435
 		if (type.isOptional() && areEquivalent(type.withoutOptional(), toType))
412 436
 			return true;
413
-		
414
-		return getImplicitCaster(toType) != null || extendsOrImplements(toType.type);
437
+   
438
+		if( getImplicitCaster(toType) != null || extendsOrImplements(toType.type))
439
+		    return true;
440
+
441
+		if(type.type.isGeneric() && type.type instanceof GenericTypeID) {
442
+			final GenericTypeID genericTypeID = (GenericTypeID) type.type;
443
+			if(genericTypeID.parameter.matches(cache, toType.type)) {
444
+				return true;
445
+			}
446
+		}
447
+
448
+
449
+        final StoredType accept = type.type.accept(new TagRemovingTypeVisitor(cache));
450
+
451
+        if(!this.type.type.equals(accept.type) && cache.get(accept).canCastImplicit(toType)){
452
+            return true;
453
+        }
454
+        return false;
415 455
 	}
416 456
 	
417 457
 	private boolean areEquivalent(StoredType fromType, StoredType toType) {
418
-		if (fromType == toType)
458
+		if (fromType == toType || fromType.equals(toType))
419 459
 			return true;
420 460
 		if (!fromType.getActualStorage().canCastTo(toType.getActualStorage()) && !toType.getActualStorage().canCastFrom(fromType.getActualStorage()))
421 461
 			return false;
422 462
 		
423
-		return fromType.type == toType.type;
463
+		return fromType.type.equals(toType.type);
424 464
 	}
425 465
 	
426 466
 	public CasterMemberRef getImplicitCaster(StoredType toType) {
@@ -559,7 +599,7 @@ public final class TypeMembers {
559 599
 			if (implementation.member.implementsType.type.getNormalized() == toType.type)
560 600
 				return castEquivalent(position, new InterfaceCastExpression(position, value, implementation.member), toType);
561 601
 		}
562
-		if (extendsType(toType.type))
602
+		if (extendsOrImplements(toType.type))
563 603
 			return new SupertypeCastExpression(position, value, toType);
564 604
 		
565 605
 		return new InvalidExpression(position, toType, CompileExceptionCode.INVALID_CAST, "Could not cast " + toString() + " to " + toType);
@@ -570,7 +610,12 @@ public final class TypeMembers {
570 610
 		if (this.canCastImplicit(toType))
571 611
 			return castImplicit(position, value, toType, false);
572 612
 		
573
-		for (TypeMember<CasterMemberRef> caster : casters)
613
+        final TypeMembers typeMembers = cache.get(type.type.accept(new TagRemovingTypeVisitor(cache)));
614
+        if(this.type.type != typeMembers.type.type && typeMembers.canCast(toType)) {
615
+            return typeMembers.castExplicit(position, value, toType, optional);
616
+        }
617
+        
618
+        for (TypeMember<CasterMemberRef> caster : casters)
574 619
 			if (areEquivalent(caster.member.toType, toType))
575 620
 				return castEquivalent(position, caster.member.cast(position, value, false), toType);
576 621
 		

+ 2
- 1
CompilerShared/src/main/java/org/openzen/zenscript/compiler/Target.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.compiler;
7 7
 
8
+import org.openzen.zencode.shared.logging.*;
8 9
 import org.openzen.zenscript.codemodel.SemanticModule;
9 10
 
10 11
 /**
@@ -12,7 +13,7 @@ import org.openzen.zenscript.codemodel.SemanticModule;
12 13
  * @author Hoofdgebruiker
13 14
  */
14 15
 public interface Target {
15
-	public ZenCodeCompiler createCompiler(SemanticModule module);
16
+	public ZenCodeCompiler createCompiler(SemanticModule module, IZSLogger logger);
16 17
 	
17 18
 	public String getModule();
18 19
 	

+ 37
- 23
Constructor/src/main/java/org/openzen/zenscript/constructor/ConstructorRegistry.java View File

@@ -5,16 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.constructor;
7 7
 
8
-import java.io.File;
9
-import java.io.FileOutputStream;
10
-import java.io.IOException;
11
-import java.io.OutputStreamWriter;
12
-import java.nio.charset.StandardCharsets;
13
-import java.util.ArrayList;
14
-import java.util.HashMap;
15
-import java.util.List;
16
-import java.util.Map;
17 8
 import org.json.JSONObject;
9
+import org.openzen.zencode.shared.logging.*;
18 10
 import org.openzen.zenscript.codemodel.SemanticModule;
19 11
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
20 12
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -24,13 +16,23 @@ import org.openzen.zenscript.compiler.ZenCodeCompiler;
24 16
 import org.openzen.zenscript.javabytecode.JavaBytecodeModule;
25 17
 import org.openzen.zenscript.javabytecode.JavaBytecodeRunUnit;
26 18
 import org.openzen.zenscript.javabytecode.JavaCompiler;
27
-import org.openzen.zenscript.javashared.JavaCompileSpace;
28 19
 import org.openzen.zenscript.javashared.JavaCompiledModule;
29 20
 import org.openzen.zenscript.javashared.SimpleJavaCompileSpace;
30 21
 import org.openzen.zenscript.javasource.JavaDirectoryOutput;
31 22
 import org.openzen.zenscript.javasource.JavaSourceCompiler;
32 23
 import org.openzen.zenscript.javasource.JavaSourceModule;
33 24
 
25
+import java.io.File;
26
+import java.io.FileOutputStream;
27
+import java.io.IOException;
28
+import java.io.OutputStreamWriter;
29
+import java.lang.reflect.InvocationTargetException;
30
+import java.nio.charset.StandardCharsets;
31
+import java.util.ArrayList;
32
+import java.util.HashMap;
33
+import java.util.List;
34
+import java.util.Map;
35
+
34 36
 /**
35 37
  *
36 38
  * @author Hoofdgebruiker
@@ -74,8 +76,8 @@ public class ConstructorRegistry {
74 76
 		}
75 77
 
76 78
 		@Override
77
-		public ZenCodeCompiler createCompiler(SemanticModule module) {
78
-			return new JavaSourceZenCompiler(output, module.registry);
79
+		public ZenCodeCompiler createCompiler(SemanticModule module, IZSLogger logger) {
80
+			return new JavaSourceZenCompiler(output, module.registry, logger);
79 81
 		}
80 82
 
81 83
 		@Override
@@ -106,17 +108,19 @@ public class ConstructorRegistry {
106 108
 		
107 109
 		public final GlobalTypeRegistry registry;
108 110
 		private final SimpleJavaCompileSpace space;
111
+		private final IZSLogger logger;
109 112
 		
110
-		public JavaSourceZenCompiler(File output, GlobalTypeRegistry registry) {
113
+		public JavaSourceZenCompiler(File output, GlobalTypeRegistry registry, IZSLogger logger) {
111 114
 			this.output = output;
112 115
 			compiler = new JavaSourceCompiler(registry);
113 116
 			this.registry = registry;
114 117
 			space = new SimpleJavaCompileSpace(registry);
115
-		}
118
+            this.logger = logger;
119
+        }
116 120
 
117 121
 		@Override
118 122
 		public void addModule(SemanticModule module) {
119
-			JavaSourceModule result = compiler.compile(module, space, module.modulePackage.fullName);
123
+			JavaSourceModule result = compiler.compile(logger, module, space, module.modulePackage.fullName);
120 124
 			writeMappings(result);
121 125
 			
122 126
 			modules.add(result);
@@ -168,8 +172,8 @@ public class ConstructorRegistry {
168 172
 		}
169 173
 
170 174
 		@Override
171
-		public ZenCodeCompiler createCompiler(SemanticModule module) {
172
-			return new JavaBytecodeJarCompiler();
175
+		public ZenCodeCompiler createCompiler(SemanticModule module, IZSLogger logger) {
176
+			return new JavaBytecodeJarCompiler(logger);
173 177
 		}
174 178
 
175 179
 		@Override
@@ -198,11 +202,17 @@ public class ConstructorRegistry {
198 202
 		private final ZSPackage stdlib = new ZSPackage(root, "stdlib");
199 203
 		public final GlobalTypeRegistry registry = new GlobalTypeRegistry(stdlib);
200 204
 		
201
-		private final JavaCompiler compiler = new JavaCompiler();
205
+		private final JavaCompiler compiler;
202 206
 		private final List<JavaBytecodeModule> modules = new ArrayList<>();
203 207
 		private final SimpleJavaCompileSpace space = new SimpleJavaCompileSpace(registry);
204
-
205
-		@Override
208
+        private final IZSLogger logger;
209
+        
210
+        public JavaBytecodeJarCompiler(IZSLogger logger) {
211
+            this.logger = logger;
212
+            compiler = new JavaCompiler(logger);
213
+        }
214
+        
215
+        @Override
206 216
 		public void addModule(SemanticModule module) {
207 217
 			JavaBytecodeModule result = compiler.compile(module.modulePackage.fullName, module, space);
208 218
 			modules.add(result);
@@ -216,11 +226,15 @@ public class ConstructorRegistry {
216 226
 
217 227
 		@Override
218 228
 		public void run() {
219
-			JavaBytecodeRunUnit unit = new JavaBytecodeRunUnit();
229
+			JavaBytecodeRunUnit unit = new JavaBytecodeRunUnit(logger);
220 230
 			for (JavaBytecodeModule module : modules)
221 231
 				unit.add(module);
222 232
 			//unit.add(compiler.helpers);
223
-			unit.run();
224
-		}
233
+            try {
234
+                unit.run();
235
+            } catch(ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
236
+                e.printStackTrace();
237
+            }
238
+        }
225 239
 	}
226 240
 }

+ 2
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java View File

@@ -9,6 +9,7 @@ import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
9 9
 import org.openzen.zenscript.constructor.module.ModuleReference;
10 10
 import org.openzen.zenscript.constructor.module.SourceModuleReference;
11 11
 import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
12
+import org.openzen.zenscript.constructor.module.logging.*;
12 13
 
13 14
 public class Main {
14 15
     /**
@@ -22,7 +23,7 @@ public class Main {
22 23
 			return;
23 24
 		}
24 25
 		
25
-		Consumer<CompileException> exceptionLogger = exception -> System.err.println(exception.toString());
26
+        ModuleLogger exceptionLogger = new EmptyModuleLogger();
26 27
 		
27 28
 		File currentDirectory = new File(arguments.directory);
28 29
 		ZSPackage root = ZSPackage.createRoot();

+ 4
- 2
Constructor/src/main/java/org/openzen/zenscript/constructor/ModuleLoader.java View File

@@ -11,9 +11,11 @@ import java.util.Map;
11 11
 import java.util.Stack;
12 12
 import java.util.function.Consumer;
13 13
 import org.openzen.zencode.shared.CompileException;
14
+import org.openzen.zencode.shared.logging.*;
14 15
 import org.openzen.zenscript.codemodel.SemanticModule;
15 16
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
16 17
 import org.openzen.zenscript.constructor.module.ModuleReference;
18
+import org.openzen.zenscript.constructor.module.logging.*;
17 19
 
18 20
 /**
19 21
  *
@@ -27,9 +29,9 @@ public class ModuleLoader {
27 29
 	private final Stack<String> compilingModulesStack = new Stack<>();
28 30
 	
29 31
 	private final GlobalTypeRegistry registry;
30
-	private final Consumer<CompileException> exceptionLogger;
32
+	private final ModuleLogger exceptionLogger;
31 33
 	
32
-	public ModuleLoader(GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger) {
34
+	public ModuleLoader(GlobalTypeRegistry registry, ModuleLogger exceptionLogger) {
33 35
 		this.registry = registry;
34 36
 		this.exceptionLogger = exceptionLogger;
35 37
 	}

+ 4
- 3
Constructor/src/main/java/org/openzen/zenscript/constructor/ParsedModule.java View File

@@ -16,6 +16,7 @@ import org.json.JSONArray;
16 16
 import org.json.JSONObject;
17 17
 import org.json.JSONTokener;
18 18
 import org.openzen.zencode.shared.CompileException;
19
+import org.openzen.zencode.shared.logging.*;
19 20
 import org.openzen.zenscript.codemodel.context.CompilingPackage;
20 21
 import org.openzen.zenscript.lexer.ParseException;
21 22
 import org.openzen.zenscript.parser.BracketExpressionParser;
@@ -32,12 +33,12 @@ public class ParsedModule {
32 33
 	public final String packageName;
33 34
 	public final String javaPackageName;
34 35
 	public final String host;
35
-	private final Consumer<CompileException> exceptionLogger;
36
+	//private final CompileExceptionLogger exceptionLogger;
36 37
 	
37
-	public ParsedModule(String name, File directory, File moduleFile, Consumer<CompileException> exceptionLogger) throws IOException {
38
+	public ParsedModule(String name, File directory, File moduleFile, CompileExceptionLogger exceptionLogger) throws IOException {
38 39
 		this.name = name;
39 40
 		this.sourceDirectory = new File(directory, "src");
40
-		this.exceptionLogger = exceptionLogger;
41
+		//this.exceptionLogger = exceptionLogger;
41 42
 		
42 43
 		BufferedInputStream input = new BufferedInputStream(new FileInputStream(moduleFile));
43 44
 		JSONObject json = new JSONObject(new JSONTokener(input));

+ 4
- 2
Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java View File

@@ -8,9 +8,10 @@ package org.openzen.zenscript.constructor.module;
8 8
 import org.openzen.zenscript.constructor.module.directory.SourceDirectoryPackage;
9 9
 import java.io.File;
10 10
 import java.io.IOException;
11
+import java.lang.*;
12
+import java.lang.String;
11 13
 import java.util.ArrayList;
12 14
 import java.util.List;
13
-import java.util.function.Consumer;
14 15
 import org.json.JSONArray;
15 16
 import org.json.JSONObject;
16 17
 import org.openzen.zencode.shared.CompileException;
@@ -28,6 +29,7 @@ import org.openzen.zenscript.constructor.ParsedModule;
28 29
 import org.openzen.zenscript.constructor.ModuleLoader;
29 30
 import org.openzen.zenscript.codemodel.type.TypeSymbol;
30 31
 import org.openzen.zenscript.codemodel.type.storage.StorageType;
32
+import org.openzen.zenscript.constructor.module.logging.*;
31 33
 import org.openzen.zenscript.lexer.ParseException;
32 34
 import org.openzen.zenscript.parser.ParsedFile;
33 35
 
@@ -53,7 +55,7 @@ public class DirectoryModuleReference implements ModuleReference {
53 55
 	}
54 56
 
55 57
 	@Override
56
-	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger) {
58
+	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, ModuleLogger exceptionLogger) {
57 59
 		if (!directory.exists())
58 60
 			throw new ConstructorException("Error: module directory not found: " + directory);
59 61
 		

+ 3
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/module/ModuleReference.java View File

@@ -7,9 +7,11 @@ package org.openzen.zenscript.constructor.module;
7 7
 
8 8
 import java.util.function.Consumer;
9 9
 import org.openzen.zencode.shared.CompileException;
10
+import org.openzen.zencode.shared.logging.*;
10 11
 import org.openzen.zenscript.codemodel.SemanticModule;
11 12
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
12 13
 import org.openzen.zenscript.constructor.ModuleLoader;
14
+import org.openzen.zenscript.constructor.module.logging.*;
13 15
 
14 16
 /**
15 17
  *
@@ -18,7 +20,7 @@ import org.openzen.zenscript.constructor.ModuleLoader;
18 20
 public interface ModuleReference {
19 21
 	public String getName();
20 22
 	
21
-	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger);
23
+	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, ModuleLogger exceptionLogger);
22 24
 	
23 25
 	public SourcePackage getRootPackage();
24 26
 }

+ 2
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceModule.java View File

@@ -8,6 +8,7 @@ package org.openzen.zenscript.constructor.module;
8 8
 import java.util.Map;
9 9
 import java.util.function.Consumer;
10 10
 import org.openzen.zencode.shared.CompileException;
11
+import org.openzen.zencode.shared.logging.*;
11 12
 import org.openzen.zenscript.codemodel.SemanticModule;
12 13
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
13 14
 import org.openzen.zenscript.codemodel.type.ISymbol;
@@ -22,7 +23,7 @@ public interface SourceModule {
22 23
 	
23 24
 	public SourcePackage getRootPackage();
24 25
 	
25
-	public SemanticModule[] loadDependencies(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger);
26
+	public SemanticModule[] loadDependencies(ModuleLoader loader, GlobalTypeRegistry registry, CompileExceptionLogger exceptionLogger);
26 27
 	
27 28
 	public Map<String, ISymbol> getGlobals(SemanticModule module);
28 29
 }

+ 9
- 7
Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceModuleReference.java View File

@@ -11,6 +11,7 @@ import java.util.function.Consumer;
11 11
 import org.openzen.zencode.shared.CompileException;
12 12
 import org.openzen.zencode.shared.CompileExceptionCode;
13 13
 import org.openzen.zencode.shared.SourceFile;
14
+import org.openzen.zencode.shared.logging.*;
14 15
 import org.openzen.zenscript.codemodel.FunctionParameter;
15 16
 import org.openzen.zenscript.codemodel.Module;
16 17
 import org.openzen.zenscript.codemodel.ModuleSpace;
@@ -21,6 +22,7 @@ import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
21 22
 import org.openzen.zenscript.constructor.ConstructorException;
22 23
 import org.openzen.zenscript.constructor.ModuleLoader;
23 24
 import org.openzen.zenscript.codemodel.type.storage.StorageType;
25
+import org.openzen.zenscript.constructor.module.logging.*;
24 26
 import org.openzen.zenscript.lexer.ParseException;
25 27
 import org.openzen.zenscript.parser.BracketExpressionParser;
26 28
 import org.openzen.zenscript.parser.ParsedFile;
@@ -48,8 +50,8 @@ public class SourceModuleReference implements ModuleReference {
48 50
 	}
49 51
 
50 52
 	@Override
51
-	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger) {
52
-		SemanticModule[] dependencies = module.loadDependencies(loader, registry, exceptionLogger);
53
+	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, ModuleLogger logger) {
54
+		SemanticModule[] dependencies = module.loadDependencies(loader, registry, logger);
53 55
 
54 56
 		ModuleSpace space = new ModuleSpace(registry, new ArrayList<>(), StorageType.getStandard());
55 57
 		for (SemanticModule module : dependencies) {
@@ -64,8 +66,8 @@ public class SourceModuleReference implements ModuleReference {
64 66
 		Module module = new Module(getName());
65 67
 		CompilingPackage compilingPackage = new CompilingPackage(pkg, module);
66 68
 
67
-		ParsedFile[] parsedFiles = parse(compilingPackage, exceptionLogger);
68
-		SemanticModule result = ParsedFile.compileSyntaxToSemantic(dependencies, compilingPackage, parsedFiles, space, FunctionParameter.NONE, exceptionLogger);
69
+		ParsedFile[] parsedFiles = parse(compilingPackage, logger);
70
+		SemanticModule result = ParsedFile.compileSyntaxToSemantic(dependencies, compilingPackage, parsedFiles, space, FunctionParameter.NONE, logger);
69 71
 		result.globals.putAll(this.module.getGlobals(result));
70 72
 		return result;
71 73
 	}
@@ -75,19 +77,19 @@ public class SourceModuleReference implements ModuleReference {
75 77
 		return module.getRootPackage();
76 78
 	}
77 79
 	
78
-	public ParsedFile[] parse(CompilingPackage compilingPackage, Consumer<CompileException> exceptionLogger) {
80
+	public ParsedFile[] parse(CompilingPackage compilingPackage, CompileExceptionLogger exceptionLogger) {
79 81
 		// TODO: load bracket parsers from host plugins
80 82
 		List<ParsedFile> files = new ArrayList<>();
81 83
 		parse(files, compilingPackage, null, module.getRootPackage(), exceptionLogger);
82 84
 		return files.toArray(new ParsedFile[files.size()]);
83 85
 	}
84 86
 	
85
-	private static void parse(List<ParsedFile> files, CompilingPackage pkg, BracketExpressionParser bracketParser, SourcePackage directory, Consumer<CompileException> exceptionLogger) {
87
+	private static void parse(List<ParsedFile> files, CompilingPackage pkg, BracketExpressionParser bracketParser, SourcePackage directory, CompileExceptionLogger exceptionLogger) {
86 88
 		for (SourceFile file : directory.getFiles()) {
87 89
 			try {
88 90
 				files.add(ParsedFile.parse(pkg, bracketParser, file));
89 91
 			} catch (ParseException ex) {
90
-				exceptionLogger.accept(new CompileException(ex.position, CompileExceptionCode.PARSE_ERROR, ex.message));
92
+				exceptionLogger.logCompileException(new CompileException(ex.position, CompileExceptionCode.PARSE_ERROR, ex.message));
91 93
 			}
92 94
 		}
93 95
 		for (SourcePackage subpkg : directory.getSubPackages()) {

+ 2
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/module/directory/DirectorySourceModule.java View File

@@ -16,6 +16,7 @@ import java.util.function.Consumer;
16 16
 import org.json.JSONArray;
17 17
 import org.json.JSONObject;
18 18
 import org.openzen.zencode.shared.CompileException;
19
+import org.openzen.zencode.shared.logging.*;
19 20
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
20 21
 import org.openzen.zenscript.codemodel.ModuleSpace;
21 22
 import org.openzen.zenscript.codemodel.SemanticModule;
@@ -75,7 +76,7 @@ public class DirectorySourceModule implements SourceModule {
75 76
 	}
76 77
 
77 78
 	@Override
78
-	public SemanticModule[] loadDependencies(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger) {
79
+	public SemanticModule[] loadDependencies(ModuleLoader loader, GlobalTypeRegistry registry, CompileExceptionLogger exceptionLogger) {
79 80
 		List<String> dependencyNames = new ArrayList<>();
80 81
 		if (!isStdLib)
81 82
 			dependencyNames.add("stdlib");

+ 43
- 0
Constructor/src/main/java/org/openzen/zenscript/constructor/module/logging/EmptyModuleLogger.java View File

@@ -0,0 +1,43 @@
1
+package org.openzen.zenscript.constructor.module.logging;
2
+
3
+import org.openzen.zencode.shared.*;
4
+
5
+public class EmptyModuleLogger implements ModuleLogger {
6
+    
7
+    @Override
8
+    public void logCompileException(CompileException exception) {
9
+        error(exception.getMessage());
10
+    }
11
+    
12
+    @Override
13
+    public void info(String message) {
14
+        System.out.println(message);
15
+    }
16
+    
17
+    @Override
18
+    public void debug(String message) {
19
+        System.out.println(message);
20
+    }
21
+    
22
+    @Override
23
+    public void warning(String message) {
24
+        System.out.println(message);
25
+    }
26
+    
27
+    @Override
28
+    public void error(String message) {
29
+        System.err.println(message);
30
+    }
31
+    
32
+    @Override
33
+    public void throwingErr(String message, Throwable throwable) {
34
+        System.err.println(message);
35
+        throwable.printStackTrace();
36
+    }
37
+    
38
+    @Override
39
+    public void throwingWarn(String message, Throwable throwable) {
40
+        System.out.println(message);
41
+        throwable.printStackTrace(System.out);
42
+    }
43
+}

+ 6
- 0
Constructor/src/main/java/org/openzen/zenscript/constructor/module/logging/ModuleLogger.java View File

@@ -0,0 +1,6 @@
1
+package org.openzen.zenscript.constructor.module.logging;
2
+
3
+import org.openzen.zencode.shared.logging.*;
4
+import org.openzen.zenscript.parser.logger.*;
5
+
6
+public interface ModuleLogger extends CompileExceptionLogger, ParserLogger {}

+ 4
- 2
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalModule.java View File

@@ -13,7 +13,9 @@ import org.openzen.zenscript.ide.host.IDECodeError;
13 13
 import org.openzen.zenscript.ide.host.IDEModule;
14 14
 import org.openzen.zenscript.ide.host.IDEModuleType;
15 15
 import org.openzen.zenscript.ide.host.IDEPackage;
16
-import org.openzen.zenscript.validator.Validator;
16
+import org.openzen.zenscript.ide.host.local.logging.*;
17
+import org.openzen.zenscript.validator.*;
18
+import org.openzen.zenscript.validator.logger.*;
17 19
 
18 20
 /**
19 21
  *
@@ -46,6 +48,6 @@ public class LocalModule implements IDEModule {
46 48
 	@Override
47 49
 	public void prebuild(ModuleLoader loader, Consumer<IDECodeError> errors) {
48 50
 		SemanticModule module = loader.getModule(this.module.getName());
49
-		Validator.validate(module, entry -> errors.accept(new IDECodeError(null, entry.position, entry.message)));
51
+		Validator.validate(module, new LocalValidatorLogger(errors));
50 52
 	}
51 53
 }

+ 16
- 28
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java View File

@@ -12,6 +12,7 @@ import java.util.Stack;
12 12
 import java.util.function.Consumer;
13 13
 import live.LiveObject;
14 14
 import live.SimpleLiveObject;
15
+import org.openzen.zencode.shared.logging.*;
15 16
 import org.openzen.zenscript.codemodel.SemanticModule;
16 17
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
17 18
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -23,14 +24,17 @@ import org.openzen.zenscript.constructor.Project;
23 24
 import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
24 25
 import org.openzen.zenscript.constructor.module.ModuleReference;
25 26
 import org.openzen.zenscript.constructor.module.SourceModuleReference;
27
+import org.openzen.zenscript.constructor.module.logging.*;
26 28
 import org.openzen.zenscript.ide.host.IDECodeError;
27 29
 import org.openzen.zenscript.ide.host.IDECompileState;
28 30
 import org.openzen.zenscript.ide.host.IDESourceFile;
29 31
 import org.openzen.zenscript.ide.host.IDETarget;
30
-import org.openzen.zenscript.ide.ui.view.output.ErrorOutputSpan;
31
-import org.openzen.zenscript.ide.ui.view.output.OutputLine;
32
+import org.openzen.zenscript.ide.host.local.logging.*;
33
+import org.openzen.zenscript.ide.ui.view.output.*;
34
+import org.openzen.zenscript.parser.logger.*;
32 35
 import org.openzen.zenscript.validator.ValidationLogEntry;
33 36
 import org.openzen.zenscript.validator.Validator;
37
+import org.openzen.zenscript.validator.logger.*;
34 38
 import stdlib.Strings;
35 39
 
36 40
 /**
@@ -92,30 +96,14 @@ public class LocalTarget implements IDETarget {
92 96
 		ZSPackage root = ZSPackage.createRoot();
93 97
 		ZSPackage stdlibPackage = new ZSPackage(root, "stdlib");
94 98
 		GlobalTypeRegistry registry = new GlobalTypeRegistry(stdlibPackage);
95
-		
96
-		ModuleLoader moduleLoader = new ModuleLoader(registry, exception -> {
97
-			IDESourceFile sourceFile = new LocalSourceFile(exception.position.file);
98
-			state.addError(sourceFile, new IDECodeError(sourceFile, exception.position, exception.message));
99
-			
100
-			String[] lines = Strings.split(exception.getMessage(), '\n');
101
-			for (String line : lines) {
102
-				output.accept(new OutputLine(new ErrorOutputSpan(line)));
103
-			}
104
-		});
99
+        final LocalModuleLogger localModuleLogger = new LocalModuleLogger(state, output);
100
+        ModuleLoader moduleLoader = new ModuleLoader(registry, localModuleLogger);
101
+        
105 102
 		//moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
106 103
 		moduleLoader.register("stdlib", new SourceModuleReference(new DirectorySourceModule("stdlib", new File("../../StdLibs/stdlib"), true), true));
107 104
 		Set<String> compiledModules = new HashSet<>();
108
-		
109
-		Consumer<ValidationLogEntry> validationLogger = entry -> {
110
-			String[] message = Strings.split(entry.message, '\n');
111
-			output.accept(new OutputLine(new ErrorOutputSpan(entry.kind + " " + entry.position.toString() + ": " + message[0])));
112
-			for (int i = 1; i < message.length; i++)
113
-				output.accept(new OutputLine(new ErrorOutputSpan("    " + message[i])));
114
-			
115
-			IDESourceFile sourceFile = new LocalSourceFile(entry.position.file);
116
-			state.addError(sourceFile, new IDECodeError(sourceFile, entry.position, entry.message));
117
-		};
118
-		try {
105
+        
106
+        try {
119 107
 			for (Library library : project.libraries) {
120 108
 				for (ModuleReference module : library.modules)
121 109
 					moduleLoader.register(module.getName(), module);
@@ -125,22 +113,22 @@ public class LocalTarget implements IDETarget {
125 113
 			}
126 114
 			
127 115
 			SemanticModule module = moduleLoader.getModule(target.getModule());
128
-			module = Validator.validate(module.normalize(), validationLogger);
116
+			module = Validator.validate(module.normalize(), localModuleLogger);
129 117
 			
130 118
 			if (compile) {
131
-				ZenCodeCompiler compiler = target.createCompiler(module);
119
+				ZenCodeCompiler compiler = target.createCompiler(module, localModuleLogger);
132 120
 				if (!module.isValid())
133 121
 					return compiler;
134 122
 
135 123
 				SemanticModule stdlib = moduleLoader.getModule("stdlib");
136
-				stdlib = Validator.validate(stdlib.normalize(), validationLogger);
124
+				stdlib = Validator.validate(stdlib.normalize(), localModuleLogger);
137 125
 				if (!stdlib.isValid())
138 126
 					return compiler;
139 127
 
140 128
 				compiler.addModule(stdlib);
141 129
 				compiledModules.add(stdlib.name);
142 130
 
143
-				boolean isValid = compileDependencies(moduleLoader, compiler, compiledModules, new Stack<>(), module, validationLogger);
131
+				boolean isValid = compileDependencies(moduleLoader, compiler, compiledModules, new Stack<>(), module, localModuleLogger);
144 132
 				if (!isValid)
145 133
 					return compiler;
146 134
 
@@ -169,7 +157,7 @@ public class LocalTarget implements IDETarget {
169 157
 		}
170 158
 	}
171 159
 	
172
-	private boolean compileDependencies(ModuleLoader loader, ZenCodeCompiler compiler, Set<String> compiledModules, Stack<String> compilingModules, SemanticModule module, Consumer<ValidationLogEntry> logger) {
160
+	private boolean compileDependencies(ModuleLoader loader, ZenCodeCompiler compiler, Set<String> compiledModules, Stack<String> compilingModules, SemanticModule module, ValidatorLogger logger) {
173 161
 		for (SemanticModule dependency : module.dependencies) {
174 162
 			if (compiledModules.contains(dependency.name))
175 163
 				continue;

+ 80
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/local/logging/LocalModuleLogger.java View File

@@ -0,0 +1,80 @@
1
+package org.openzen.zenscript.ide.host.local.logging;
2
+
3
+import org.openzen.zencode.shared.*;
4
+import org.openzen.zenscript.constructor.module.logging.*;
5
+import org.openzen.zenscript.ide.host.*;
6
+import org.openzen.zenscript.ide.host.local.*;
7
+import org.openzen.zenscript.ide.ui.view.output.*;
8
+import org.openzen.zenscript.validator.*;
9
+import org.openzen.zenscript.validator.logger.*;
10
+import stdlib.*;
11
+
12
+import java.util.function.*;
13
+
14
+public class LocalModuleLogger implements ModuleLogger, ValidatorLogger {
15
+    
16
+    private final LocalCompileState state;
17
+    private final Consumer<OutputLine> output;
18
+    
19
+    public LocalModuleLogger(LocalCompileState state, Consumer<OutputLine> output) {
20
+        this.state = state;
21
+        this.output = output;
22
+    }
23
+    
24
+    @Override
25
+    public void logCompileException(CompileException exception) {
26
+        IDESourceFile sourceFile = new LocalSourceFile(exception.position.file);
27
+        state.addError(sourceFile, new IDECodeError(sourceFile, exception.position, exception.message));
28
+        
29
+        String[] lines = Strings.split(exception.getMessage(), '\n');
30
+        for(String line : lines) {
31
+            output.accept(new OutputLine(new ErrorOutputSpan(line)));
32
+        }
33
+    }
34
+    
35
+    @Override
36
+    public void info(String message) {
37
+        output.accept(new OutputLine(new BasicOutputSpan(message)));
38
+    }
39
+    
40
+    @Override
41
+    public void debug(String message) {
42
+        output.accept(new OutputLine(new BasicOutputSpan(message)));
43
+    }
44
+    
45
+    @Override
46
+    public void warning(String message) {
47
+        output.accept(new OutputLine(new BasicOutputSpan(message)));
48
+    }
49
+    
50
+    @Override
51
+    public void error(String message) {
52
+        output.accept(new OutputLine(new ErrorOutputSpan(message)));
53
+    }
54
+    
55
+    @Override
56
+    public void throwingErr(String message, Throwable throwable) {
57
+        output.accept(new OutputLine(new ErrorOutputSpan(message)));
58
+    }
59
+    
60
+    @Override
61
+    public void throwingWarn(String message, Throwable throwable) {
62
+        output.accept(new OutputLine(new BasicOutputSpan(message)));
63
+    }
64
+    
65
+    @Override
66
+    public void logValidationError(ValidationLogEntry entry) {
67
+        String[] message = Strings.split(entry.message, '\n');
68
+        output.accept(new OutputLine(new ErrorOutputSpan(entry.kind + " " + entry.position.toString() + ": " + message[0])));
69
+        for(int i = 1; i < message.length; i++)
70
+            output.accept(new OutputLine(new ErrorOutputSpan("    " + message[i])));
71
+        
72
+        IDESourceFile sourceFile = new LocalSourceFile(entry.position.file);
73
+        state.addError(sourceFile, new IDECodeError(sourceFile, entry.position, entry.message));
74
+    }
75
+    
76
+    @Override
77
+    public void logValidationWarning(ValidationLogEntry warningEntry) {
78
+        logValidationError(warningEntry);
79
+    }
80
+}

+ 57
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/local/logging/LocalValidatorLogger.java View File

@@ -0,0 +1,57 @@
1
+package org.openzen.zenscript.ide.host.local.logging;
2
+
3
+import org.openzen.zenscript.ide.host.*;
4
+import org.openzen.zenscript.validator.*;
5
+import org.openzen.zenscript.validator.logger.*;
6
+
7
+import java.util.function.*;
8
+
9
+public class LocalValidatorLogger implements ValidatorLogger {
10
+    
11
+    private final Consumer<IDECodeError> errors;
12
+    
13
+    public LocalValidatorLogger(Consumer<IDECodeError> errors) {
14
+        this.errors = errors;
15
+    }
16
+    
17
+    @Override
18
+    public void info(String message) {
19
+        throw new UnsupportedOperationException();
20
+    }
21
+    
22
+    @Override
23
+    public void debug(String message) {
24
+        throw new UnsupportedOperationException();
25
+    }
26
+    
27
+    @Override
28
+    public void warning(String message) {
29
+        throw new UnsupportedOperationException();
30
+    }
31
+    
32
+    @Override
33
+    public void error(String message) {
34
+        throw new UnsupportedOperationException();
35
+    }
36
+    
37
+    @Override
38
+    public void throwingErr(String message, Throwable throwable) {
39
+        throw new UnsupportedOperationException();
40
+    }
41
+    
42
+    @Override
43
+    public void throwingWarn(String message, Throwable throwable) {
44
+        throw new UnsupportedOperationException();
45
+    }
46
+    
47
+    @Override
48
+    public void logValidationError(ValidationLogEntry errorEntry) {
49
+        logValidationWarning(errorEntry);
50
+    }
51
+    
52
+    @Override
53
+    public void logValidationWarning(ValidationLogEntry entry) {
54
+        final IDECodeError ideCodeError = new IDECodeError(null, entry.position, entry.message);
55
+        errors.accept(ideCodeError);
56
+    }
57
+}

+ 5
- 0
JavaAnnotations/src/main/java/org/openzen/zencode/java/StorageTagType.java View File

@@ -0,0 +1,5 @@
1
+package org.openzen.zencode.java;
2
+
3
+public enum StorageTagType {
4
+    STATIC
5
+}

+ 11
- 0
JavaAnnotations/src/main/java/org/openzen/zencode/java/ZenCodeStorageTag.java View File

@@ -0,0 +1,11 @@
1
+package org.openzen.zencode.java;
2
+
3
+import java.lang.annotation.*;
4
+
5
+@Retention(RetentionPolicy.RUNTIME)
6
+@Target(ElementType.TYPE_USE)
7
+public @interface ZenCodeStorageTag {
8
+    
9
+    StorageTagType value();
10
+    
11
+}

+ 3
- 1
JavaAnnotations/src/main/java/org/openzen/zencode/java/ZenCodeType.java View File

@@ -97,7 +97,9 @@ public interface ZenCodeType {
97 97
 	
98 98
 	@Retention(RetentionPolicy.RUNTIME)
99 99
 	@Target(ElementType.PARAMETER)
100
-	@interface Optional {}
100
+	@interface Optional {
101
+		String value() default "";
102
+	}
101 103
 	
102 104
 	@Retention(RetentionPolicy.RUNTIME)
103 105
 	@Target(ElementType.PARAMETER)

+ 3
- 2
JavaBytecodeCompiler/build.gradle View File

@@ -14,7 +14,8 @@ if (!hasProperty('mainClass')) {
14 14
 }
15 15
 
16 16
 dependencies {
17
-	compile 'org.ow2.asm:asm-debug-all:6.0_BETA'
18
-	compile project(':CodeModel')
17
+    compile group: 'org.ow2.asm', name: 'asm', version: '7.2'
18
+    compile group: 'org.ow2.asm', name: 'asm-commons', version: '7.2'
19
+    compile project(':CodeModel')
19 20
 	compile project(':JavaShared')
20 21
 }

+ 4
- 3
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeContext.java View File

@@ -9,6 +9,7 @@ import org.objectweb.asm.ClassWriter;
9 9
 import org.objectweb.asm.Opcodes;
10 10
 import org.objectweb.asm.Type;
11 11
 import org.openzen.zencode.shared.CodePosition;
12
+import org.openzen.zencode.shared.logging.*;
12 13
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
13 14
 import org.openzen.zenscript.codemodel.type.StoredType;
14 15
 import org.openzen.zenscript.codemodel.type.TypeID;
@@ -34,8 +35,8 @@ public class JavaBytecodeContext extends JavaContext {
34 35
 	private final JavaTypeDescriptorVisitor descriptorVisitor;
35 36
 	private int lambdaCounter = 0;
36 37
 	
37
-	public JavaBytecodeContext(JavaBytecodeModule target, JavaCompileSpace space, ZSPackage modulePackage, String basePackage) {
38
-		super(space, modulePackage, basePackage);
38
+	public JavaBytecodeContext(JavaBytecodeModule target, JavaCompileSpace space, ZSPackage modulePackage, String basePackage, IZSLogger logger) {
39
+		super(space, modulePackage, basePackage, logger);
39 40
 		
40 41
 		this.target = target;
41 42
 		
@@ -102,7 +103,7 @@ public class JavaBytecodeContext extends JavaContext {
102 103
 		rangeWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "to", getDescriptor(range.baseType), null, null).visitEnd();
103 104
 		
104 105
 		JavaMethod method = JavaMethod.getConstructor(range.cls, "(" + getDescriptor(range.baseType) + getDescriptor(range.baseType) + ")V", Opcodes.ACC_PUBLIC);
105
-		JavaWriter constructorWriter = new JavaWriter(CodePosition.GENERATED, rangeWriter, method, null, method.descriptor, null);
106
+		JavaWriter constructorWriter = new JavaWriter(logger, CodePosition.GENERATED, rangeWriter, method, null, method.descriptor, null);
106 107
 		constructorWriter.loadObject(0);
107 108
 		constructorWriter.invokeSpecial("java/lang/Object", "<init>", "()V");
108 109
 		constructorWriter.loadObject(0);

+ 15
- 5
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeModule.java View File

@@ -9,6 +9,8 @@ import java.util.ArrayList;
9 9
 import java.util.HashMap;
10 10
 import java.util.List;
11 11
 import java.util.Map;
12
+
13
+import org.openzen.zencode.shared.logging.*;
12 14
 import org.openzen.zenscript.codemodel.FunctionParameter;
13 15
 import org.openzen.zenscript.codemodel.Module;
14 16
 import org.openzen.zenscript.javashared.JavaCompiledModule;
@@ -21,16 +23,24 @@ import org.openzen.zenscript.javashared.JavaMethod;
21 23
 public class JavaBytecodeModule extends JavaCompiledModule {
22 24
 	private final Map<String, byte[]> classes = new HashMap<>();
23 25
 	private final List<JavaScriptMethod> scripts = new ArrayList<>();
24
-	
25
-	public JavaBytecodeModule(Module module, FunctionParameter[] parameters) {
26
+    private final IZSLogger logger;
27
+    
28
+    public JavaBytecodeModule(Module module, FunctionParameter[] parameters, IZSLogger logger) {
26 29
 		super(module, parameters);
27
-	}
30
+        this.logger = logger;
31
+    }
28 32
 	
29 33
 	public void addClass(String name, byte[] bytecode) {
30 34
 		if (bytecode == null)
31 35
 			return;
32
-		
33
-		classes.put(name, bytecode);
36
+
37
+		if(name.startsWith("java")) {
38
+			logger.debug("Warning: Invalid name " + name);
39
+		} else if(classes.containsKey(name)) {
40
+			logger.error("Trying to register " + name + " a 2nd time");
41
+		} else {
42
+			classes.put(name, bytecode);
43
+		}
34 44
 	}
35 45
 	
36 46
 	public void addScript(JavaScriptMethod method) {

+ 22
- 15
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaBytecodeRunUnit.java View File

@@ -9,6 +9,7 @@ import org.objectweb.asm.ClassWriter;
9 9
 import org.objectweb.asm.Opcodes;
10 10
 import org.objectweb.asm.Type;
11 11
 import org.openzen.zencode.shared.CodePosition;
12
+import org.openzen.zencode.shared.logging.*;
12 13
 import org.openzen.zenscript.codemodel.FunctionHeader;
13 14
 import org.openzen.zenscript.codemodel.FunctionParameter;
14 15
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
@@ -22,10 +23,11 @@ import java.io.File;
22 23
 import java.io.FileOutputStream;
23 24
 import java.io.IOException;
24 25
 import java.lang.reflect.InvocationTargetException;
25
-import java.lang.reflect.Method;
26
-import java.util.*;
27
-import java.util.logging.Level;
28
-import java.util.logging.Logger;
26
+import java.util.ArrayList;
27
+import java.util.Collections;
28
+import java.util.HashMap;
29
+import java.util.List;
30
+import java.util.Map;
29 31
 
30 32
 /**
31 33
  * @author Hoofdgebruiker
@@ -37,8 +39,13 @@ public class JavaBytecodeRunUnit {
37 39
 	private final List<JavaParameterInfo> scriptParameterInfo = new ArrayList<>();
38 40
 
39 41
 	private boolean scriptsWritten = false;
40
-
41
-	public void add(JavaBytecodeModule module) {
42
+	private final IZSLogger logger;
43
+    
44
+    public JavaBytecodeRunUnit(IZSLogger logger) {
45
+        this.logger = logger;
46
+    }
47
+    
48
+    public void add(JavaBytecodeModule module) {
42 49
 		scriptsWritten = false;
43 50
 
44 51
 		for (Map.Entry<String, byte[]> classEntry : module.getClasses().entrySet())
@@ -57,15 +64,15 @@ public class JavaBytecodeRunUnit {
57 64
 		}
58 65
 	}
59 66
 
60
-	public void run() {
67
+	public void run() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
61 68
 		run(Collections.emptyMap(), this.getClass().getClassLoader());
62 69
 	}
63 70
 
64
-	public void run(Map<FunctionParameter, Object> arguments) {
71
+	public void run(Map<FunctionParameter, Object> arguments) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
65 72
 		run(arguments, this.getClass().getClassLoader());
66 73
 	}
67 74
 
68
-	public void run(Map<FunctionParameter, Object> arguments, ClassLoader parentClassLoader) {
75
+	public void run(Map<FunctionParameter, Object> arguments, ClassLoader parentClassLoader) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
69 76
 		writeScripts();
70 77
 
71 78
 		ScriptClassLoader classLoader = new ScriptClassLoader(parentClassLoader);
@@ -78,14 +85,10 @@ public class JavaBytecodeRunUnit {
78 85
 
79 86
 			argumentsArray[i] = arguments.get(parameter);
80 87
 		}
81
-		try {
82 88
 			Class[] classes = new Class[scriptParameters.size()];
83 89
 			for (int i = 0; i < classes.length; i++)
84 90
 				classes[i] = loadClass(classLoader, scriptParameterInfo.get(i).typeDescriptor);
85 91
 			classLoader.loadClass("Scripts").getMethod("run", classes).invoke(null, argumentsArray);
86
-		} catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | SecurityException | IllegalArgumentException ex) {
87
-			Logger.getLogger(JavaBytecodeRunUnit.class.getName()).log(Level.SEVERE, null, ex);
88
-		}
89 92
 	}
90 93
 
91 94
 	public void dump(File directory) {
@@ -95,7 +98,11 @@ public class JavaBytecodeRunUnit {
95 98
 			directory.mkdirs();
96 99
 
97 100
 		for (Map.Entry<String, byte[]> classEntry : classes.entrySet()) {
98
-			File output = new File(directory, classEntry.getKey() + ".class");
101
+			File output = new File(directory, classEntry.getKey().replace('.', File.separatorChar) + ".class");
102
+			if (!output.getParentFile().exists() && !output.getParentFile().mkdirs()) {
103
+				//Throw error?
104
+				continue;
105
+			}
99 106
 			try (FileOutputStream outputStream = new FileOutputStream(output)) {
100 107
 				outputStream.write(classEntry.getValue());
101 108
 			} catch (IOException ex) {
@@ -124,7 +131,7 @@ public class JavaBytecodeRunUnit {
124 131
 		headerBuilder.append(")V");
125 132
 
126 133
 		JavaMethod runMethod = JavaMethod.getStatic(new JavaClass("script", "Scripts", JavaClass.Kind.CLASS), "run", headerBuilder.toString(), Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
127
-		final JavaWriter runWriter = new JavaWriter(CodePosition.GENERATED, scriptsClassWriter, runMethod, null, null, null);
134
+		final JavaWriter runWriter = new JavaWriter(logger, CodePosition.GENERATED, scriptsClassWriter, runMethod, null, null, null);
128 135
 		runWriter.start();
129 136
 		for (JavaScriptMethod method : scripts) {
130 137
 			for (int i = 0; i < method.parameters.length; i++) {

+ 77
- 50
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java View File

@@ -5,65 +5,76 @@
5 5
  */
6 6
 package org.openzen.zenscript.javabytecode;
7 7
 
8
-import java.util.HashMap;
9
-import java.util.Map;
10
-import org.objectweb.asm.ClassWriter;
11
-import org.objectweb.asm.Opcodes;
12
-import org.openzen.zencode.shared.CodePosition;
13
-import org.openzen.zencode.shared.SourceFile;
14
-import org.openzen.zenscript.codemodel.FunctionHeader;
15
-import org.openzen.zenscript.codemodel.FunctionParameter;
16
-import org.openzen.zenscript.codemodel.HighLevelDefinition;
17
-import org.openzen.zenscript.codemodel.ScriptBlock;
18
-import org.openzen.zenscript.codemodel.SemanticModule;
19
-import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
20
-import org.openzen.zenscript.codemodel.statement.Statement;
21
-import org.openzen.zenscript.codemodel.type.BasicTypeID;
22
-import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
23
-import org.openzen.zenscript.javabytecode.compiler.JavaScriptFile;
24
-import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
25
-import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
26
-import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
27
-import org.openzen.zenscript.javashared.JavaClass;
28
-import org.openzen.zenscript.javashared.JavaCompileSpace;
29
-import org.openzen.zenscript.javashared.JavaMethod;
30
-import org.openzen.zenscript.javashared.JavaParameterInfo;
31
-import org.openzen.zenscript.javashared.prepare.JavaPrepareDefinitionMemberVisitor;
32
-import org.openzen.zenscript.javashared.prepare.JavaPrepareDefinitionVisitor;
8
+import org.objectweb.asm.*;
9
+import org.openzen.zencode.shared.*;
10
+import org.openzen.zencode.shared.logging.*;
11
+import org.openzen.zenscript.codemodel.*;
12
+import org.openzen.zenscript.codemodel.definition.*;
13
+import org.openzen.zenscript.codemodel.statement.*;
14
+import org.openzen.zenscript.codemodel.type.*;
15
+import org.openzen.zenscript.javabytecode.compiler.*;
16
+import org.openzen.zenscript.javabytecode.compiler.definitions.*;
17
+import org.openzen.zenscript.javashared.*;
18
+import org.openzen.zenscript.javashared.prepare.*;
19
+
20
+import java.io.*;
21
+import java.util.*;
22
+import java.util.stream.*;
33 23
 
34 24
 /**
35 25
  * @author Hoofdgebruiker
36 26
  */
37 27
 public class JavaCompiler {
38
-	private int generatedScriptBlockCounter = 0;
39
-	
40
-	public JavaCompiler() {}
28
+    
29
+    private int generatedScriptBlockCounter = 0;
30
+	private int expansionCounter = 0;
31
+	private final IZSLogger logger;
32
+    
33
+    public JavaCompiler(IZSLogger logger) {
34
+        this.logger = logger;
35
+    }
41 36
 	
42 37
 	public JavaBytecodeModule compile(String packageName, SemanticModule module, JavaCompileSpace space) {
43
-		Map<String, JavaScriptFile> scriptBlocks = new HashMap<>();
38
+		Map<String, JavaScriptFile> scriptBlocks = new LinkedHashMap<>();
39
+		Set<JavaScriptFile> scriptFilesThatAreActuallyUsedInScripts = new HashSet<>();
44 40
 		
45
-		JavaBytecodeModule target = new JavaBytecodeModule(module.module, module.parameters);
46
-		JavaBytecodeContext context = new JavaBytecodeContext(target, space, module.modulePackage, packageName);
41
+		JavaBytecodeModule target = new JavaBytecodeModule(module.module, module.parameters, logger);
42
+		JavaBytecodeContext context = new JavaBytecodeContext(target, space, module.modulePackage, packageName, logger);
47 43
 		context.addModule(module.module, target);
48 44
 		
49 45
 		for (HighLevelDefinition definition : module.definitions.getAll()) {
50
-			String filename = getFilename(definition);
51
-			JavaPrepareDefinitionVisitor definitionPreparer = new JavaPrepareDefinitionVisitor(context, target, filename, null);
52
-			definition.accept(definitionPreparer);
46
+			final String className = getClassName(getFilename(definition));
47
+			final String filename;
48
+            if(definition instanceof FunctionDefinition) {
49
+                filename = className;
50
+            } else {
51
+                filename = className + "_" + (definition.name == null ? "generated" : definition.name) + "_" + expansionCounter++;
52
+            }
53
+            JavaPrepareDefinitionVisitor definitionPreparer = new JavaPrepareDefinitionVisitor(context, target, filename, null, filename);
54
+            definition.accept(definitionPreparer);
53 55
 		}
54 56
 		
55 57
 		for (HighLevelDefinition definition : module.definitions.getAll()) {
56 58
 			JavaPrepareDefinitionMemberVisitor memberPreparer = new JavaPrepareDefinitionMemberVisitor(context, target);
57 59
 			definition.accept(memberPreparer);
58 60
 		}
59
-		
60
-		for (HighLevelDefinition definition : module.definitions.getAll()) {
61
-			String className = getClassName(definition.position.getFilename());
62
-			JavaScriptFile scriptFile = getScriptFile(scriptBlocks, definition.pkg.fullName + "/" + className);
63
-			
64
-			JavaClass cls = definition instanceof ExpansionDefinition ? context.getJavaExpansionClass(definition) : context.getJavaClass(definition);
65
-			target.addClass(cls.internalName, definition.accept(new JavaDefinitionVisitor(context, scriptFile.classWriter)));
66
-		}
61
+        
62
+        for(HighLevelDefinition definition : module.definitions.getAll()) {
63
+            final String internalName;
64
+            final JavaScriptFile scriptFile;
65
+            if(definition instanceof FunctionDefinition) {
66
+                internalName = getClassName(getFilename(definition));
67
+                scriptFile = getScriptFile(scriptBlocks, module.modulePackage.fullName + "/" + internalName);
68
+                scriptFilesThatAreActuallyUsedInScripts.add(scriptFile);
69
+            } else {
70
+                JavaClass cls = definition instanceof ExpansionDefinition ? context.getJavaExpansionClass(definition) : context
71
+                        .getJavaClass(definition);
72
+                scriptFile = getScriptFile(scriptBlocks, cls.fullName);
73
+                internalName = cls.internalName;
74
+            }
75
+            scriptFile.classWriter.visitSource(definition.position.getFilename(), null);
76
+            target.addClass(internalName, definition.accept(new JavaDefinitionVisitor(context, scriptFile.classWriter)));
77
+        }
67 78
 		
68 79
 		FunctionHeader scriptHeader = new FunctionHeader(BasicTypeID.VOID, module.parameters);
69 80
 		String scriptDescriptor = context.getMethodDescriptor(scriptHeader);
@@ -79,6 +90,10 @@ public class JavaCompiler {
79 90
 			final SourceFile sourceFile = script.file;
80 91
 			final String className = getClassName(sourceFile == null ? null : sourceFile.getFilename());
81 92
 			JavaScriptFile scriptFile = getScriptFile(scriptBlocks, script.pkg.fullName + "/" + className);
93
+			scriptFilesThatAreActuallyUsedInScripts.add(scriptFile);
94
+			if(sourceFile != null) {
95
+                scriptFile.classWriter.visitSource(sourceFile.getFilename(), null);
96
+            }
82 97
 
83 98
 			String methodName = scriptFile.scriptMethods.isEmpty() ? "run" : "run" + scriptFile.scriptMethods.size();
84 99
 
@@ -88,7 +103,7 @@ public class JavaCompiler {
88 103
 			JavaMethod method = JavaMethod.getStatic(new JavaClass(context.getPackageName(script.pkg), className, JavaClass.Kind.CLASS), methodName, scriptDescriptor, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
89 104
 			scriptFile.scriptMethods.add(new JavaScriptMethod(method, module.parameters, javaScriptParameters));
90 105
 
91
-			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, context.getJavaModule(script.module), new JavaWriter(CodePosition.UNKNOWN, visitor, method, null, null, null));
106
+			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, context.getJavaModule(script.module), new JavaWriter(logger, CodePosition.UNKNOWN, visitor, method, null, null, null));
92 107
 			statementVisitor.start();
93 108
 			for (Statement statement : script.statements) {
94 109
 				statement.accept(statementVisitor);
@@ -101,7 +116,9 @@ public class JavaCompiler {
101 116
 				target.addScript(method);
102 117
 
103 118
 			entry.getValue().classWriter.visitEnd();
104
-			target.addClass(entry.getKey(), entry.getValue().classWriter.toByteArray());
119
+			if(scriptFilesThatAreActuallyUsedInScripts.contains(entry.getValue())) {
120
+				target.addClass(entry.getKey(), entry.getValue().classWriter.toByteArray());
121
+			}
105 122
 		}
106 123
 
107 124
 		return target;
@@ -110,10 +127,11 @@ public class JavaCompiler {
110 127
 	private String getFilename(HighLevelDefinition definition) {
111 128
 		SourceFile source = definition.position.file;
112 129
 		if (source != null) {
113
-			int slash = Math.max(source.getFilename().lastIndexOf('/'), source.getFilename().lastIndexOf('\\'));
114
-			String filename = source.getFilename().substring(slash < 0 ? 0 : slash + 1);
115
-			filename = filename.substring(0, filename.lastIndexOf('.'));
116
-			return filename;
130
+			//int slash = Math.max(source.getFilename().lastIndexOf('/'), source.getFilename().lastIndexOf('\\'));
131
+			//String filename = source.getFilename().substring(slash < 0 ? 0 : slash + 1);
132
+			//filename = filename.substring(0, filename.lastIndexOf('.'));
133
+			//return filename;
134
+			return source.getFilename();
117 135
 		} else {
118 136
 			return definition.name == null ? "Expansion" : definition.name;
119 137
 		}
@@ -123,8 +141,17 @@ public class JavaCompiler {
123 141
 		if (filename == null) {
124 142
 			return "generatedBlock" + (generatedScriptBlockCounter++);
125 143
 		} else {
126
-			// TODO: remove special characters
127
-			return filename.substring(0, filename.lastIndexOf('.')).replace("/", "_");
144
+            // TODO: find all special characters
145
+            final String specialCharRegex = Stream.of('/', '\\', '.', ';')
146
+                    .filter(character -> character != File.separatorChar)
147
+                    .map(String::valueOf)
148
+                    .collect(Collectors.joining("", "[", "]"));
149
+            
150
+			return filename
151
+                    .substring(0, filename.lastIndexOf('.')) //remove the .zs part
152
+                    .replaceAll(specialCharRegex, "_")
153
+                    .replace('[', '_')
154
+                    .replace(File.separatorChar, '/');
128 155
 		}
129 156
 	}
130 157
 

+ 4
- 4
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/ArrayInitializerHelper.java View File

@@ -137,12 +137,12 @@ class ArrayInitializerHelper {
137 137
 	}
138 138
 
139 139
 	/**
140
-	 * Checks if an expression can be inlined
140
+	 * Checks if an expression can be inLined
141 141
 	 *
142 142
 	 * @param expression Expression to check for.
143
-	 * @return can expression be inlined
143
+	 * @return can expression be inLined
144 144
 	 */
145
-	static boolean canBeInlined(Expression expression) {
145
+	static boolean canBeInLined(Expression expression) {
146 146
 		while (expression instanceof StorageCastExpression)
147 147
 			expression = ((StorageCastExpression) expression).value;
148 148
 
@@ -162,7 +162,7 @@ class ArrayInitializerHelper {
162 162
 	 * @param currentArrayType  The current type of the array, reduced during the recursions of the functions
163 163
 	 * @param innermostFunction The function that will decide what to add to the array, needs to increase the stack size by one and may not touch the other stacks!
164 164
 	 */
165
-	private static void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counterLocations, int dim, Type currentArrayType, InnermostFunction innermostFunction) {
165
+	static void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counterLocations, int dim, Type currentArrayType, InnermostFunction innermostFunction) {
166 166
 		final Label begin = new Label();
167 167
 		final Label end = new Label();
168 168
 		javaWriter.label(begin);

+ 48
- 5
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java View File

@@ -12,12 +12,15 @@ import org.openzen.zenscript.codemodel.member.IDefinitionMember;
12 12
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
13 13
 import org.openzen.zenscript.codemodel.type.StoredType;
14 14
 import org.openzen.zenscript.codemodel.type.TypeID;
15
+import org.openzen.zenscript.javashared.JavaField;
15 16
 import org.openzen.zenscript.javashared.JavaParameterInfo;
16 17
 
17 18
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
18 19
 import org.openzen.zenscript.javashared.JavaCompiledModule;
19 20
 import org.openzen.zenscript.javashared.JavaTypeParameterInfo;
20 21
 
22
+import java.util.List;
23
+
21 24
 public class CompilerUtils {
22 25
 
23 26
 	private CompilerUtils() {}
@@ -28,7 +31,7 @@ public class CompilerUtils {
28 31
 	}
29 32
 
30 33
 	public static boolean isLarge(StoredType type) {
31
-		return type.type == BasicTypeID.DOUBLE || type.type == BasicTypeID.DOUBLE;
34
+		return type.type == BasicTypeID.DOUBLE || type.type == BasicTypeID.LONG;
32 35
 	}
33 36
 	
34 37
 	public static int calcAccess(int modifiers) {
@@ -48,21 +51,60 @@ public class CompilerUtils {
48 51
 		return out;
49 52
 	}
50 53
 
51
-    public static void tagMethodParameters(JavaBytecodeContext context, JavaCompiledModule module, FunctionHeader header, boolean isStatic) {
52
-		int index = header.getNumberOfTypeParameters();
54
+    public static void tagMethodParameters(JavaBytecodeContext context, JavaCompiledModule module, FunctionHeader header, boolean isStatic, List<TypeParameter> baseTypeTypeParameters) {
55
+		int index = isStatic ? 0 : 1;
56
+
57
+		for (TypeParameter baseTypeTypeParameter : baseTypeTypeParameters) {
58
+			module.setTypeParameterInfo(baseTypeTypeParameter, new JavaTypeParameterInfo(index));
59
+			index++;
60
+		}
61
+
53 62
 		for (int i = 0; i < header.typeParameters.length; i++) {
54 63
 			TypeParameter parameter = header.typeParameters[i];
55
-			module.setTypeParameterInfo(parameter, new JavaTypeParameterInfo(index++));
64
+			module.setTypeParameterInfo(parameter, new JavaTypeParameterInfo(index));
65
+			index++;
56 66
 		}
57 67
         for (int i = 0; i < header.parameters.length; i++) {
58 68
             FunctionParameter parameter = header.parameters[i];
59 69
             String parameterType = context.getDescriptor(parameter.type);
60
-            module.setParameterInfo(parameter, new JavaParameterInfo(isStatic ? index : index + 1, parameterType));
70
+            module.setParameterInfo(parameter, new JavaParameterInfo(index, parameterType));
61 71
 			index++;
62 72
         }
63 73
     }
64 74
 
65 75
     public static void tagConstructorParameters(JavaBytecodeContext context, JavaCompiledModule module, HighLevelDefinition definition, FunctionHeader header, boolean isEnum) {
76
+		int index = 1;
77
+		for (TypeParameter typeParameter : definition.typeParameters) {
78
+			final JavaField field = new JavaField(context.getJavaClass(definition),
79
+					"typeOf" + typeParameter.name,
80
+					"Ljava/lang/Class;",
81
+					//"Ljava/lang/Class;"
82
+					"Ljava/lang/Class<T" + typeParameter.name + ";>;"
83
+			);
84
+			final JavaTypeParameterInfo info = new JavaTypeParameterInfo(index, field);
85
+			module.setTypeParameterInfo(typeParameter, info);
86
+			index++;
87
+		}
88
+
89
+		for (int i = 0; i < header.typeParameters.length; i++) {
90
+			TypeParameter typeParameter = header.typeParameters[i];
91
+			final JavaField field = new JavaField(context.getJavaClass(definition),
92
+					"typeOf" + typeParameter.name,
93
+					"Ljava/lang/Class;",
94
+					//"Ljava/lang/Class;"
95
+					"Ljava/lang/Class<T" + typeParameter.name + ";>;"
96
+					);
97
+			final JavaTypeParameterInfo info = new JavaTypeParameterInfo(index, field);
98
+			module.setTypeParameterInfo(typeParameter, info);
99
+			index++;
100
+		}
101
+		for (int i = 0; i < header.parameters.length; i++) {
102
+			FunctionParameter parameter = header.parameters[i];
103
+			String parameterType = context.getDescriptor(parameter.type);
104
+			module.setParameterInfo(parameter, new JavaParameterInfo(index, parameterType));
105
+			index++;
106
+		}
107
+		/*
66 108
 		int index = header.getNumberOfTypeParameters();
67 109
 		for (int i = 0; i < definition.typeParameters.length; i++) {
68 110
 			JavaTypeParameterInfo info = module.getTypeParameterInfo(definition.typeParameters[i]);
@@ -78,6 +120,7 @@ public class CompilerUtils {
78 120
             String parameterType = context.getDescriptor(parameter.type);
79 121
 			module.setParameterInfo(parameter, new JavaParameterInfo(isEnum ? i + 3 : i + 1, parameterType));
80 122
         }
123
+		 */
81 124
     }
82 125
 
83 126
     public static void writeDefaultFieldInitializers(JavaBytecodeContext context, JavaWriter constructorWriter, HighLevelDefinition definition, boolean staticFields) {

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

@@ -60,7 +60,6 @@ public class JavaBoxingTypeVisitor implements TypeVisitorWithContext<StoredType,
60 60
 			default:
61 61
 				return null;
62 62
 		}
63
-		writer.dup();
64 63
 		
65 64
 		if (method != null)
66 65
 			writer.invokeStatic(method);

+ 399
- 171
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
File diff suppressed because it is too large
View File


+ 58
- 18
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachWriter.java View File

@@ -4,12 +4,14 @@ import org.objectweb.asm.Label;
4 4
 import org.objectweb.asm.Type;
5 5
 import org.openzen.zenscript.codemodel.statement.Statement;
6 6
 import org.openzen.zenscript.codemodel.statement.VarStatement;
7
+import org.openzen.zenscript.codemodel.type.RangeTypeID;
7 8
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
8 9
 import org.openzen.zenscript.javashared.JavaClass;
9 10
 import org.openzen.zenscript.javashared.JavaMethod;
11
+import org.openzen.zenscript.javashared.JavaModifiers;
10 12
 
11 13
 import java.util.Map;
12
-
14
+@SuppressWarnings("Duplicates")
13 15
 public class JavaForeachWriter {
14 16
 
15 17
 	private final JavaWriter javaWriter;
@@ -18,6 +20,7 @@ public class JavaForeachWriter {
18 20
 	private final Label startLabel;
19 21
 	private final Label endLabel;
20 22
 	private final JavaStatementVisitor statementVisitor;
23
+	private final JavaUnboxingTypeVisitor unboxingTypeVisitor;
21 24
 
22 25
 	public JavaForeachWriter(JavaStatementVisitor statementVisitor, VarStatement[] variables, Statement content, Label start, Label end) {
23 26
 		this.statementVisitor = statementVisitor;
@@ -26,13 +29,15 @@ public class JavaForeachWriter {
26 29
 		this.content = content;
27 30
 		this.startLabel = start;
28 31
 		this.endLabel = end;
29
-	}
32
+        this.unboxingTypeVisitor = new JavaUnboxingTypeVisitor(this.javaWriter);
33
+    }
30 34
 
31
-	public void visitIntRange() {
35
+	public void visitIntRange(RangeTypeID type) {
36
+		final String owner = statementVisitor.context.getInternalName(type);
32 37
 		javaWriter.dup();
33
-		javaWriter.getField("zsynthetic/IntRange", "to", "I");
38
+		javaWriter.getField(owner, "to", "I");
34 39
 		javaWriter.swap();
35
-		javaWriter.getField("zsynthetic/IntRange", "from", "I");
40
+		javaWriter.getField(owner, "from", "I");
36 41
 
37 42
 		final int z = javaWriter.getLocalVariable(variables[0].variable).local;
38 43
 		javaWriter.storeInt(z);
@@ -54,8 +59,7 @@ public class JavaForeachWriter {
54 59
 	}
55 60
 
56 61
 	public void visitStringCharacterIterator() {
57
-		//TODO UNTESTED!
58
-		javaWriter.invokeSpecial("java/lang/String", "toCharArray()", "()[C");
62
+        javaWriter.invokeVirtual(JavaMethod.getVirtual(JavaClass.STRING, "toCharArray", "()[C", JavaModifiers.PUBLIC));
59 63
 		handleArray(javaWriter.local(int.class), javaWriter.getLocalVariable(variables[0].variable));
60 64
 	}
61 65
 
@@ -79,12 +83,12 @@ public class JavaForeachWriter {
79 83
 
80 84
 		javaWriter.label(startLabel);
81 85
 		javaWriter.dup();
82
-		javaWriter.dup();
83 86
 		javaWriter.arrayLength();
84
-		javaWriter.loadInt(z);
85
-
86
-		javaWriter.ifICmpLE(endLabel);
87
-		javaWriter.loadInt(z);
87
+        javaWriter.loadInt(z);
88
+        
89
+        javaWriter.ifICmpLE(endLabel);
90
+        javaWriter.dup();
91
+        javaWriter.loadInt(z);
88 92
 
89 93
 		javaWriter.arrayLoad(arrayTypeInfo.type);
90 94
 		javaWriter.store(arrayTypeInfo.type, arrayTypeInfo.local);
@@ -93,11 +97,38 @@ public class JavaForeachWriter {
93 97
 	}
94 98
 
95 99
 	public void visitCustomIterator() {
96
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
100
+        javaWriter.invokeInterface(JavaMethod.getVirtual(new JavaClass("java.lang", "Iterable", JavaClass.Kind.INTERFACE), "iterator", "()Ljava/util/Iterator;", 0));
101
+        
102
+        javaWriter.label(startLabel);
103
+        javaWriter.dup();
104
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "hasNext", "()Z", 0));
105
+        javaWriter.ifEQ(endLabel);
106
+        javaWriter.dup();
107
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "next", "()Ljava/lang/Object;", 0));
108
+        
109
+        final JavaLocalVariableInfo keyVariable = javaWriter.getLocalVariable(variables[0].variable);
110
+        this.downCast(0, keyVariable.type);
111
+        javaWriter.store(keyVariable.type, keyVariable.local);
112
+        
113
+        content.accept(statementVisitor);
97 114
 	}
98 115
 
99 116
 	public void visitAssocKeyIterator() {
100
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
117
+	    javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.MAP, "keySet", "()Ljava/util/Set;", 0));
118
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.COLLECTION, "iterator", "()Ljava/util/Iterator;", 0));
119
+        
120
+        javaWriter.label(startLabel);
121
+        javaWriter.dup();
122
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "hasNext", "()Z", 0));
123
+        javaWriter.ifEQ(endLabel);
124
+        javaWriter.dup();
125
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "next", "()Ljava/lang/Object;", 0));
126
+        
127
+        final JavaLocalVariableInfo keyVariable = javaWriter.getLocalVariable(variables[0].variable);
128
+        this.downCast(0, keyVariable.type);
129
+        javaWriter.store(keyVariable.type, keyVariable.local);
130
+        
131
+        content.accept(statementVisitor);
101 132
 	}
102 133
 
103 134
 	public void visitAssocKeyValueIterator() {
@@ -108,6 +139,7 @@ public class JavaForeachWriter {
108 139
 		javaWriter.dup();
109 140
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "hasNext", "()Z", 0));
110 141
 		javaWriter.ifEQ(endLabel);
142
+		javaWriter.dup();
111 143
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "next", "()Ljava/lang/Object;", 0));
112 144
 		javaWriter.checkCast(Type.getType(Map.Entry.class));
113 145
 		javaWriter.dup(false);
@@ -117,13 +149,21 @@ public class JavaForeachWriter {
117 149
 		final JavaLocalVariableInfo valueVariable = javaWriter.getLocalVariable(variables[1].variable);
118 150
 
119 151
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.fromInternalName("java/util/Map$Entry", JavaClass.Kind.INTERFACE), "getKey", "()Ljava/lang/Object;", 0));
152
+		this.downCast(0, keyVariable.type);
120 153
 		javaWriter.store(keyVariable.type, keyVariable.local);
121
-
154
+		
122 155
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.fromInternalName("java/util/Map$Entry", JavaClass.Kind.INTERFACE), "getValue", "()Ljava/lang/Object;", 0));
156
+        this.downCast(1, valueVariable.type);
123 157
 		javaWriter.store(valueVariable.type, valueVariable.local);
158
+		
124 159
 		content.accept(statementVisitor);
125
-
126
-
127
-		//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
128 160
 	}
161
+	
162
+	private void downCast(int typeNumber, Type t) {
163
+        if(CompilerUtils.isPrimitive(variables[typeNumber].type.type)) {
164
+            variables[typeNumber].type.type.accept(variables[typeNumber].type, unboxingTypeVisitor);
165
+        } else {
166
+            javaWriter.checkCast(t);
167
+        }
168
+    }
129 169
 }

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

@@ -77,6 +77,7 @@ import org.openzen.zenscript.codemodel.expression.TryRethrowAsExceptionExpressio
77 77
 import org.openzen.zenscript.codemodel.expression.TryRethrowAsResultExpression;
78 78
 import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
79 79
 import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
80
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
80 81
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
81 82
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
82 83
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
@@ -624,6 +625,14 @@ public class JavaNonPushingExpressionVisitor implements ExpressionVisitor<Void>
624 625
 	@Override
625 626
 	public Void visitSetter(SetterExpression expression) {
626 627
 		expression.target.accept(original);
628
+
629
+		if (expression.setter.member.definition.isExpansion()) {
630
+			for (TypeParameter typeParameter : expression.setter.member.definition.typeParameters) {
631
+				javaWriter.aConstNull(); //TODO replace with actual type
632
+				javaWriter.checkCast("java/lang/Class");
633
+			}
634
+		}
635
+
627 636
 		expression.value.accept(original);
628 637
 		original.checkAndExecuteMethodInfo(expression.setter, expression.type, expression);
629 638
 		return null;

+ 34
- 8
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java View File

@@ -3,6 +3,7 @@ package org.openzen.zenscript.javabytecode.compiler;
3 3
 import org.objectweb.asm.Label;
4 4
 import org.objectweb.asm.Type;
5 5
 import org.openzen.zenscript.codemodel.statement.*;
6
+import org.openzen.zenscript.codemodel.type.RangeTypeID;
6 7
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
7 8
 
8 9
 import java.util.Arrays;
@@ -14,9 +15,9 @@ import org.openzen.zenscript.javashared.JavaCompiledModule;
14 15
 
15 16
 public class JavaStatementVisitor implements StatementVisitor<Boolean> {
16 17
     private final JavaWriter javaWriter;
17
-	private final JavaBytecodeContext context;
18
-    public JavaExpressionVisitor expressionVisitor;
19
-	public JavaNonPushingExpressionVisitor nonPushingExpressionVisitor;
18
+	final JavaBytecodeContext context;
19
+    public final JavaExpressionVisitor expressionVisitor;
20
+	public final JavaNonPushingExpressionVisitor nonPushingExpressionVisitor;
20 21
 
21 22
     /**
22 23
      * @param javaWriter the method writer that compiles the statement
@@ -25,17 +26,19 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
25 26
         this.javaWriter = javaWriter;
26 27
 		this.context = context;
27 28
         this.expressionVisitor = new JavaExpressionVisitor(context, module, javaWriter);
28
-		nonPushingExpressionVisitor = new JavaNonPushingExpressionVisitor(context, module, javaWriter, expressionVisitor);
29
+		this.nonPushingExpressionVisitor = new JavaNonPushingExpressionVisitor(context, module, javaWriter, expressionVisitor);
29 30
     }
30 31
 
31 32
     public JavaStatementVisitor(JavaBytecodeContext context, JavaExpressionVisitor expressionVisitor) {
32 33
         this.javaWriter = expressionVisitor.getJavaWriter();
33 34
 		this.context = context;
34 35
         this.expressionVisitor = expressionVisitor;
36
+		this.nonPushingExpressionVisitor = new JavaNonPushingExpressionVisitor(expressionVisitor.context, expressionVisitor.module, expressionVisitor.javaWriter, expressionVisitor);
35 37
     }
36 38
 
37 39
 	@Override
38 40
 	public Boolean visitBlock(BlockStatement statement) {
41
+    	javaWriter.position(statement.position.fromLine);
39 42
 		Boolean returns = false;
40 43
 		for (Statement statement1 : statement.statements) {
41 44
 			returns = statement1.accept(this);
@@ -45,18 +48,21 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
45 48
 
46 49
 	@Override
47 50
 	public Boolean visitBreak(BreakStatement statement) {
51
+    	javaWriter.position(statement.position.fromLine);
48 52
 		javaWriter.goTo(javaWriter.getNamedLabel(statement.target.label + "_end"));
49 53
 		return false;
50 54
 	}
51 55
 
52 56
 	@Override
53 57
 	public Boolean visitContinue(ContinueStatement statement) {
58
+    	javaWriter.position(statement.position.fromLine);
54 59
 		javaWriter.goTo(javaWriter.getNamedLabel(statement.target.label + "_start"));
55 60
 		return false;
56 61
 	}
57 62
 
58 63
 	@Override
59 64
 	public Boolean visitDoWhile(DoWhileStatement statement) {
65
+    	javaWriter.position(statement.position.fromLine);
60 66
 		Label start = new Label();
61 67
 		Label end = new Label();
62 68
 		if (statement.label == null)
@@ -82,12 +88,14 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
82 88
 
83 89
 	@Override
84 90
 	public Boolean visitExpression(ExpressionStatement statement) {
91
+    	javaWriter.position(statement.position.fromLine);
85 92
 		statement.expression.accept(nonPushingExpressionVisitor);
86 93
 		return false;
87 94
 	}
88 95
 
89 96
 	@Override
90 97
 	public Boolean visitForeach(ForeachStatement statement) {
98
+    	javaWriter.position(statement.position.fromLine);
91 99
 		//Create Labels
92 100
 		Label start = new Label();
93 101
 		Label end = new Label();
@@ -118,7 +126,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
118 126
 		} else {
119 127
 			switch (statement.iterator.target.getBuiltin()) {
120 128
 				case ITERATOR_INT_RANGE:
121
-					iteratorWriter.visitIntRange();
129
+					iteratorWriter.visitIntRange(((RangeTypeID) statement.iterator.getOwnerType().type));
122 130
 					break;
123 131
 				case ITERATOR_ARRAY_VALUES:
124 132
 					iteratorWriter.visitArrayValueIterator();
@@ -145,11 +153,13 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
145 153
 		
146 154
 		javaWriter.goTo(start);
147 155
 		javaWriter.label(end);
156
+		javaWriter.pop();
148 157
 		return false;
149 158
 	}
150 159
 
151 160
 	@Override
152 161
 	public Boolean visitIf(IfStatement statement) {
162
+    	javaWriter.position(statement.position.fromLine);
153 163
 		statement.condition.accept(expressionVisitor);
154 164
 		Label onElse = null;
155 165
 		Label end = new Label();
@@ -174,16 +184,28 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
174 184
 	public Boolean visitLock(LockStatement statement) {
175 185
 		return false;
176 186
 	}
177
-
187
+	
188
+	@Override
189
+	public Boolean visitInvalid(InvalidStatement statement) {
190
+		throw new UnsupportedOperationException("Invalid Statement: " + statement.message);
191
+	}
192
+	
178 193
 	@Override
179 194
 	public Boolean visitReturn(ReturnStatement statement) {
180
-		statement.value.accept(expressionVisitor);
181
-		javaWriter.returnType(context.getType(statement.value.type));
195
+    	javaWriter.position(statement.position.fromLine);
196
+    	if(statement.value == null) {
197
+    		javaWriter.ret();
198
+		} else {
199
+			statement.value.accept(expressionVisitor);
200
+			javaWriter.returnType(context.getType(statement.value.type));
201
+		}
202
+
182 203
 		return true;
183 204
 	}
184 205
 
185 206
 	@Override
186 207
 	public Boolean visitSwitch(SwitchStatement statement) {
208
+    	javaWriter.position(statement.position.fromLine);
187 209
 
188 210
 		final Label start = new Label();
189 211
 		final Label end = new Label();
@@ -249,6 +271,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
249 271
 
250 272
 	@Override
251 273
 	public Boolean visitThrow(ThrowStatement statement) {
274
+    	javaWriter.position(statement.position.fromLine);
252 275
 		statement.value.accept(expressionVisitor);
253 276
 		javaWriter.aThrow();
254 277
 		return false;
@@ -256,6 +279,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
256 279
 
257 280
 	@Override
258 281
 	public Boolean visitTryCatch(TryCatchStatement statement) {
282
+    	javaWriter.position(statement.position.fromLine);
259 283
 		final Label tryCatchStart = new Label();
260 284
 		final Label tryFinish = new Label();
261 285
 		final Label tryCatchFinish = new Label();
@@ -307,6 +331,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
307 331
 
308 332
 	@Override
309 333
 	public Boolean visitVar(VarStatement statement) {
334
+    	javaWriter.position(statement.position.fromLine);
310 335
 		if (statement.initializer != null) {
311 336
 			statement.initializer.accept(expressionVisitor);
312 337
 		}
@@ -325,6 +350,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
325 350
 
326 351
 	@Override
327 352
 	public Boolean visitWhile(WhileStatement statement) {
353
+    	javaWriter.position(statement.position.fromLine);
328 354
 		Label start = new Label();
329 355
 		Label end = new Label();
330 356
 

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

@@ -0,0 +1,137 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.objectweb.asm.Type;
4
+import org.openzen.zenscript.codemodel.type.*;
5
+import org.openzen.zenscript.javashared.JavaClass;
6
+import org.openzen.zenscript.javashared.JavaMethod;
7
+
8
+public class JavaUnboxingTypeVisitor implements TypeVisitorWithContext<StoredType, Void, RuntimeException> {
9
+    
10
+    private static final JavaMethod UNBOX_BOOLEAN = JavaMethod.getNativeVirtual(JavaClass.BOOLEAN, "booleanValue", "()Z");
11
+    private static final JavaMethod UNBOX_BYTE = JavaMethod.getNativeVirtual(JavaClass.BYTE, "byteValue", "()B");
12
+    private static final JavaMethod UNBOX_SHORT = JavaMethod.getNativeVirtual(JavaClass.SHORT, "shortValue", "()S");
13
+    private static final JavaMethod UNBOX_INTEGER = JavaMethod.getNativeVirtual(JavaClass.INTEGER, "intValue", "()I");
14
+    private static final JavaMethod UNBOX_LONG = JavaMethod.getNativeVirtual(JavaClass.LONG, "longValue", "()J");
15
+    private static final JavaMethod UNBOX_FLOAT = JavaMethod.getNativeVirtual(JavaClass.FLOAT, "floatValue", "()F");
16
+    private static final JavaMethod UNBOX_DOUBLE = JavaMethod.getNativeVirtual(JavaClass.DOUBLE, "doubleValue", "()D");
17
+    private static final JavaMethod UNBOX_CHARACTER = JavaMethod.getNativeVirtual(JavaClass.CHARACTER, "charValue", "()C");
18
+    
19
+    private final JavaWriter writer;
20
+    
21
+    public JavaUnboxingTypeVisitor(JavaWriter writer) {
22
+        this.writer = writer;
23
+    }
24
+    
25
+    
26
+    @Override
27
+    public Void visitBasic(StoredType context, BasicTypeID basic) throws RuntimeException {
28
+        final JavaMethod method;
29
+        
30
+        switch(basic) {
31
+            case BOOL:
32
+                writer.checkCast(JavaClass.BOOLEAN.internalName);
33
+                method = UNBOX_BOOLEAN;
34
+                break;
35
+            case BYTE:
36
+            case SBYTE:
37
+                writer.checkCast(JavaClass.BYTE.internalName);
38
+                method = UNBOX_BYTE;
39
+                break;
40
+            case SHORT:
41
+            case USHORT:
42
+                writer.checkCast(JavaClass.SHORT.internalName);
43
+                method = UNBOX_SHORT;
44
+                break;
45
+            case INT:
46
+            case UINT:
47
+                writer.checkCast(JavaClass.INTEGER.internalName);
48
+                method = UNBOX_INTEGER;
49
+                break;
50
+            case LONG:
51
+            case ULONG:
52
+            case USIZE:
53
+                writer.checkCast(JavaClass.LONG.internalName);
54
+                method = UNBOX_LONG;
55
+                break;
56
+            case FLOAT:
57
+                writer.checkCast(JavaClass.FLOAT.internalName);
58
+                method = UNBOX_FLOAT;
59
+                break;
60
+            case DOUBLE:
61
+                writer.checkCast(JavaClass.DOUBLE.internalName);
62
+                method = UNBOX_DOUBLE;
63
+                break;
64
+            case CHAR:
65
+                writer.checkCast(JavaClass.CHARACTER.internalName);
66
+                method = UNBOX_CHARACTER;
67
+                break;
68
+            case VOID:
69
+            case UNDETERMINED:
70
+            case NULL:
71
+            default:
72
+                return null;
73
+        }
74
+        writer.invokeVirtual(method);
75
+        return null;
76
+    }
77
+    
78
+    @Override
79
+    public Void visitString(StoredType context, StringTypeID string) throws RuntimeException {
80
+        //NO-OP
81
+        return null;
82
+    }
83
+    
84
+    @Override
85
+    public Void visitArray(StoredType context, ArrayTypeID array) throws RuntimeException {
86
+        //NO-OP
87
+        return null;
88
+    }
89
+    
90
+    @Override
91
+    public Void visitAssoc(StoredType context, AssocTypeID assoc) throws RuntimeException {
92
+        //NO-OP
93
+        return null;
94
+    }
95
+    
96
+    @Override
97
+    public Void visitGenericMap(StoredType context, GenericMapTypeID map) throws RuntimeException {
98
+        //NO-OP
99
+        return null;
100
+    }
101
+    
102
+    @Override
103
+    public Void visitIterator(StoredType context, IteratorTypeID iterator) throws RuntimeException {
104
+        //NO-OP
105
+        return null;
106
+    }
107
+    
108
+    @Override
109
+    public Void visitFunction(StoredType context, FunctionTypeID function) throws RuntimeException {
110
+        //NO-OP
111
+        return null;
112
+    }
113
+    
114
+    @Override
115
+    public Void visitDefinition(StoredType context, DefinitionTypeID definition) throws RuntimeException {
116
+        //NO-OP
117
+        return null;
118
+    }
119
+    
120
+    @Override
121
+    public Void visitGeneric(StoredType context, GenericTypeID generic) throws RuntimeException {
122
+        //NO-OP
123
+        return null;
124
+    }
125
+    
126
+    @Override
127
+    public Void visitRange(StoredType context, RangeTypeID range) throws RuntimeException {
128
+        //NO-OP
129
+        return null;
130
+    }
131
+    
132
+    @Override
133
+    public Void visitOptional(StoredType context, OptionalTypeID type) throws RuntimeException {
134
+        //NO-OP
135
+        return null;
136
+    }
137
+}

+ 1134
- 1106
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
File diff suppressed because it is too large
View File


+ 69
- 37
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java View File

@@ -1,32 +1,44 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
2 2
 
3
-import org.openzen.zenscript.codemodel.member.MethodMember;
4
-import org.openzen.zenscript.javashared.*;
5 3
 import org.objectweb.asm.ClassWriter;
6 4
 import org.objectweb.asm.Opcodes;
7
-import org.openzen.zenscript.codemodel.definition.*;
5
+import org.openzen.zenscript.codemodel.definition.AliasDefinition;
6
+import org.openzen.zenscript.codemodel.definition.ClassDefinition;
7
+import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
8
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
9
+import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
10
+import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
11
+import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
12
+import org.openzen.zenscript.codemodel.definition.StructDefinition;
13
+import org.openzen.zenscript.codemodel.definition.VariantDefinition;
8 14
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
9 15
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
16
+import org.openzen.zenscript.codemodel.member.ImplementationMember;
10 17
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
11 18
 import org.openzen.zenscript.codemodel.type.GenericTypeID;
19
+import org.openzen.zenscript.codemodel.type.StoredType;
12 20
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
13
-import org.openzen.zenscript.javabytecode.compiler.*;
21
+import org.openzen.zenscript.javabytecode.compiler.CompilerUtils;
22
+import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
23
+import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
24
+import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
25
+import org.openzen.zenscript.javashared.JavaClass;
26
+import org.openzen.zenscript.javashared.JavaMethod;
27
+import org.openzen.zenscript.javashared.JavaModifiers;
28
+import org.openzen.zenscript.javashared.JavaTypeGenericVisitor;
29
+import org.openzen.zenscript.javashared.JavaVariantOption;
14 30
 
15
-import java.io.FileNotFoundException;
16
-import java.io.FileOutputStream;
17
-import java.io.IOException;
18 31
 import java.util.ArrayList;
32
+import java.util.Collections;
19 33
 import java.util.List;
20
-import org.openzen.zenscript.codemodel.member.ImplementationMember;
21
-import org.openzen.zenscript.codemodel.type.StoredType;
22 34
 
23 35
 
24 36
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
25
-	private static final JavaMethod CLASS_FORNAME
37
+	private final JavaMethod CLASS_FORNAME
26 38
 			= JavaMethod.getNativeStatic(JavaClass.CLASS, "forName", "(Ljava/lang/String;)Ljava/lang/Class;");
27
-	private static final JavaMethod ENUM_VALUEOF
39
+	private final JavaMethod ENUM_VALUEOF
28 40
 			= JavaMethod.getNativeStatic(JavaClass.CLASS, "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
29
-	private static final JavaMethod ARRAY_CLONE
41
+	private final JavaMethod ARRAY_CLONE
30 42
 			= JavaMethod.getNativeVirtual(JavaClass.ARRAYS, "clone", "()Ljava/lang/Object;");
31 43
 
32 44
 	private final JavaClassWriter outerWriter;
@@ -52,9 +64,43 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
52 64
 			if (member instanceof ImplementationMember)
53 65
 				interfaces.add(context.getInternalName(((ImplementationMember) member).type));
54 66
 		}
55
-        String signature = null;
67
+        String signature;
68
+
69
+		{
70
+			final StringBuilder signatureBuilder = new StringBuilder();
71
+			if(definition.typeParameters.length != 0) {
72
+				signatureBuilder.append("<");
73
+				for (TypeParameter typeParameter : definition.typeParameters) {
74
+					signatureBuilder.append(typeParameter.name);
75
+					signatureBuilder.append(":");
76
+					signatureBuilder.append("Ljava/lang/Object;");
77
+				}
78
+				signatureBuilder.append(">");
79
+			}
80
+
81
+			signatureBuilder.append("L").append(superTypeInternalName).append(";");
82
+			for (IDefinitionMember member : definition.members) {
83
+				if(member instanceof ImplementationMember) {
84
+					signatureBuilder.append(context.getInternalName(((ImplementationMember) member).type));
85
+				}
86
+			}
87
+
88
+			signature = signatureBuilder.toString();
89
+		}
56 90
 
57 91
         writer.visit(Opcodes.V1_8, definition.modifiers, toClass.internalName, signature, superTypeInternalName, interfaces.toArray(new String[0]));
92
+		for (TypeParameter typeParameter : definition.typeParameters) {
93
+			//Add it to the class
94
+			writer.visitField(
95
+					Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL,
96
+					"typeOf" + typeParameter.name,
97
+					"Ljava/lang/Class;",
98
+					"Ljava/lang/Class<T" + typeParameter.name + ";>;",
99
+					//"Ljava/lang/Class;",
100
+					null
101
+			);
102
+		}
103
+
58 104
 		JavaMemberVisitor memberVisitor = new JavaMemberVisitor(context, writer, toClass, definition);
59 105
         for (IDefinitionMember member : definition.members) {
60 106
             member.accept(memberVisitor);
@@ -87,7 +133,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
87 133
 
88 134
 	@Override
89 135
 	public byte[] visitEnum(EnumDefinition definition) {
90
-		System.out.println("Compiling enum " + definition.name + " in " + definition.position.getFilename());
136
+		context.logger.debug("Compiling enum " + definition.name + " in " + definition.position.getFilename());
91 137
 
92 138
 		String superTypeInternalName = definition.getSuperType() == null ? "java/lang/Object" : context.getInternalName(definition.getSuperType());
93 139
 
@@ -105,7 +151,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
105 151
         }
106 152
 
107 153
 		JavaMethod valuesMethod = JavaMethod.getStatic(toClass, "values", "()[L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
108
-		JavaWriter valuesWriter = new JavaWriter(definition.position, writer, true, valuesMethod, definition, null, null);
154
+		JavaWriter valuesWriter = new JavaWriter(context.logger, definition.position, writer, true, valuesMethod, definition, null, null);
109 155
 		valuesWriter.start();
110 156
 		valuesWriter.getStaticField(toClass.internalName, "$VALUES", "[L" + toClass.internalName + ";");
111 157
 		valuesWriter.invokeVirtual(ARRAY_CLONE);
@@ -114,7 +160,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
114 160
 		valuesWriter.end();
115 161
 
116 162
 		JavaMethod valueOfMethod = JavaMethod.getStatic(toClass, "valueOf", "(Ljava/lang/String;)L" + toClass.internalName + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
117
-		JavaWriter valueOfWriter = new JavaWriter(definition.position, writer, true, valueOfMethod, definition, null, null);
163
+		JavaWriter valueOfWriter = new JavaWriter(context.logger, definition.position, writer, true, valueOfMethod, definition, null, null);
118 164
 		valueOfWriter.start();
119 165
 		valueOfWriter.invokeStatic(CLASS_FORNAME);
120 166
 		valueOfWriter.loadObject(0);
@@ -134,12 +180,13 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
134 180
 
135 181
 	@Override
136 182
 	public byte[] visitFunction(FunctionDefinition definition) {
137
-		CompilerUtils.tagMethodParameters(context, context.getJavaModule(definition.module), definition.header, true);
183
+		CompilerUtils.tagMethodParameters(context, context.getJavaModule(definition.module), definition.header, true, Collections
184
+                .emptyList());
138 185
 
139 186
         final String signature = context.getMethodSignature(definition.header);
140 187
 		final JavaMethod method = context.getJavaMethod(definition.caller);
141 188
 
142
-		final JavaWriter writer = new JavaWriter(definition.position, outerWriter, true, method, definition, signature, null);
189
+		final JavaWriter writer = new JavaWriter(context.logger, definition.position, outerWriter, true, method, definition, signature, null);
143 190
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, context.getJavaModule(definition.module), writer);
144 191
         statementVisitor.start();
145 192
 		boolean returns = definition.caller.body.accept(statementVisitor);
@@ -173,15 +220,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
173 220
 		writer.visitEnd();
174 221
 
175 222
 
176
-		final byte[] classBytes = writer.toByteArray();
177
-
178
-		try (FileOutputStream out = new FileOutputStream("ttt.class")) {
179
-			out.write(classBytes);
180
-		} catch (IOException e) {
181
-			e.printStackTrace();
182
-		}
183
-
184
-		return classBytes;
223
+		return writer.toByteArray();
185 224
 	}
186 225
 
187 226
 	@Override
@@ -262,7 +301,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
262 301
 			optionInitSignatureBuilder.append(")V");
263 302
 
264 303
 			JavaMethod constructorMethod = JavaMethod.getConstructor(optionTag.variantOptionClass, optionInitDescBuilder.toString(), JavaModifiers.PUBLIC);
265
-			final JavaWriter initWriter = new JavaWriter(option.position, optionWriter, constructorMethod, variant, optionInitSignatureBuilder.toString(), null);
304
+			final JavaWriter initWriter = new JavaWriter(context.logger, option.position, optionWriter, constructorMethod, variant, optionInitSignatureBuilder.toString(), null);
266 305
 			initWriter.start();
267 306
 			initWriter.loadObject(0);
268 307
 			initWriter.dup();
@@ -280,7 +319,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
280 319
 
281 320
 			//Denominator for switch-cases
282 321
 			JavaMethod denominator = JavaMethod.getVirtual(optionTag.variantOptionClass, "getDenominator", "()I", JavaModifiers.PUBLIC);
283
-			final JavaWriter getDenominator = new JavaWriter(option.position, optionWriter, denominator, null, null, null, "java/lang/Override");
322
+			final JavaWriter getDenominator = new JavaWriter(context.logger, option.position, optionWriter, denominator, null, null, null, "java/lang/Override");
284 323
 			getDenominator.start();
285 324
 			getDenominator.constant(option.ordinal);
286 325
 			getDenominator.returnInt();
@@ -290,13 +329,6 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
290 329
 			optionWriter.visitEnd();
291 330
 			final byte[] byteArray = optionWriter.toByteArray();
292 331
 			context.register(optionTag.variantOptionClass.internalName, byteArray);
293
-
294
-			//Print the option files, won't be in production
295
-			try (FileOutputStream out = new FileOutputStream(optionTag.variantOptionClass.internalName.replace('/', '_') + ".class")) {
296
-				out.write(byteArray);
297
-			} catch (IOException e) {
298
-				e.printStackTrace();
299
-			}
300 332
 		}
301 333
 
302 334
 
@@ -304,7 +336,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
304 336
 			member.accept(visitor);
305 337
 		}
306 338
 
307
-		final JavaWriter superInitWriter = new JavaWriter(variant.position, writer, JavaMethod.getConstructor(toClass, "()V", Opcodes.ACC_PUBLIC), variant, "()V", null);
339
+		final JavaWriter superInitWriter = new JavaWriter(context.logger, variant.position, writer, JavaMethod.getConstructor(toClass, "()V", Opcodes.ACC_PUBLIC), variant, "()V", null);
308 340
 		superInitWriter.start();
309 341
 		superInitWriter.loadObject(0);
310 342
 		superInitWriter.invokeSpecial("java/lang/Object", "<init>", "()V");

+ 216
- 14
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaExpansionMemberVisitor.java View File

@@ -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;
@@ -14,6 +15,10 @@ import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
14 15
 import org.openzen.zenscript.javashared.JavaCompiledModule;
15 16
 import org.openzen.zenscript.javashared.JavaField;
16 17
 import org.openzen.zenscript.javashared.JavaMethod;
18
+import org.openzen.zenscript.javashared.JavaParameterInfo;
19
+
20
+import java.util.ArrayList;
21
+import java.util.stream.Collectors;
17 22
 
18 23
 public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
19 24
 
@@ -32,7 +37,7 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
32 37
 		this.context = context;
33 38
 		javaModule = context.getJavaModule(definition.module);
34 39
 
35
-		final JavaWriter javaWriter = new JavaWriter(definition.position, writer, new JavaMethod(context.getJavaClass(definition), JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
40
+		final JavaWriter javaWriter = new JavaWriter(context.logger, definition.position, writer, new JavaMethod(context.getJavaClass(definition), JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
36 41
 		this.clinitStatementVisitor = new JavaStatementVisitor(context, javaModule, javaWriter);
37 42
 		this.clinitStatementVisitor.start();
38 43
 		CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
@@ -79,38 +84,76 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
79 84
 		if (!method.compile)
80 85
 			return null;
81 86
 
87
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
88
+		expandedClass.type.extractTypeParameters(typeParameters);
82 89
 
83
-		CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic());
90
+		CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic(), typeParameters);
84 91
 
85 92
 		final String expandedClassDescriptor = context.getDescriptor(expandedClass);
93
+		final String expandedClassSignature = context.getSignature(expandedClass);
86 94
 		final Label methodStart = new Label();
87 95
 		final Label methodEnd = new Label();
88 96
 		final String methodSignature;
97
+		final String methodDescriptor;
98
+
99
+
89 100
 
90 101
 		if (!isStatic) {
91
-			methodSignature = "(" + expandedClassDescriptor + context.getMethodSignature(member.header).substring(1);
102
+			String methodSignature1 = context.getMethodSignature(member.header);
103
+
104
+			//Add the expanded type as first generic parameter to the list.
105
+			if(!typeParameters.isEmpty()){
106
+				final String collect = typeParameters.stream()
107
+						.map(t -> t.name + ":" + "Ljava/lang/Object;")
108
+						.collect(Collectors.joining("", "<", ""));
109
+				if(methodSignature1.startsWith("<")) {
110
+					methodSignature1 = collect + methodSignature1.substring(1);
111
+				} else {
112
+					methodSignature1 = collect + ">" + methodSignature1;
113
+				}
114
+			}
115
+
116
+			final StringBuilder typeParamSigBuilder = new StringBuilder();
117
+			final StringBuilder typeParamDescBuilder = new StringBuilder();
118
+			int i = 1;
119
+			for (TypeParameter typeParameter : typeParameters) {
120
+				typeParamSigBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
121
+				typeParamDescBuilder.append("Ljava/lang/Class;");
122
+			}
123
+
124
+
125
+			final int index = methodSignature1.lastIndexOf('(') + 1;
126
+			methodSignature = methodSignature1.substring(0, index) + expandedClassSignature + typeParamSigBuilder.toString() + methodSignature1.substring(index);
127
+			methodDescriptor = "(" + expandedClassDescriptor + typeParamDescBuilder.toString() + context.getMethodDescriptor(member.header).substring(1);
92 128
 		} else {
93 129
 			methodSignature = context.getMethodSignature(member.header);
130
+			methodDescriptor = context.getMethodDescriptor(member.header);
94 131
 		}
95 132
 
96 133
 
97
-		final JavaWriter methodWriter = new JavaWriter(member.position, writer, true, method, definition, true, methodSignature, methodSignature, null);
134
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, writer, true, method, definition, true, methodSignature, methodDescriptor, null);
98 135
 		methodWriter.label(methodStart);
99 136
 
100 137
 		if (!isStatic) {
101 138
 			methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, Type.getType(expandedClassDescriptor));
102 139
 			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));
140
+
141
+			for (TypeParameter typeParameter : typeParameters) {
142
+				methodWriter.nameParameter(0, "typeOf" + typeParameter.name);
143
+				methodWriter.nameVariable(javaModule.getTypeParameterInfo(typeParameter).parameterIndex, "typeOf" + typeParameter.name, methodStart, methodEnd, Type.getType(Class.class));
111 144
 			}
112 145
 		}
113 146
 
147
+		for (TypeParameter typeParameter : member.header.typeParameters) {
148
+			methodWriter.nameParameter(0, "typeOf" + typeParameter.name);
149
+			methodWriter.nameVariable(javaModule.getTypeParameterInfo(typeParameter).parameterIndex, "typeOf" + typeParameter.name, methodStart, methodEnd, Type.getType(Class.class));
150
+		}
151
+
152
+		for (final FunctionParameter parameter : member.header.parameters) {
153
+			methodWriter.nameParameter(0, parameter.name);
154
+			methodWriter.nameVariable(javaModule.getParameterInfo(parameter).index, parameter.name, methodStart, methodEnd, context.getType(parameter.type));
155
+		}
156
+
114 157
 
115 158
 		{
116 159
 			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
@@ -126,21 +169,173 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
126 169
 
127 170
 	@Override
128 171
 	public Void visitGetter(GetterMember member) {
172
+		final boolean isStatic = member.isStatic();
173
+		final StoredType returnType = member.getType();
174
+		final String descriptor;
175
+		final String signature;
176
+
177
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
178
+		expandedClass.type.extractTypeParameters(typeParameters);
179
+		{
180
+
181
+			final String descMiddle, signatureMiddle, signatureStart;
182
+			if (typeParameters.isEmpty()) {
183
+				descMiddle = signatureMiddle = signatureStart = "";
184
+			} else {
185
+				final StringBuilder descMiddleBuilder = new StringBuilder();
186
+				final StringBuilder signatureMiddleBuilder = new StringBuilder();
187
+				final StringBuilder signatureStartBuilder = new StringBuilder("<");
188
+
189
+				for (TypeParameter typeParameter : typeParameters) {
190
+					descMiddleBuilder.append("Ljava/lang/Class;");
191
+					signatureMiddleBuilder.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
192
+					signatureStartBuilder.append(typeParameter.name).append(":Ljava/lang/Object;");
193
+				}
194
+
195
+				descMiddle = descMiddleBuilder.toString();
196
+				signatureMiddle = signatureMiddleBuilder.toString();
197
+				signatureStart = signatureStartBuilder.append(">").toString();
198
+			}
199
+
200
+
201
+			if (isStatic) {
202
+				descriptor = "(" + descMiddle + ")" + context.getDescriptor(returnType);
203
+				signature = signatureStart + "(" + signatureMiddle + ")" + context.getSignature(returnType);
204
+			} else {
205
+				descriptor = "(" + context.getDescriptor(expandedClass) + descMiddle + ")" + context.getDescriptor(returnType);
206
+				signature = signatureStart + "(" + context.getSignature(expandedClass) + signatureMiddle + ")" + context
207
+						.getSignature(returnType);
208
+			}
209
+		}
210
+
211
+		final Label methodStart = new Label();
212
+		final Label methodEnd = new Label();
213
+
214
+		final JavaMethod method = context.getJavaMethod(member);
215
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, this.writer, true, method, definition, true, signature, descriptor, new String[0]);
216
+
217
+		methodWriter.label(methodStart);
218
+
219
+		if (!isStatic) {
220
+			methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
221
+			methodWriter.nameParameter(0, "expandedObj");
222
+		}
223
+
224
+		int i = isStatic ? 0 : 1;
225
+		for (TypeParameter typeParameter : typeParameters) {
226
+			final String name = "typeOf" + typeParameter.name;
227
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
228
+			methodWriter.nameParameter(0, name);
229
+		}
230
+
231
+		{
232
+			final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
233
+			statementVisitor.start();
234
+			member.body.accept(statementVisitor);
235
+			methodWriter.label(methodEnd);
236
+			statementVisitor.end();
237
+		}
238
+
129 239
 		return null;
130 240
 	}
131 241
 
132 242
 	@Override
133 243
 	public Void visitSetter(SetterMember member) {
244
+		final boolean isStatic = member.isStatic();
245
+		final StoredType setterType = member.parameter.type;
246
+
247
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
248
+		expandedClass.type.extractTypeParameters(typeParameters);
249
+		CompilerUtils.tagMethodParameters(context, javaModule, member.getHeader(), isStatic, typeParameters);
250
+		setterType.type.extractTypeParameters(typeParameters);
251
+
252
+
253
+		final String signature = context.getMethodSignatureExpansion(member.getHeader(), expandedClass);
254
+		final String description = context.getMethodDescriptorExpansion(member.getHeader(), expandedClass);
255
+
256
+		final Label methodStart = new Label();
257
+		final Label methodEnd = new Label();
258
+
259
+		final JavaMethod javaMethod = context.getJavaMethod(member);
260
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, writer, true, javaMethod, member.definition, true, signature, description, new String[0]);
261
+
262
+
263
+		methodWriter.label(methodStart);
264
+		if (!isStatic) {
265
+			methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
266
+			methodWriter.nameParameter(0, "expandedObj");
267
+		}
268
+
269
+		int i = isStatic ? 0 : 1;
270
+		for (TypeParameter typeParameter : typeParameters) {
271
+			final String name = "typeOf" + typeParameter.name;
272
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
273
+			methodWriter.nameParameter(0, name);
274
+			i++;
275
+		}
276
+
277
+		//in script you use $ but the parameter is named "value", which to choose?
278
+		//final String name = member.parameter.name;
279
+		final String name = "$";
280
+		methodWriter.nameVariable(i, name, methodStart, methodEnd, context.getType(setterType));
281
+		methodWriter.nameParameter(0, name);
282
+
283
+		javaModule.setParameterInfo(member.parameter, new JavaParameterInfo(i, context.getDescriptor(setterType)));
284
+
285
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
286
+		javaStatementVisitor.start();
287
+		member.body.accept(javaStatementVisitor);
288
+		javaStatementVisitor.end();
289
+		methodWriter.label(methodEnd);
290
+
134 291
 		return null;
135 292
 	}
136 293
 
137 294
 	@Override
138 295
 	public Void visitOperator(OperatorMember member) {
139
-		return null;
296
+		final JavaMethod javaMethod = context.getJavaMethod(member);
297
+		final MethodMember methodMember = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
298
+		methodMember.body = member.body;
299
+		methodMember.annotations = member.annotations;
300
+		javaModule.setMethodInfo(methodMember, javaMethod);
301
+
302
+		return methodMember.accept(this);
140 303
 	}
141 304
 
142 305
 	@Override
143 306
 	public Void visitCaster(CasterMember member) {
307
+
308
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
309
+		expandedClass.type.extractTypeParameters(typeParameters);
310
+
311
+		CompilerUtils.tagMethodParameters(context, javaModule, member.getHeader(), false, typeParameters);
312
+		member.toType.type.extractTypeParameters(typeParameters);
313
+
314
+		final String methodSignature = context.getMethodSignatureExpansion(member.getHeader(), expandedClass);
315
+		final String methodDescriptor = context.getMethodDescriptorExpansion(member.getHeader(), expandedClass);
316
+
317
+		final Label methodStart = new Label();
318
+		final Label methodEnd = new Label();
319
+
320
+		final JavaMethod javaMethod = context.getJavaMethod(member);
321
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, writer, true, javaMethod, member.definition, true, methodSignature, methodDescriptor, new String[0]);
322
+
323
+		methodWriter.label(methodStart);
324
+		methodWriter.nameVariable(0, "expandedObj", methodStart, methodEnd, context.getType(this.expandedClass));
325
+		methodWriter.nameParameter(0, "expandedObj");
326
+
327
+		int i = 1;
328
+		for (TypeParameter typeParameter : typeParameters) {
329
+			final String name = "typeOf" + typeParameter.name;
330
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
331
+			methodWriter.nameParameter(0, name);
332
+		}
333
+
334
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
335
+		javaStatementVisitor.start();
336
+		member.body.accept(javaStatementVisitor);
337
+		javaStatementVisitor.end();
338
+		methodWriter.label(methodEnd);
144 339
 		return null;
145 340
 	}
146 341
 
@@ -151,7 +346,14 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
151 346
 
152 347
 	@Override
153 348
 	public Void visitCaller(CallerMember member) {
154
-		return null;
349
+		//It's gonna be a method anyways, so why not reuse the code ^^
350
+		final JavaMethod javaMethod = context.getJavaMethod(member);
351
+		final MethodMember call = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
352
+		call.body = member.body;
353
+		call.annotations = member.annotations;
354
+
355
+		javaModule.setMethodInfo(call, javaMethod);
356
+		return call.accept(this);
155 357
 	}
156 358
 
157 359
 	@Override

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

@@ -4,21 +4,24 @@ import org.objectweb.asm.ClassWriter;
4 4
 import org.objectweb.asm.Label;
5 5
 import org.objectweb.asm.Opcodes;
6 6
 import org.objectweb.asm.Type;
7
+import org.openzen.zencode.shared.logging.*;
7 8
 import org.openzen.zenscript.codemodel.FunctionParameter;
8 9
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
9 10
 import org.openzen.zenscript.codemodel.Modifiers;
11
+import org.openzen.zenscript.codemodel.annotations.NativeTag;
10 12
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
11 13
 import org.openzen.zenscript.codemodel.expression.Expression;
14
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 15
 import org.openzen.zenscript.codemodel.member.*;
16
+import org.openzen.zenscript.codemodel.type.StoredType;
13 17
 import org.openzen.zenscript.javabytecode.compiler.*;
14 18
 
19
+import java.util.ArrayList;
20
+import java.util.Arrays;
21
+import java.util.Collections;
15 22
 import java.util.List;
16 23
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
17
-import org.openzen.zenscript.javashared.JavaClass;
18
-import org.openzen.zenscript.javashared.JavaCompiledModule;
19
-import org.openzen.zenscript.javashared.JavaField;
20
-import org.openzen.zenscript.javashared.JavaImplementation;
21
-import org.openzen.zenscript.javashared.JavaMethod;
24
+import org.openzen.zenscript.javashared.*;
22 25
 
23 26
 public class JavaMemberVisitor implements MemberVisitor<Void> {
24 27
     private final ClassWriter writer;
@@ -36,7 +39,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
36 39
 		this.context = context;
37 40
 		javaModule = context.getJavaModule(definition.module);
38 41
 
39
-        final JavaWriter javaWriter = new JavaWriter(definition.position, writer, new JavaMethod(toClass, JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
42
+        final JavaWriter javaWriter = new JavaWriter(context.logger, definition.position, writer, new JavaMethod(toClass, JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
40 43
         this.clinitStatementVisitor = new JavaStatementVisitor(context, javaModule, javaWriter);
41 44
         this.clinitStatementVisitor.start();
42 45
         CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
@@ -63,9 +66,25 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
63 66
 
64 67
         final Label constructorStart = new Label();
65 68
         final Label constructorEnd = new Label();
66
-        final JavaWriter constructorWriter = new JavaWriter(member.position, writer, method, definition, context.getMethodSignature(member.header), null);
69
+        final JavaWriter constructorWriter = new JavaWriter(context.logger, member.position, writer, method, definition, context.getMethodSignature(member.header), null);
67 70
         constructorWriter.label(constructorStart);
68 71
         CompilerUtils.tagConstructorParameters(context, javaModule, member.definition, member.header, isEnum);
72
+        if(isEnum) {
73
+			constructorWriter.nameParameter(0, "name");
74
+			constructorWriter.nameParameter(0, "index");
75
+		}
76
+
77
+		for (TypeParameter typeParameter : definition.typeParameters) {
78
+			constructorWriter.nameParameter(0, "typeof" + typeParameter.name);
79
+			constructorWriter.nameVariable(
80
+					javaModule.getTypeParameterInfo(typeParameter).parameterIndex,
81
+					"typeOf" + typeParameter.name,
82
+					constructorStart,
83
+					constructorEnd,
84
+					Type.getType(Class.class)
85
+			);
86
+		}
87
+
69 88
         for (FunctionParameter parameter : member.header.parameters) {
70 89
             constructorWriter.nameVariable(
71 90
                     javaModule.getParameterInfo(parameter).index,
@@ -80,7 +99,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
80 99
 
81 100
 		if (!member.isConstructorForwarded()) {
82 101
 			if (isEnum) {
83
-				System.out.println("Writing enum constructor");
102
+				context.logger.debug("Writing enum constructor");
84 103
 				constructorWriter.getVisitor().newLocal(Type.getType(String.class));
85 104
 				constructorWriter.getVisitor().newLocal(Type.getType(int.class));
86 105
 				constructorWriter.loadObject(0);
@@ -88,11 +107,34 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
88 107
 				constructorWriter.loadInt(2);
89 108
 				constructorWriter.invokeSpecial(Type.getInternalName(Enum.class), "<init>", "(Ljava/lang/String;I)V");
90 109
 			} else if (definition.getSuperType() == null) {
91
-				System.out.println("Writing regular constructor");
110
+				context.logger.debug("Writing regular constructor");
92 111
 				constructorWriter.loadObject(0);
93 112
 				constructorWriter.invokeSpecial(Type.getInternalName(Object.class), "<init>", "()V");
94 113
 			}
95 114
         }
115
+    
116
+        for(IDefinitionMember membersOfSameType : member.definition.members) {
117
+            if(membersOfSameType instanceof FieldMember) {
118
+                final FieldMember fieldMember = ((FieldMember) membersOfSameType);
119
+                final Expression initializer = fieldMember.initializer;
120
+                if(initializer != null) {
121
+                    constructorWriter.loadObject(0);
122
+                    initializer.accept(statementVisitor.expressionVisitor);
123
+                    constructorWriter.putField(context.getJavaField(fieldMember));
124
+                }
125
+            }
126
+        }
127
+
128
+		for (TypeParameter typeParameter : definition.typeParameters) {
129
+			final JavaTypeParameterInfo typeParameterInfo = javaModule.getTypeParameterInfo(typeParameter);
130
+			final JavaField field = typeParameterInfo.field;
131
+
132
+			//Init from Constructor
133
+			final int parameterIndex = typeParameterInfo.parameterIndex;
134
+			constructorWriter.loadObject(0);
135
+			constructorWriter.loadObject(parameterIndex);
136
+			constructorWriter.putField(field);
137
+		}
96 138
 
97 139
 		if (member.body != null) {
98 140
 			member.body.accept(statementVisitor);
@@ -115,7 +157,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
115 157
 
116 158
 		final Label constructorStart = new Label();
117 159
 		final Label constructorEnd = new Label();
118
-		final JavaWriter destructorWriter = new JavaWriter(member.position, writer, method, definition, null, null);
160
+		final JavaWriter destructorWriter = new JavaWriter(context.logger, member.position, writer, method, definition, null, null);
119 161
 		destructorWriter.label(constructorStart);
120 162
 		
121 163
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, destructorWriter);
@@ -129,12 +171,12 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
129 171
 
130 172
     @Override
131 173
     public Void visitMethod(MethodMember member) {
132
-        CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic());
174
+        CompilerUtils.tagMethodParameters(context, javaModule, member.header, member.isStatic(), Collections.emptyList());
133 175
 
134 176
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.getEffectiveModifiers());
135 177
         final JavaMethod method = context.getJavaMethod(member);
136 178
 		
137
-		final JavaWriter methodWriter = new JavaWriter(member.position, writer, method, definition, context.getMethodSignature(member.header), null);
179
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, writer, method, definition, context.getMethodSignature(member.header), null);
138 180
 
139 181
 		if (!isAbstract) {
140 182
 			if (method.isAbstract() || method.cls.kind == JavaClass.Kind.INTERFACE)
@@ -155,21 +197,105 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
155 197
 
156 198
 	@Override
157 199
 	public Void visitGetter(GetterMember member) {
200
+		if (member.hasTag(NativeTag.class)) {
201
+			return null;
202
+		}
203
+
204
+		final String descriptor = context.getMethodDescriptor(member.getHeader());
205
+		final String signature = context.getMethodSignature(member.getHeader(), true);
206
+
207
+		final Label methodStart = new Label();
208
+		final Label methodEnd = new Label();
209
+
210
+		final JavaMethod method = context.getJavaMethod(member);
211
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, this.writer, true, method, definition, false, signature, descriptor, new String[0]);
212
+
213
+		methodWriter.label(methodStart);
214
+		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
215
+		statementVisitor.start();
216
+		member.body.accept(statementVisitor);
217
+		methodWriter.label(methodEnd);
218
+		statementVisitor.end();
219
+
158 220
 		return null;
159 221
 	}
160 222
 
161 223
 	@Override
162 224
 	public Void visitSetter(SetterMember member) {
225
+		final String signature = context.getMethodSignature(member.getHeader());
226
+		final String description = context.getMethodDescriptor(member.getHeader());
227
+
228
+		final Label methodStart = new Label();
229
+		final Label methodEnd = new Label();
230
+
231
+		final JavaMethod javaMethod = context.getJavaMethod(member);
232
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, writer, true, javaMethod, member.definition, false, signature, description, new String[0]);
233
+		methodWriter.label(methodStart);
234
+
235
+		//in script you use $ but the parameter is named "value", which to choose?
236
+		//final String name = member.parameter.name;
237
+		final String name = "$";
238
+		methodWriter.nameVariable(1, name, methodStart, methodEnd, context.getType(member.getType()));
239
+		methodWriter.nameParameter(0, name);
240
+
241
+		javaModule.setParameterInfo(member.parameter, new JavaParameterInfo(1, context.getDescriptor(member.getType())));
242
+
243
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
244
+		javaStatementVisitor.start();
245
+		member.body.accept(javaStatementVisitor);
246
+		javaStatementVisitor.end();
247
+		methodWriter.label(methodEnd);
248
+
163 249
 		return null;
164 250
 	}
165 251
 
166 252
 	@Override
167 253
 	public Void visitOperator(OperatorMember member) {
168
-		return null;
254
+
255
+		final JavaMethod javaMethod = context.getJavaMethod(member);
256
+		final MethodMember methodMember = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
257
+		methodMember.body = member.body;
258
+		methodMember.annotations = member.annotations;
259
+		javaModule.setMethodInfo(methodMember, javaMethod);
260
+
261
+		return methodMember.accept(this);
169 262
 	}
170 263
 
171 264
 	@Override
172 265
 	public Void visitCaster(CasterMember member) {
266
+		final JavaMethod javaMethod = context.getJavaMethod(member);
267
+		if(javaMethod == null || !javaMethod.compile) {
268
+			return null;
269
+		}
270
+
271
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>(Arrays.asList(this.definition.typeParameters));
272
+
273
+		CompilerUtils.tagMethodParameters(context, javaModule, member.getHeader(), false, typeParameters);
274
+		member.toType.type.extractTypeParameters(typeParameters);
275
+
276
+		final String methodSignature = context.getMethodSignature(member.getHeader());
277
+		final String methodDescriptor = context.getMethodDescriptor(member.getHeader());
278
+
279
+		final Label methodStart = new Label();
280
+		final Label methodEnd = new Label();
281
+
282
+
283
+		final JavaWriter methodWriter = new JavaWriter(context.logger, member.position, writer, true, javaMethod, member.definition, false, methodSignature, methodDescriptor, new String[0]);
284
+
285
+		methodWriter.label(methodStart);
286
+
287
+		int i = 1;
288
+		for (TypeParameter typeParameter : typeParameters) {
289
+			final String name = "typeOf" + typeParameter.name;
290
+			methodWriter.nameVariable(i, name, methodStart, methodEnd, Type.getType(Class.class));
291
+			methodWriter.nameParameter(0, name);
292
+		}
293
+
294
+		final JavaStatementVisitor javaStatementVisitor = new JavaStatementVisitor(context, javaModule, methodWriter);
295
+		javaStatementVisitor.start();
296
+		member.body.accept(javaStatementVisitor);
297
+		javaStatementVisitor.end();
298
+		methodWriter.label(methodEnd);
173 299
 		return null;
174 300
 	}
175 301
 
@@ -180,7 +306,14 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
180 306
 
181 307
 	@Override
182 308
 	public Void visitCaller(CallerMember member) {
183
-		return null;
309
+		//It's gonna be a method anyways, so why not reuse the code ^^
310
+		final JavaMethod javaMethod = context.getJavaMethod(member);
311
+		final MethodMember call = new MethodMember(member.position, member.definition, member.getEffectiveModifiers(), javaMethod.name, member.header, member.builtin);
312
+		call.body = member.body;
313
+		call.annotations = member.annotations;
314
+
315
+		javaModule.setMethodInfo(call, javaMethod);
316
+		return call.accept(this);
184 317
 	}
185 318
 
186 319
 	@Override
@@ -190,6 +323,13 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
190 323
 			for (IDefinitionMember imember : member.members)
191 324
 				imember.accept(this);
192 325
 		} else {
326
+			//TODO: Fixme???
327
+			// What should I do if a native class has interfaces to be visited?
328
+			if(javaModule.getNativeClassInfo(member.definition) != null) {
329
+				return null;
330
+			}
331
+
332
+
193 333
 			throw new UnsupportedOperationException("Non-inline interface implementations not yet available");
194 334
 		}
195 335
 		return null;

JavaIntegration/src/main/resources/StdLibs.zip → JavaIntegration/StdLibs.jar View File


+ 10
- 11
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeLoader.java View File

@@ -5,12 +5,10 @@
5 5
  */
6 6
 package org.openzen.zencode.java;
7 7
 
8
-import java.util.ArrayList;
9
-import java.util.HashMap;
10
-import java.util.List;
11
-import java.util.Map;
8
+import java.util.*;
12 9
 import java.util.function.Consumer;
13 10
 import org.openzen.zencode.shared.CompileException;
11
+import org.openzen.zencode.shared.logging.*;
14 12
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
15 13
 
16 14
 /**
@@ -20,13 +18,14 @@ import org.openzen.zenscript.codemodel.definition.ZSPackage;
20 18
 public class JavaNativeLoader {
21 19
 	private final Class<?>[] classes;
22 20
 	private final Class<?>[] globals;
23
-	private final Map<String, LoadingModule> modulesByBasePackage = new HashMap<>();
24 21
 	private final Map<String, LoadingModule> modulesByName = new HashMap<>();
25
-	private boolean loaded = false;
22
+    private final IZSLogger logger;
23
+    private boolean loaded = false;
26 24
 	
27
-	public JavaNativeLoader(Class<?>[] classes, Class<?>[] globals) {
25
+	public JavaNativeLoader(Class<?>[] classes, Class<?>[] globals, IZSLogger logger) {
28 26
 		this.classes = classes;
29 27
 		this.globals = globals;
28
+		this.logger = logger;
30 29
 	}
31 30
 	
32 31
 	public LoadingModule addModule(
@@ -40,7 +39,6 @@ public class JavaNativeLoader {
40 39
 			throw new IllegalArgumentException("Module already exists: " + name);
41 40
 		
42 41
 		LoadingModule module = new LoadingModule(pkg, name, basePackage, dependencies);
43
-		modulesByBasePackage.put(name, module);
44 42
 		modulesByName.put(name, module);
45 43
 		
46 44
 		return module;
@@ -52,7 +50,7 @@ public class JavaNativeLoader {
52 50
 		sortClasses();
53 51
 		
54 52
 		ScriptingEngine engine = new ScriptingEngine();
55
-		for (LoadingModule module : modulesByBasePackage.values()) {
53
+		for (LoadingModule module : modulesByName.values()) {
56 54
 			load(engine, module);
57 55
 		}
58 56
 		return engine;
@@ -70,7 +68,7 @@ public class JavaNativeLoader {
70 68
 		for (Class<?> cls : classes) {
71 69
 			LoadingModule module = findModuleByPackage(modulesByPackage, getPackageName(cls));
72 70
 			if (module == null) {
73
-				System.out.println("Warning: module not found for class " + cls.getName());
71
+				logger.warning("Module not found for class " + cls.getName());
74 72
 			} else {
75 73
 				module.classes.add(cls);
76 74
 			}
@@ -78,7 +76,7 @@ public class JavaNativeLoader {
78 76
 		for (Class<?> cls : globals) {
79 77
 			LoadingModule module = findModuleByPackage(modulesByPackage, getPackageName(cls));
80 78
 			if (module == null) {
81
-				System.out.println("Warning: module not found for class " + cls.getName());
79
+				logger.warning("Module not found for class " + cls.getName());
82 80
 			} else {
83 81
 				module.globals.add(cls);
84 82
 			}
@@ -115,6 +113,7 @@ public class JavaNativeLoader {
115 113
 		}
116 114
 		
117 115
 		module.resolved = new JavaNativeModule(
116
+                logger,
118 117
 				module.pkg,
119 118
 				module.name,
120 119
 				module.basePackage,

+ 682
- 316
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java
File diff suppressed because it is too large
View File


+ 68
- 58
JavaIntegration/src/main/java/org/openzen/zencode/java/ScriptingEngine.java View File

@@ -5,31 +5,22 @@
5 5
  */
6 6
 package org.openzen.zencode.java;
7 7
 
8
-import java.io.File;
9
-import java.io.IOException;
10
-import java.util.ArrayList;
11
-import java.util.Collections;
12
-import java.util.List;
13
-import java.util.Map;
14
-import org.openzen.zencode.shared.CompileException;
15
-import org.openzen.zencode.shared.SourceFile;
16
-import org.openzen.zenscript.codemodel.FunctionParameter;
17
-import org.openzen.zenscript.codemodel.Module;
18
-import org.openzen.zenscript.codemodel.ModuleSpace;
19
-import org.openzen.zenscript.codemodel.SemanticModule;
20
-import org.openzen.zenscript.codemodel.context.CompilingPackage;
21
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
22
-import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
23
-import org.openzen.zenscript.codemodel.type.ISymbol;
24
-import org.openzen.zenscript.codemodel.type.storage.StorageType;
25
-import org.openzen.zenscript.javabytecode.JavaBytecodeRunUnit;
26
-import org.openzen.zenscript.javabytecode.JavaCompiler;
27
-import org.openzen.zenscript.javashared.SimpleJavaCompileSpace;
28
-import org.openzen.zenscript.lexer.ParseException;
29
-import org.openzen.zenscript.parser.BracketExpressionParser;
30
-import org.openzen.zenscript.parser.ParsedFile;
31
-import org.openzen.zenscript.parser.ZippedPackage;
32
-import org.openzen.zenscript.validator.Validator;
8
+import org.openzen.zencode.java.logger.*;
9
+import org.openzen.zencode.shared.*;
10
+import org.openzen.zenscript.codemodel.*;
11
+import org.openzen.zenscript.codemodel.context.*;
12
+import org.openzen.zenscript.codemodel.definition.*;
13
+import org.openzen.zenscript.codemodel.type.*;
14
+import org.openzen.zenscript.codemodel.type.storage.*;
15
+import org.openzen.zenscript.javabytecode.*;
16
+import org.openzen.zenscript.javashared.*;
17
+import org.openzen.zenscript.lexer.*;
18
+import org.openzen.zenscript.parser.*;
19
+import org.openzen.zenscript.validator.*;
20
+
21
+import java.io.*;
22
+import java.lang.reflect.InvocationTargetException;
23
+import java.util.*;
33 24
 
34 25
 /**
35 26
  *
@@ -46,32 +37,34 @@ public class ScriptingEngine {
46 37
 	
47 38
 	public boolean debug = false;
48 39
 	
40
+	public final ScriptingEngineLogger logger;
41
+	
49 42
 	public ScriptingEngine() {
50
-		space = new ModuleSpace(registry, new ArrayList<>(), StorageType.getStandard());
51
-		
52
-		try {
53
-			ZippedPackage stdlibs = new ZippedPackage(ScriptingEngine.class.getResourceAsStream("/StdLibs.zip"));
54
-			SemanticModule stdlibModule = stdlibs.loadModule(space, "stdlib", null, new SemanticModule[0], FunctionParameter.NONE, stdlib);
55
-			stdlibModule = Validator.validate(stdlibModule, error -> System.out.println(error.toString()));
56
-			space.addModule("stdlib", stdlibModule);
57
-		} catch (IOException ex) {
58
-			throw new RuntimeException(ex);
59
-		} catch (CompileException ex) {
60
-			throw new RuntimeException(ex);
61
-		} catch (ParseException ex) {
62
-			throw new RuntimeException(ex);
63
-		}
64
-	}
43
+        this(new ScriptingEngineStreamLogger());
44
+    }
45
+    
46
+    public ScriptingEngine(ScriptingEngineLogger logger) {
47
+        this.space = new ModuleSpace(registry, new ArrayList<>(), StorageType.getStandard());
48
+        this.logger = logger;
49
+        try {
50
+            ZippedPackage stdlibs = new ZippedPackage(ScriptingEngine.class.getResourceAsStream("/StdLibs.jar"));
51
+            SemanticModule stdlibModule = stdlibs.loadModule(space, "stdlib", null, SemanticModule.NONE, FunctionParameter.NONE, stdlib, logger);
52
+            stdlibModule = Validator.validate(stdlibModule, logger);
53
+            space.addModule("stdlib", stdlibModule);
54
+            registerCompiled(stdlibModule);
55
+        } catch (CompileException | ParseException | IOException ex) {
56
+            throw new RuntimeException(ex);
57
+        }
58
+    }
65 59
 	
66 60
 	public JavaNativeModule createNativeModule(String name, String basePackage, JavaNativeModule... dependencies) {
67 61
 		ZSPackage testPackage = new ZSPackage(space.rootPackage, name);
68
-		return new JavaNativeModule(testPackage, name, basePackage, registry, dependencies);
62
+		return new JavaNativeModule(logger, testPackage, name, basePackage, registry, dependencies);
69 63
 	}
70 64
 	
71 65
 	public void registerNativeProvided(JavaNativeModule module) throws CompileException {
72 66
 		SemanticModule semantic = Validator.validate(
73
-				module.toSemantic(space),
74
-				entry -> System.out.println(entry));
67
+				module.toSemantic(space), logger);
75 68
 		if (!semantic.isValid())
76 69
 			return;
77 70
 		
@@ -97,8 +90,10 @@ public class ScriptingEngine {
97 90
 		CompilingPackage scriptPackage = new CompilingPackage(new ZSPackage(space.rootPackage, name), scriptModule);
98 91
 		
99 92
 		ParsedFile[] files = new ParsedFile[sources.length];
100
-		for (int i = 0; i < sources.length; i++)
93
+		for (int i = 0; i < sources.length; i++) {
94
+			logger.logSourceFile(sources[i]);
101 95
 			files[i] = ParsedFile.parse(scriptPackage, bracketParser, sources[i]);
96
+		}
102 97
 		
103 98
 		SemanticModule[] dependencyModules = new SemanticModule[dependencies.length + 1];
104 99
 		dependencyModules[0] = space.getModule("stdlib");
@@ -112,13 +107,13 @@ public class ScriptingEngine {
112 107
 				files,
113 108
 				space,
114 109
 				scriptParameters,
115
-				ex -> ex.printStackTrace());
110
+				logger);
116 111
 		if (!scripts.isValid())
117 112
 			return scripts;
118 113
 		
119 114
 		return Validator.validate(
120 115
 				scripts.normalize(),
121
-				error -> System.out.println(error.toString()));
116
+				logger);
122 117
 	}
123 118
 	
124 119
 	public void registerCompiled(SemanticModule module) {
@@ -132,19 +127,34 @@ public class ScriptingEngine {
132 127
 	public void run(Map<FunctionParameter, Object> arguments) {
133 128
 		run(arguments, this.getClass().getClassLoader());
134 129
 	}
130
+	
131
+	public JavaBytecodeRunUnit createRunUnit() {
132
+        SimpleJavaCompileSpace javaSpace = new SimpleJavaCompileSpace(registry);
133
+        for (JavaNativeModule nativeModule : nativeModules)
134
+            javaSpace.register(nativeModule.getCompiled());
135
+        
136
+        JavaCompiler compiler = new JavaCompiler(logger);
137
+        
138
+        JavaBytecodeRunUnit runUnit = new JavaBytecodeRunUnit(logger);
139
+        for (SemanticModule compiled : compiledModules)
140
+            runUnit.add(compiler.compile(compiled.name, compiled, javaSpace));
141
+        if (debug)
142
+            runUnit.dump(new File("classes"));
143
+        
144
+        return runUnit;
145
+    }
135 146
 
136 147
 	public void run(Map<FunctionParameter, Object> arguments, ClassLoader parentClassLoader) {
137
-		SimpleJavaCompileSpace javaSpace = new SimpleJavaCompileSpace(registry);
138
-		for (JavaNativeModule nativeModule : nativeModules)
139
-			javaSpace.register(nativeModule.getCompiled());
140
-
141
-		JavaCompiler compiler = new JavaCompiler();
142
-
143
-		JavaBytecodeRunUnit runUnit = new JavaBytecodeRunUnit();
144
-		for (SemanticModule compiled : compiledModules)
145
-			runUnit.add(compiler.compile(compiled.name, compiled, javaSpace));
146
-		if (debug)
147
-			runUnit.dump(new File("classes"));
148
-		runUnit.run(arguments, parentClassLoader);
148
+	    JavaBytecodeRunUnit runUnit = createRunUnit();
149
+        
150
+        try {
151
+            runUnit.run(arguments, parentClassLoader);
152
+        } catch(ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
153
+            logger.throwingErr(e.getCause().getMessage(), e.getCause());
154
+        }
155
+    }
156
+	
157
+	public List<JavaNativeModule> getNativeModules() {
158
+		return Collections.unmodifiableList(this.nativeModules);
149 159
 	}
150 160
 }

+ 7
- 0
JavaIntegration/src/main/java/org/openzen/zencode/java/logger/ScriptingEngineLogger.java View File

@@ -0,0 +1,7 @@
1
+package org.openzen.zencode.java.logger;
2
+
3
+import org.openzen.zencode.shared.logging.*;
4
+import org.openzen.zenscript.parser.logger.*;
5
+import org.openzen.zenscript.validator.logger.*;
6
+
7
+public interface ScriptingEngineLogger extends ValidatorLogger, SourceFileLogger, ParserLogger {}

+ 83
- 0
JavaIntegration/src/main/java/org/openzen/zencode/java/logger/ScriptingEngineStreamLogger.java View File

@@ -0,0 +1,83 @@
1
+package org.openzen.zencode.java.logger;
2
+
3
+import org.openzen.zencode.shared.*;
4
+import org.openzen.zenscript.validator.*;
5
+
6
+import java.io.*;
7
+
8
+public class ScriptingEngineStreamLogger implements ScriptingEngineLogger {
9
+    
10
+    private final PrintStream infoStream, debugStream, warningStream, errorStream;
11
+    
12
+    public ScriptingEngineStreamLogger(PrintStream debugStream, PrintStream infoStream, PrintStream warningStream, PrintStream errorStream) {
13
+        this.infoStream = infoStream;
14
+        this.debugStream = debugStream;
15
+        this.warningStream = warningStream;
16
+        this.errorStream = errorStream;
17
+    }
18
+    
19
+    public ScriptingEngineStreamLogger(PrintStream normalStream, PrintStream errorStream) {
20
+        this(normalStream, normalStream, normalStream, errorStream);
21
+    }
22
+    
23
+    public ScriptingEngineStreamLogger() {
24
+        this(System.out, System.err);
25
+    }
26
+    
27
+    @Override
28
+    public void info(String message) {
29
+        infoStream.println("INFO: " + message);
30
+        infoStream.flush();
31
+    }
32
+    
33
+    @Override
34
+    public void debug(String message) {
35
+        debugStream.println("DEBUG:   " + message);
36
+        debugStream.flush();
37
+    }
38
+    
39
+    @Override
40
+    public void warning(String message) {
41
+        warningStream.println("WARNING: " + message);
42
+        warningStream.flush();
43
+    }
44
+    
45
+    @Override
46
+    public void error(String message) {
47
+        errorStream.println("ERROR:   " + message);
48
+    }
49
+    
50
+    @Override
51
+    public void throwingErr(String message, Throwable throwable) {
52
+        errorStream.println("ERROR:   " + message);
53
+        throwable.printStackTrace(errorStream);
54
+        errorStream.flush();
55
+    }
56
+    
57
+    @Override
58
+    public void throwingWarn(String message, Throwable throwable) {
59
+        warningStream.println("WARNING: " + message);
60
+        throwable.printStackTrace(warningStream);
61
+        warningStream.flush();
62
+    }
63
+    
64
+    @Override
65
+    public void logCompileException(CompileException exception) {
66
+        throwingErr("Compile Exception:", exception);
67
+    }
68
+    
69
+    @Override
70
+    public void logSourceFile(SourceFile file) {
71
+        info("Loading File: " + file.getFilename());
72
+    }
73
+    
74
+    @Override
75
+    public void logValidationError(ValidationLogEntry errorEntry) {
76
+        error(errorEntry.toString());
77
+    }
78
+    
79
+    @Override
80
+    public void logValidationWarning(ValidationLogEntry warningEntry) {
81
+        warning(warningEntry.toString());
82
+    }
83
+}

+ 3
- 3
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaClass.java View File

@@ -42,8 +42,8 @@ public class JavaClass implements Comparable<JavaClass> {
42 42
 			return new JavaClass("", internalName, kind, new String[0]);
43 43
 		
44 44
 		int lastSlash = internalName.lastIndexOf('/');
45
-		if (lastSlash < 0)
46
-			System.out.println(internalName);
45
+		//if (lastSlash < 0)
46
+		//	System.out.println(internalName);
47 47
 		
48 48
 		String pkg = lastSlash < 0 ? "" : internalName.substring(0, lastSlash);
49 49
 		String className = lastSlash < 0 ? internalName : internalName.substring(lastSlash + 1);
@@ -53,7 +53,7 @@ public class JavaClass implements Comparable<JavaClass> {
53 53
 	
54 54
 	public static String getNameFromFile(String filename) {
55 55
 		if (filename.indexOf('.') > 0)
56
-			return filename.substring(0, filename.indexOf('.'));
56
+			return filename.substring(0, filename.lastIndexOf('.'));
57 57
 		else
58 58
 			return filename;
59 59
 	}

+ 2
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaCompileSpace.java View File

@@ -13,6 +13,8 @@ import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
13 13
  * @author Hoofdgebruiker
14 14
  */
15 15
 public interface JavaCompileSpace {
16
+	void register(JavaCompiledModule module);
17
+
16 18
 	GlobalTypeRegistry getRegistry();
17 19
 	
18 20
 	JavaCompiledModule getCompiled(Module module);

+ 12
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaCompiledModule.java View File

@@ -185,4 +185,16 @@ public class JavaCompiledModule {
185 185
 		
186 186
 		return info;
187 187
 	}
188
+    
189
+    public void addAllFrom(JavaCompiledModule compiled) {
190
+        this.classes.putAll(compiled.classes);
191
+        this.expansionClasses.putAll(compiled.expansionClasses);
192
+        this.nativeClasses.putAll(compiled.nativeClasses);
193
+        this.implementations.putAll(compiled.implementations);
194
+        this.fields.putAll(compiled.fields);
195
+        this.methods.putAll(compiled.methods);
196
+        this.typeParameters.putAll(compiled.typeParameters);
197
+        this.parameters.putAll(compiled.parameters);
198
+        this.variantOptions.putAll(compiled.variantOptions);
199
+    }
188 200
 }

+ 57
- 7
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java View File

@@ -10,14 +10,17 @@ import java.util.HashMap;
10 10
 import java.util.List;
11 11
 import java.util.Map;
12 12
 import org.openzen.zencode.shared.CodePosition;
13
+import org.openzen.zencode.shared.logging.*;
13 14
 import org.openzen.zenscript.codemodel.FunctionHeader;
14 15
 import org.openzen.zenscript.codemodel.FunctionParameter;
15 16
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
16 17
 import org.openzen.zenscript.codemodel.Modifiers;
17 18
 import org.openzen.zenscript.codemodel.Module;
19
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
18 20
 import org.openzen.zenscript.codemodel.definition.VariantDefinition;
19 21
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
20 22
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
23
+import org.openzen.zenscript.codemodel.member.DefinitionMember;
21 24
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
22 25
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
23 26
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
@@ -46,8 +49,10 @@ public abstract class JavaContext {
46 49
 	
47 50
 	public final ZSPackage modulePackage;
48 51
 	public final String basePackage;
52
+	public final IZSLogger logger;
49 53
 	
50
-	public JavaContext(JavaCompileSpace space, ZSPackage modulePackage, String basePackage) {
54
+	public JavaContext(JavaCompileSpace space, ZSPackage modulePackage, String basePackage, IZSLogger logger) {
55
+	    this.logger = logger;
51 56
 		this.space = space;
52 57
 		this.registry = space.getRegistry();
53 58
 		
@@ -125,9 +130,16 @@ public abstract class JavaContext {
125 130
 	public abstract String getDescriptor(TypeID type);
126 131
 	
127 132
 	public abstract String getDescriptor(StoredType type);
128
-	
133
+
134
+	public String getSignature(StoredType type) {
135
+		return new JavaTypeGenericVisitor(this).getGenericSignature(type);
136
+	}
137
+
129 138
 	public void addModule(Module module, JavaCompiledModule target) {
130 139
 		modules.put(module, target);
140
+
141
+		//TODO: can we do this here?
142
+		space.register(target);
131 143
 	}
132 144
 	
133 145
 	public JavaCompiledModule getJavaModule(Module module) {
@@ -218,15 +230,34 @@ public abstract class JavaContext {
218 230
 	}
219 231
 	
220 232
 	public String getMethodDescriptor(FunctionHeader header) {
221
-		return getMethodDescriptor(header, false);
233
+		return getMethodDescriptor(header, false, "");
234
+	}
235
+
236
+	public String getMethodDescriptorExpansion(FunctionHeader header, StoredType expandedType) {
237
+		StringBuilder startBuilder = new StringBuilder(getDescriptor(expandedType));
238
+		final List<TypeParameter> typeParameters = new ArrayList<>();
239
+		expandedType.type.extractTypeParameters(typeParameters);
240
+		for (TypeParameter typeParameter : typeParameters) {
241
+			startBuilder.append("Ljava/lang/Class;");
242
+		}
243
+
244
+		return getMethodDescriptor(header, false, startBuilder.toString());
245
+	}
246
+
247
+	public String getMethodSignatureExpansion(FunctionHeader header, StoredType expandedClass) {
248
+		return new JavaTypeGenericVisitor(this).getMethodSignatureExpansion(header, expandedClass);
222 249
 	}
223 250
 	
224 251
     public String getMethodSignature(FunctionHeader header) {
225
-        return new JavaTypeGenericVisitor(this).getGenericMethodSignature(header);
252
+        return getMethodSignature(header, true);
226 253
     }
254
+
255
+    public String getMethodSignature(FunctionHeader header, boolean withGenerics) {
256
+		return new JavaTypeGenericVisitor(this).getGenericMethodSignature(header, withGenerics);
257
+	}
227 258
 	
228 259
 	public String getEnumConstructorDescriptor(FunctionHeader header) {
229
-		return getMethodDescriptor(header, true);
260
+		return getMethodDescriptor(header, true, "");
230 261
 	}
231 262
 	
232 263
 	public JavaSynthesizedFunctionInstance getFunction(FunctionTypeID type) {
@@ -336,14 +367,25 @@ public abstract class JavaContext {
336 367
 			return new JavaSynthesizedClass(range.cls, new TypeID[] { type.baseType.type });
337 368
 		}
338 369
 	}
339
-	
340
-	private String getMethodDescriptor(FunctionHeader header, boolean isEnumConstructor) {
370
+
371
+	/**
372
+	 * @param header Function Header
373
+	 * @param isEnumConstructor If this is an enum constructor, add String, int as parameters
374
+	 * @param expandedType If this is for an expanded type, add the type at the beginning.
375
+	 *                        Can be null or an empty string if this is not an expansion method header
376
+	 * @return Method descriptor {@code (<LClass;*No.TypeParameters><LString;I if enum><expandedType><headerTypes>)<retType> }
377
+	 */
378
+	public String getMethodDescriptor(FunctionHeader header, boolean isEnumConstructor, String expandedType) {
341 379
         StringBuilder descBuilder = new StringBuilder("(");
342 380
 		for (int i = 0; i < header.getNumberOfTypeParameters(); i++)
343 381
 			descBuilder.append("Ljava/lang/Class;");
344 382
 		
345 383
         if (isEnumConstructor)
346 384
             descBuilder.append("Ljava/lang/String;I");
385
+
386
+        //TODO: Put this earlier? We'd need to agree on one...
387
+        if(expandedType != null)
388
+        	descBuilder.append(expandedType);
347 389
 		
348 390
         for (FunctionParameter parameter : header.parameters) {
349 391
 			descBuilder.append(getDescriptor(parameter.type));
@@ -352,4 +394,12 @@ public abstract class JavaContext {
352 394
         descBuilder.append(getDescriptor(header.getReturnType()));
353 395
         return descBuilder.toString();
354 396
     }
397
+
398
+	public String getMethodDescriptorConstructor(FunctionHeader header, DefinitionMember member) {
399
+		StringBuilder startBuilder = new StringBuilder();
400
+		for (TypeParameter typeParameter : member.definition.typeParameters) {
401
+			startBuilder.append("Ljava/lang/Class;");
402
+		}
403
+		return getMethodDescriptor(header, member.definition instanceof EnumDefinition, startBuilder.toString());
404
+	}
355 405
 }

+ 0
- 113
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaDefaultExpressionTypeVisitor.java View File

@@ -1,113 +0,0 @@
1
-package org.openzen.zenscript.javashared;
2
-
3
-import org.openzen.zencode.shared.CodePosition;
4
-import org.openzen.zenscript.codemodel.expression.*;
5
-import org.openzen.zenscript.codemodel.type.*;
6
-
7
-public class JavaDefaultExpressionTypeVisitor implements TypeVisitor<Expression> {
8
-
9
-	public static final JavaDefaultExpressionTypeVisitor INSTANCE = new JavaDefaultExpressionTypeVisitor();
10
-
11
-	private JavaDefaultExpressionTypeVisitor(){}
12
-
13
-	@Override
14
-	public Expression visitBasic(BasicTypeID basic) {
15
-
16
-
17
-		if (basic == null)
18
-			throw new IllegalStateException("Null basic type!");
19
-
20
-		switch (basic) {
21
-			case UNDETERMINED:
22
-			case VOID:
23
-				throw new IllegalStateException("Void and Undetermined have no default type");
24
-			case NULL:
25
-				return new NullExpression(CodePosition.UNKNOWN);
26
-			case BOOL:
27
-				return new ConstantBoolExpression(CodePosition.UNKNOWN, false);
28
-			case BYTE:
29
-				return new ConstantByteExpression(CodePosition.UNKNOWN, 0);
30
-			case SBYTE:
31
-				return new ConstantSByteExpression(CodePosition.UNKNOWN, (byte) 0);
32
-			case SHORT:
33
-				return new ConstantShortExpression(CodePosition.UNKNOWN, (short) 0);
34
-			case USHORT:
35
-				return new ConstantUShortExpression(CodePosition.UNKNOWN, 0);
36
-			case INT:
37
-				return new ConstantIntExpression(CodePosition.UNKNOWN, 0);
38
-			case UINT:
39
-				return new ConstantUIntExpression(CodePosition.UNKNOWN, 0);
40
-			case LONG:
41
-				return new ConstantLongExpression(CodePosition.UNKNOWN, 0L);
42
-			case ULONG:
43
-				return new ConstantULongExpression(CodePosition.UNKNOWN, 0L);
44
-			case USIZE:
45
-				return new ConstantUSizeExpression(CodePosition.UNKNOWN, 0L);
46
-			case FLOAT:
47
-				return new ConstantFloatExpression(CodePosition.UNKNOWN, 0.0f);
48
-			case DOUBLE:
49
-				return new ConstantDoubleExpression(CodePosition.UNKNOWN, 0.0d);
50
-			case CHAR:
51
-				return new ConstantCharExpression(CodePosition.UNKNOWN, '\0');
52
-			default:
53
-				throw new IllegalStateException("Unknown basic type!");
54
-		}
55
-
56
-
57
-	}
58
-
59
-	@Override
60
-	public Expression visitString(StringTypeID string) {
61
-		return new NullExpression(CodePosition.UNKNOWN);
62
-	}
63
-
64
-	@Override
65
-	public Expression visitArray(ArrayTypeID array) {
66
-		return new NullExpression(CodePosition.UNKNOWN);
67
-	}
68
-
69
-	@Override
70
-	public Expression visitAssoc(AssocTypeID assoc) {
71
-		return new NullExpression(CodePosition.UNKNOWN);
72
-	}
73
-
74
-	@Override
75
-	public Expression visitGenericMap(GenericMapTypeID map) {
76
-		return new NullExpression(CodePosition.UNKNOWN);
77
-	}
78
-
79
-	@Override
80
-	public Expression visitIterator(IteratorTypeID iterator) {
81
-		return new NullExpression(CodePosition.UNKNOWN);
82
-	}
83
-
84
-	@Override
85
-	public Expression visitFunction(FunctionTypeID function) {
86
-		return new NullExpression(CodePosition.UNKNOWN);
87
-	}
88
-
89
-	@Override
90
-	public Expression visitDefinition(DefinitionTypeID definition) {
91
-		return new NullExpression(CodePosition.UNKNOWN);
92
-	}
93
-
94
-	@Override
95
-	public Expression visitGeneric(GenericTypeID generic) {
96
-		return new NullExpression(CodePosition.UNKNOWN);
97
-	}
98
-
99
-	@Override
100
-	public Expression visitRange(RangeTypeID range) {
101
-		return new NullExpression(CodePosition.UNKNOWN);
102
-	}
103
-
104
-	@Override
105
-	public Expression visitOptional(OptionalTypeID type) {
106
-		return new NullExpression(CodePosition.UNKNOWN);
107
-	}
108
-
109
-	@Override
110
-	public Expression visitInvalid(InvalidTypeID type) {
111
-		return new NullExpression(CodePosition.UNKNOWN);
112
-	}
113
-}

+ 6
- 1
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaField.java View File

@@ -13,12 +13,17 @@ public class JavaField {
13 13
 	public final JavaClass cls;
14 14
 	public final String name;
15 15
 	public final String descriptor;
16
-	public final String signature = null; // TODO: calculate signature too
16
+	public final String signature; // TODO: calculate signature too
17 17
 	
18 18
 	public JavaField(JavaClass cls, String name, String descriptor) {
19
+		this(cls, name, descriptor, null);
20
+	}
21
+
22
+	public JavaField(JavaClass cls, String name, String descriptor, String signature) {
19 23
 		this.cls = cls;
20 24
 		this.name = name;
21 25
 		this.descriptor = descriptor;
26
+		this.signature = signature;
22 27
 	}
23 28
 	
24 29
 	public String getMapping(JavaClass definition) {

+ 18
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaFunctionalInterfaceStorageTag.java View File

@@ -6,6 +6,8 @@
6 6
 package org.openzen.zenscript.javashared;
7 7
 
8 8
 import java.lang.reflect.Method;
9
+import java.util.*;
10
+
9 11
 import org.openzen.zenscript.codemodel.type.storage.AutoStorageTag;
10 12
 import org.openzen.zenscript.codemodel.type.storage.BorrowStorageTag;
11 13
 import org.openzen.zenscript.codemodel.type.storage.SharedStorageTag;
@@ -57,4 +59,20 @@ public class JavaFunctionalInterfaceStorageTag implements StorageTag {
57 59
 	public boolean isImmutable() {
58 60
 		return true;
59 61
 	}
62
+    
63
+    @Override
64
+    public boolean equals(Object o) {
65
+        if(this == o)
66
+            return true;
67
+        if(o == null || getClass() != o.getClass())
68
+            return false;
69
+        
70
+        JavaFunctionalInterfaceStorageTag other = (JavaFunctionalInterfaceStorageTag) o;
71
+        return Objects.equals(functionalInterfaceMethod, other.functionalInterfaceMethod);
72
+    }
73
+    
74
+    @Override
75
+    public int hashCode() {
76
+        return functionalInterfaceMethod != null ? functionalInterfaceMethod.hashCode() : 0;
77
+    }
60 78
 }

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

@@ -43,7 +43,7 @@ public class JavaMethod {
43 43
     public static JavaMethod getInterface(JavaClass cls, String name, String descriptor) {
44 44
         return new JavaMethod(cls, Kind.INTERFACE, name, false, descriptor, JavaModifiers.PUBLIC, false);
45 45
     }
46
-
46
+    
47 47
 	public static JavaMethod getNativeExpansion(JavaClass cls, String name, String descriptor) {
48 48
 		return new JavaMethod(cls, Kind.EXPANSION, name, false, descriptor, JavaModifiers.PUBLIC | JavaModifiers.STATIC, false);
49 49
 	}

+ 85
- 3
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaTypeGenericVisitor.java View File

@@ -4,7 +4,10 @@ import org.openzen.zenscript.codemodel.FunctionHeader;
4 4
 import org.openzen.zenscript.codemodel.FunctionParameter;
5 5
 import org.openzen.zenscript.codemodel.generic.*;
6 6
 import org.openzen.zenscript.codemodel.type.*;
7
+import org.openzen.zenscript.codemodel.type.storage.ValueStorageTag;
7 8
 
9
+import java.util.ArrayList;
10
+import java.util.Arrays;
8 11
 import java.util.Collection;
9 12
 
10 13
 public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType, String, RuntimeException> {
@@ -59,6 +62,34 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
59 62
 				getGenericSignature(header.getReturnType());
60 63
 	}
61 64
 
65
+	public String getGenericMethodSignature(FunctionHeader header, boolean addGenerics) {
66
+		final StringBuilder sb = new StringBuilder();
67
+		final boolean doGenerics = addGenerics && header.typeParameters.length > 0;
68
+
69
+		if(doGenerics) {
70
+			sb.append("<");
71
+			for (TypeParameter typeParameter : header.typeParameters) {
72
+				//TODO: Eventually replace with upper bound
73
+				sb.append(typeParameter.name).append(":").append("Ljava/lang/Object;");
74
+			}
75
+			sb.append(">");
76
+		}
77
+
78
+
79
+		sb.append("(");
80
+		if(doGenerics) {
81
+			for (TypeParameter typeParameter : header.typeParameters) {
82
+				//TODO: Eventually replace with -TT; or +TT; for "? super T" and "? extends T"
83
+				sb.append("Ljava/lang/Class<T").append(typeParameter.name).append(";>;");
84
+			}
85
+		}
86
+
87
+		sb.append(getGenericSignature(header.parameters));
88
+		sb.append(")");
89
+		sb.append(getGenericSignature(header.getReturnType()));
90
+		return sb.toString();
91
+	}
92
+
62 93
 
63 94
 	public String getGenericBounds(Collection<TypeParameterBound> collection) {
64 95
 		if (collection == null)
@@ -93,12 +124,17 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
93 124
 
94 125
 	@Override
95 126
 	public String visitArray(StoredType context, ArrayTypeID array) {
96
-		return this.context.getDescriptor(array);
127
+		final char[] dim = new char[array.dimension];
128
+		Arrays.fill(dim, '[');
129
+		return new String(dim) + this.context.getSignature(array.elementType);
97 130
 	}
98 131
 
99 132
 	@Override
100 133
 	public String visitAssoc(StoredType context, AssocTypeID assoc) {
101
-		return this.context.getDescriptor(assoc);
134
+		return "Ljava/util/Map<"
135
+				+ assoc.keyType.type.accept(context, this)
136
+				+ assoc.valueType.type.accept(context, this)
137
+				+ ">;";
102 138
 	}
103 139
 
104 140
 	@Override
@@ -113,7 +149,21 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
113 149
 
114 150
 	@Override
115 151
 	public String visitFunction(StoredType context, FunctionTypeID function) {
116
-		return this.context.getDescriptor(function);
152
+		final JavaSynthesizedFunctionInstance function1 = this.context.getFunction(function);
153
+		if(function1.typeArguments == null || function1.typeArguments.length == 0) {
154
+			return this.context.getDescriptor(function);
155
+		}
156
+
157
+		StringBuilder sb = new StringBuilder("L").append(function1.getCls().internalName).append("<");
158
+		for (TypeID typeArgument : function1.typeArguments) {
159
+			final String n = typeArgument instanceof GenericTypeID
160
+					? ((GenericTypeID) typeArgument).parameter.name
161
+					: "Ljava/lang/Object"; //Can latter even happen?
162
+
163
+			sb.append("T").append(n).append(";");
164
+		}
165
+
166
+		return sb.append(">;").toString();
117 167
 	}
118 168
 
119 169
 	@Override
@@ -146,4 +196,36 @@ public class JavaTypeGenericVisitor implements TypeVisitorWithContext<StoredType
146 196
 	public String visitOptional(StoredType context, OptionalTypeID type) {
147 197
 		return type.baseType.accept(context, this);
148 198
 	}
199
+
200
+	public String getMethodSignatureExpansion(FunctionHeader header, StoredType expandedClass) {
201
+		final StringBuilder stringBuilder = new StringBuilder();
202
+		final ArrayList<TypeParameter> typeParameters = new ArrayList<>();
203
+		expandedClass.type.extractTypeParameters(typeParameters);
204
+		for (TypeParameter typeParameter : header.typeParameters) {
205
+			if(!typeParameters.contains(typeParameter)){
206
+				typeParameters.add(typeParameter);
207
+			}
208
+		}
209
+
210
+		if(typeParameters.size() != 0) {
211
+			stringBuilder.append("<");
212
+			for (TypeParameter typeParameter : typeParameters) {
213
+				stringBuilder.append(typeParameter.name);
214
+				stringBuilder.append(":Ljava/lang/Object;");
215
+			}
216
+			stringBuilder.append(">");
217
+		}
218
+		stringBuilder.append("(");
219
+		stringBuilder.append(context.getSignature(expandedClass));
220
+		for (TypeParameter typeParameter : typeParameters) {
221
+			stringBuilder.append("Ljava/lang/Class<T");
222
+			stringBuilder.append(typeParameter.name);
223
+			stringBuilder.append(";>;");
224
+		}
225
+		stringBuilder.append(getGenericSignature(header.parameters));
226
+		stringBuilder.append(")");
227
+		stringBuilder.append(context.getSignature(header.getReturnType()));
228
+
229
+		return stringBuilder.toString();
230
+	}
149 231
 }

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

@@ -22,4 +22,9 @@ public class JavaTypeParameterInfo {
22 22
 		this.parameterIndex = -1;
23 23
 		this.field = field;
24 24
 	}
25
+
26
+	public JavaTypeParameterInfo(int parameterIndex, JavaField field) {
27
+		this.parameterIndex = parameterIndex;
28
+		this.field = field;
29
+	}
25 30
 }

+ 2
- 1
JavaShared/src/main/java/org/openzen/zenscript/javashared/SimpleJavaCompileSpace.java View File

@@ -21,7 +21,8 @@ public class SimpleJavaCompileSpace implements JavaCompileSpace {
21 21
 	public SimpleJavaCompileSpace(GlobalTypeRegistry registry) {
22 22
 		this.registry = registry;
23 23
 	}
24
-	
24
+
25
+	@Override
25 26
 	public void register(JavaCompiledModule module) {
26 27
 		modules.put(module.module, module);
27 28
 	}

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

@@ -73,16 +73,16 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
73 73
 	@Override
74 74
 	public Void visitConst(ConstMember member) {
75 75
 		if (DEBUG_EMPTY && cls.empty)
76
-			System.out.println("Class " + cls.fullName + " not empty because of const " + member.name);
76
+			context.logger.debug("Class " + cls.fullName + " not empty because of const " + member.name);
77 77
 		
78 78
 		cls.empty = false;
79
-		module.setFieldInfo(member, new JavaField(cls, member.name, context.getDescriptor(member.getType())));
79
+		module.setFieldInfo(member, new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType())));
80 80
 		return null;
81 81
 	}
82 82
 	
83 83
 	@Override
84 84
 	public Void visitField(FieldMember member) {
85
-		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()));
85
+		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType()));
86 86
 		module.setFieldInfo(member, field);
87 87
 		if (member.hasAutoGetter()) {
88 88
 			visitGetter(member.autoGetter);
@@ -105,7 +105,7 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
105 105
 	@Override
106 106
 	public Void visitDestructor(DestructorMember member) {
107 107
 		if (DEBUG_EMPTY && cls.empty)
108
-			System.out.println("Class " + cls.fullName + " not empty because of destructor");
108
+			context.logger.debug("Class " + cls.fullName + " not empty because of destructor");
109 109
 		
110 110
 		cls.empty = false;
111 111
 		return null;
@@ -163,7 +163,7 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
163 163
 				m.accept(this);
164 164
 		} else {
165 165
 			if (DEBUG_EMPTY && cls.empty)
166
-				System.out.println("Class " + cls.fullName + " not empty because of unmergeable implementation");
166
+				context.logger.debug("Class " + cls.fullName + " not empty because of unmergeable implementation");
167 167
 			
168 168
 			cls.empty = false;
169 169
 			
@@ -187,7 +187,7 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
187 187
 		member.innerDefinition.accept(innerDefinitionPrepare);
188 188
 		
189 189
 		if (DEBUG_EMPTY && cls.empty)
190
-			System.out.println("Class " + cls.fullName + " not empty because of inner definition " + member.innerDefinition.name);
190
+			context.logger.debug("Class " + cls.fullName + " not empty because of inner definition " + member.innerDefinition.name);
191 191
 		cls.empty = false;
192 192
 		return null;
193 193
 	}
@@ -195,7 +195,7 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
195 195
 	@Override
196 196
 	public Void visitStaticInitializer(StaticInitializerMember member) {
197 197
 		if (DEBUG_EMPTY && cls.empty)
198
-			System.out.println("Class " + cls.fullName + " not empty because of static initializer");
198
+			context.logger.debug("Class " + cls.fullName + " not empty because of static initializer");
199 199
 		
200 200
 		cls.empty = false;
201 201
 		return null;
@@ -313,20 +313,33 @@ public class JavaPrepareClassMethodVisitor implements MemberVisitor<Void> {
313 313
 					header.getReturnType().type instanceof GenericTypeID,
314 314
 					header.useTypeParameters());
315 315
 		} else if (method == null) {
316
-			method = new JavaMethod(
317
-					cls,
318
-					getKind(member),
319
-					name,
320
-					true,
321
-					context.getMethodDescriptor(header),
322
-					modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
323
-					header.getReturnType().type instanceof GenericTypeID,
324
-					header.useTypeParameters());
316
+			if(member instanceof ConstructorMember) {
317
+				method = new JavaMethod(
318
+						cls,
319
+						getKind(member),
320
+						name,
321
+						true,
322
+						context.getMethodDescriptorConstructor(header, member),
323
+						modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
324
+						false,
325
+						header.useTypeParameters()
326
+				);
327
+			} else {
328
+				method = new JavaMethod(
329
+						cls,
330
+						getKind(member),
331
+						name,
332
+						true,
333
+						context.getMethodDescriptor(header),
334
+						modifiers | JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
335
+						header.getReturnType().type instanceof GenericTypeID,
336
+						header.useTypeParameters());
337
+			}
325 338
 		}
326 339
 		
327 340
 		if (method.compile && member.getBuiltin() != BuiltinID.CLASS_DEFAULT_CONSTRUCTOR) {
328 341
 			if (DEBUG_EMPTY && cls.empty)
329
-				System.out.println("Class " + cls.fullName + " not empty because of " + member.describe());
342
+				context.logger.debug("Class " + cls.fullName + " not empty because of " + member.describe());
330 343
 			
331 344
 			cls.empty = false;
332 345
 		}

+ 11
- 10
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionMemberVisitor.java View File

@@ -5,7 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.javashared.prepare;
7 7
 
8
-import org.openzen.zenscript.javashared.JavaNativeClass;
8
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
9
+import org.openzen.zenscript.javashared.*;
9 10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
11 12
 import org.openzen.zenscript.codemodel.definition.ClassDefinition;
@@ -19,11 +20,6 @@ import org.openzen.zenscript.codemodel.definition.VariantDefinition;
19 20
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
20 21
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
21 22
 import org.openzen.zenscript.codemodel.type.TypeID;
22
-import org.openzen.zenscript.javashared.JavaClass;
23
-import org.openzen.zenscript.javashared.JavaCompiledModule;
24
-import org.openzen.zenscript.javashared.JavaContext;
25
-import org.openzen.zenscript.javashared.JavaMethod;
26
-import org.openzen.zenscript.javashared.JavaModifiers;
27 23
 
28 24
 /**
29 25
  *
@@ -56,7 +52,7 @@ public class JavaPrepareDefinitionMemberVisitor implements DefinitionVisitor<Jav
56 52
 		if (definition.module != module.module)
57 53
 			throw new IllegalArgumentException("Definition is not in the same module as the current module!");
58 54
 		
59
-		System.out.println("~~ Preparing " + definition.name);
55
+		context.logger.debug("~~ Preparing " + definition.name);
60 56
 		definition.accept(this);
61 57
 	}
62 58
 	
@@ -64,7 +60,7 @@ public class JavaPrepareDefinitionMemberVisitor implements DefinitionVisitor<Jav
64 60
 	public JavaClass visitClass(ClassDefinition definition) {
65 61
 		if (isPrepared(definition))
66 62
 			return context.getJavaClass(definition);
67
-		
63
+
68 64
 		return visitClassCompiled(definition, true, JavaClass.Kind.CLASS);
69 65
 	}
70 66
 
@@ -134,6 +130,11 @@ public class JavaPrepareDefinitionMemberVisitor implements DefinitionVisitor<Jav
134 130
 	}
135 131
 	
136 132
 	private JavaClass visitClassCompiled(HighLevelDefinition definition, boolean startsEmpty, JavaClass.Kind kind) {
133
+
134
+		for (TypeParameter typeParameter : definition.typeParameters) {
135
+			module.setTypeParameterInfo(typeParameter, new JavaTypeParameterInfo(-1));
136
+		}
137
+
137 138
 		if (definition.getSuperType() != null)
138 139
 			prepare(definition.getSuperType());
139 140
 		
@@ -151,7 +152,7 @@ public class JavaPrepareDefinitionMemberVisitor implements DefinitionVisitor<Jav
151 152
 	}
152 153
 	
153 154
 	private void visitClassMembers(HighLevelDefinition definition, JavaClass cls, JavaNativeClass nativeClass, boolean startsEmpty) {
154
-		System.out.println("Preparing " + cls.internalName);
155
+		context.logger.debug("Preparing " + cls.internalName);
155 156
 		JavaPrepareClassMethodVisitor methodVisitor = new JavaPrepareClassMethodVisitor(context, module, cls, nativeClass, this, startsEmpty);
156 157
 		for (IDefinitionMember member : definition.members) {
157 158
 			member.accept(methodVisitor);
@@ -160,7 +161,7 @@ public class JavaPrepareDefinitionMemberVisitor implements DefinitionVisitor<Jav
160 161
 	}
161 162
 	
162 163
 	private void visitExpansionMembers(HighLevelDefinition definition, JavaClass cls, JavaNativeClass nativeClass) {
163
-		System.out.println("Preparing " + cls.internalName);
164
+		context.logger.debug("Preparing " + cls.internalName);
164 165
 		JavaPrepareExpansionMethodVisitor methodVisitor = new JavaPrepareExpansionMethodVisitor(context, module, cls, nativeClass);
165 166
 		for (IDefinitionMember member : definition.members) {
166 167
 			member.accept(methodVisitor);

+ 18
- 11
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionVisitor.java View File

@@ -5,10 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.javashared.prepare;
7 7
 
8
-import org.openzen.zenscript.javashared.JavaNativeClass;
9
-import java.util.HashMap;
10
-import java.util.List;
11
-import java.util.Map;
12 8
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
13 9
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
14 10
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
@@ -33,16 +29,21 @@ import org.openzen.zenscript.javashared.JavaCompiledModule;
33 29
 import org.openzen.zenscript.javashared.JavaContext;
34 30
 import org.openzen.zenscript.javashared.JavaMethod;
35 31
 import org.openzen.zenscript.javashared.JavaModifiers;
32
+import org.openzen.zenscript.javashared.JavaNativeClass;
36 33
 import org.openzen.zenscript.javashared.JavaVariantOption;
37 34
 
35
+import java.util.HashMap;
36
+import java.util.List;
37
+import java.util.Map;
38
+
38 39
 /**
39 40
  *
40 41
  * @author Hoofdgebruiker
41 42
  */
42 43
 public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass> {
43
-	private static final Map<String, JavaNativeClass> nativeClasses = new HashMap<>();
44
+	private final Map<String, JavaNativeClass> nativeClasses = new HashMap<>();
44 45
 	
45
-	static {
46
+	 {
46 47
 		{
47 48
 			JavaNativeClass cls = new JavaNativeClass(new JavaClass("java.lang", "StringBuilder", JavaClass.Kind.CLASS));
48 49
 			cls.addConstructor("constructor", "()V");
@@ -72,7 +73,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
72 73
 			JavaNativeClass list = new JavaNativeClass(new JavaClass("java.util", "List", JavaClass.Kind.INTERFACE));
73 74
 			JavaClass arrayList = new JavaClass("java.util", "ArrayList", JavaClass.Kind.CLASS);
74 75
 			list.addMethod("constructor", JavaMethod.getNativeConstructor(arrayList, "()V"));
75
-			list.addInstanceMethod("add", "add", "(Ljava/lang/Object;)Z"); List<?> l;
76
+			list.addInstanceMethod("add", "add", "(Ljava/lang/Object;)Z");
76 77
 			list.addInstanceMethod("insert", "add", "(Ljava/lang/Object;I)V");
77 78
 			list.addInstanceMethod("remove", "remove", "(Ljava/lang/Object;)Z");
78 79
 			list.addInstanceMethod("indexOf", "indexOf", "(Ljava/lang/Object;)I");
@@ -94,7 +95,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
94 95
 		}
95 96
 		
96 97
 		{
97
-			JavaNativeClass iterator = new JavaNativeClass(JavaClass.ITERATOR);
98
+			JavaNativeClass iterator = new JavaNativeClass(new JavaClass("java.util", "Iterator", JavaClass.Kind.INTERFACE));
98 99
 			iterator.addMethod("empty", new JavaMethod(JavaClass.COLLECTIONS, JavaMethod.Kind.STATIC, "emptyIterator", false, "()Ljava/lang/Iterator;", JavaModifiers.STATIC | JavaModifiers.PUBLIC, false));
99 100
 			iterator.addInstanceMethod("hasNext", "hasNext", "()Z");
100 101
 			iterator.addInstanceMethod("next", "next", "()Ljava/lang/Object;");
@@ -235,14 +236,20 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
235 236
 	
236 237
 	private final JavaContext context;
237 238
 	private final String filename;
239
+	private final String className;
238 240
 	private final JavaClass outerClass;
239 241
 	private final JavaCompiledModule module;
240
-	
242
+
241 243
 	public JavaPrepareDefinitionVisitor(JavaContext context, JavaCompiledModule module, String filename, JavaClass outerClass) {
244
+		this(context, module, filename, outerClass, JavaClass.getNameFromFile(filename));
245
+	}
246
+
247
+	public JavaPrepareDefinitionVisitor(JavaContext context, JavaCompiledModule module, String filename, JavaClass outerClass, String className) {
242 248
 		this.context = context;
243 249
 		this.filename = filename;
244 250
 		this.outerClass = outerClass;
245 251
 		this.module = module;
252
+		this.className = className;
246 253
 	}
247 254
 	
248 255
 	private boolean isPrepared(HighLevelDefinition definition) {
@@ -297,7 +304,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
297 304
 		if (isPrepared(definition))
298 305
 			return context.getJavaClass(definition);
299 306
 		
300
-		JavaClass cls = new JavaClass(context.getPackageName(definition.pkg), JavaClass.getNameFromFile(filename), JavaClass.Kind.CLASS);
307
+		JavaClass cls = new JavaClass(context.getPackageName(definition.pkg), className, JavaClass.Kind.CLASS);
301 308
 		context.setJavaClass(definition, cls);
302 309
 		return cls;
303 310
 	}
@@ -312,7 +319,7 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
312 319
 			context.setJavaNativeClass(definition, nativeClasses.get(nativeTag.value));
313 320
 		}
314 321
 		
315
-		JavaClass cls = new JavaClass(context.getPackageName(definition.pkg), JavaClass.getNameFromFile(filename), JavaClass.Kind.CLASS);
322
+		JavaClass cls = new JavaClass(context.getPackageName(definition.pkg), className, JavaClass.Kind.CLASS);
316 323
 		context.setJavaClass(definition, cls);
317 324
 		return cls;
318 325
 	}

+ 37
- 14
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareExpansionMethodVisitor.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.javashared.prepare;
7 7
 
8
+import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
8 9
 import org.openzen.zenscript.javashared.JavaNativeClass;
9 10
 import org.openzen.zencode.shared.StringExpansion;
10 11
 import org.openzen.zenscript.codemodel.FunctionHeader;
@@ -60,11 +61,11 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
60 61
 	
61 62
 	@Override
62 63
 	public Void visitConst(ConstMember member) {
63
-		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()));
64
+		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType()));
64 65
 		module.setFieldInfo(member, field);
65 66
 		
66 67
 		if (DEBUG_EMPTY && cls.empty)
67
-			System.out.println("Class " + cls.fullName + " not empty because of const");
68
+			context.logger.debug("Class " + cls.fullName + " not empty because of const");
68 69
 		
69 70
 		cls.empty = false;
70 71
 		return null;
@@ -73,7 +74,7 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
73 74
 	@Override
74 75
 	public Void visitField(FieldMember member) {
75 76
 		// TODO: expansion fields
76
-		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()));
77
+		JavaField field = new JavaField(cls, member.name, context.getDescriptor(member.getType()), context.getSignature(member.getType()));
77 78
 		module.setFieldInfo(member, field);
78 79
 		
79 80
 		if (member.hasAutoGetter() || member.hasAutoSetter())
@@ -166,20 +167,42 @@ public class JavaPrepareExpansionMethodVisitor implements MemberVisitor<Void> {
166 167
 		JavaMethod method = null;
167 168
 		if (nativeTag != null && nativeClass != null)
168 169
 			method = nativeClass.getMethod(nativeTag.value);
169
-		if (method == null)
170
-			method = new JavaMethod(
171
-					cls,
172
-					getKind(member),
173
-					name,
174
-					true,
175
-					context.getMethodDescriptor(header),
176
-					JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
177
-					header.getReturnType().type instanceof GenericTypeID,
178
-					header.useTypeParameters()); 
170
+		if (method == null) {
171
+
172
+			if(member instanceof ConstructorMember) {
173
+				method = new JavaMethod(
174
+						cls,
175
+						getKind(member),
176
+						name,
177
+						true,
178
+						context.getMethodDescriptorConstructor(header, member),
179
+						JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
180
+						false,
181
+						header.useTypeParameters()
182
+				);
183
+			} else {
184
+				final JavaMethod.Kind kind = getKind(member);
185
+				final String descriptor;
186
+				if (kind == JavaMethod.Kind.EXPANSION && member.definition instanceof ExpansionDefinition) {
187
+					descriptor = context.getMethodDescriptorExpansion(header, ((ExpansionDefinition) member.definition).target);
188
+				} else {
189
+					descriptor = context.getMethodDescriptor(header);
190
+				}
191
+				method = new JavaMethod(
192
+						cls,
193
+						kind,
194
+						name,
195
+						true,
196
+						descriptor,
197
+						JavaModifiers.getJavaModifiers(member.getEffectiveModifiers()),
198
+						header.getReturnType().type instanceof GenericTypeID,
199
+						header.useTypeParameters());
200
+			}
201
+		}
179 202
 		
180 203
 		if (method.compile) {
181 204
 			if (DEBUG_EMPTY && cls.empty)
182
-				System.out.println("Class " + cls.fullName + " not empty because of " + member.describe());
205
+				context.logger.debug("Class " + cls.fullName + " not empty because of " + member.describe());
183 206
 			
184 207
 			cls.empty = false;
185 208
 		}

+ 3
- 2
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceCompiler.java View File

@@ -8,6 +8,7 @@ package org.openzen.zenscript.javasource;
8 8
 import java.util.HashMap;
9 9
 import java.util.Map;
10 10
 import org.openzen.zencode.shared.SourceFile;
11
+import org.openzen.zencode.shared.logging.*;
11 12
 import org.openzen.zenscript.codemodel.FunctionParameter;
12 13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
13 14
 import org.openzen.zenscript.codemodel.Module;
@@ -31,8 +32,8 @@ public class JavaSourceCompiler {
31 32
 		settings = new JavaSourceFormattingSettings.Builder().build();
32 33
 	}
33 34
 	
34
-	public JavaSourceModule compile(SemanticModule module, JavaCompileSpace space, String basePackage) {
35
-		JavaSourceContext context = new JavaSourceContext(helpers, settings, space, module.modulePackage, basePackage);
35
+	public JavaSourceModule compile(IZSLogger logger, SemanticModule module, JavaCompileSpace space, String basePackage) {
36
+		JavaSourceContext context = new JavaSourceContext(logger, helpers, settings, space, module.modulePackage, basePackage);
36 37
 		
37 38
 		JavaSourceModule result = new JavaSourceModule(module.module, module.parameters);
38 39
 		context.addModule(module.module, result);

+ 3
- 2
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceContext.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.javasource;
7 7
 
8
+import org.openzen.zencode.shared.logging.*;
8 9
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
9 10
 import org.openzen.zenscript.codemodel.type.StoredType;
10 11
 import org.openzen.zenscript.codemodel.type.TypeID;
@@ -22,8 +23,8 @@ public class JavaSourceContext extends JavaContext {
22 23
 	private final JavaSyntheticClassGenerator generator;
23 24
 	public final JavaSourceSyntheticHelperGenerator helperGenerator;
24 25
 	
25
-	public JavaSourceContext(JavaSourceModule helpers, JavaSourceFormattingSettings settings, JavaCompileSpace space, ZSPackage modulePackage, String basePackage) {
26
-		super(space, modulePackage, basePackage);
26
+	public JavaSourceContext(IZSLogger logger, JavaSourceModule helpers, JavaSourceFormattingSettings settings, JavaCompileSpace space, ZSPackage modulePackage, String basePackage) {
27
+		super(space, modulePackage, basePackage, logger);
27 28
 		
28 29
 		typeDescriptorVisitor = new JavaTypeDescriptorVisitor(this);
29 30
 		this.generator = new JavaSourceSyntheticTypeGenerator(helpers, settings, this);

+ 6
- 6
Parser/src/main/java/org/openzen/zenscript/lexer/CompiledDFA.java View File

@@ -1,10 +1,10 @@
1 1
 /* Licensed under GPLv3 - https://opensource.org/licenses/GPL-3.0 */
2 2
 package org.openzen.zenscript.lexer;
3 3
 
4
-import gnu.trove.iterator.TIntIterator;
5
-import gnu.trove.map.hash.TIntIntHashMap;
6 4
 import java.util.ArrayList;
5
+import java.util.Iterator;
7 6
 import java.util.List;
7
+import java.util.Map;
8 8
 
9 9
 /**
10 10
  * Represents a compiled DFA. A compiled DFA has a compact representation and
@@ -32,7 +32,7 @@ public class CompiledDFA<T>
32 32
 		return new NFA<>(regexps, tokens, tokenClass).compile();
33 33
 	}
34 34
 	
35
-    public TIntIntHashMap[] transitions;
35
+    public Map<Integer, Integer>[] transitions;
36 36
     public T[] finals;
37 37
 
38 38
     /**
@@ -47,7 +47,7 @@ public class CompiledDFA<T>
47 47
      * @param transitions transitions graph
48 48
      * @param finals finals
49 49
      */
50
-    public CompiledDFA(TIntIntHashMap[] transitions, T[] finals)
50
+    public CompiledDFA(Map<Integer, Integer>[] transitions, T[] finals)
51 51
 	{
52 52
         this.transitions = transitions;
53 53
         this.finals = finals;
@@ -90,9 +90,9 @@ public class CompiledDFA<T>
90 90
 	{
91 91
         StringBuilder result = new StringBuilder();
92 92
         for (int i = 0; i < transitions.length; i++) {
93
-            TIntIntHashMap map = transitions[i];
93
+            Map<Integer, Integer> map = transitions[i];
94 94
 
95
-            TIntIterator it = map.keySet().iterator();
95
+            Iterator<Integer> it = map.keySet().iterator();
96 96
             while (it.hasNext()) {
97 97
                 int v = it.next();
98 98
                 result.append("edge(");

+ 23
- 21
Parser/src/main/java/org/openzen/zenscript/lexer/DFA.java View File

@@ -1,15 +1,16 @@
1 1
 /* Licensed under GPLv3 - https://opensource.org/licenses/GPL-3.0 */
2 2
 package org.openzen.zenscript.lexer;
3 3
 
4
-import gnu.trove.iterator.TIntIterator;
5
-import gnu.trove.map.hash.TIntIntHashMap;
6
-import gnu.trove.map.hash.TIntObjectHashMap;
7
-import gnu.trove.set.hash.TIntHashSet;
4
+
8 5
 import java.lang.reflect.Array;
9 6
 import java.util.ArrayList;
10 7
 import java.util.HashMap;
8
+import java.util.HashSet;
9
+import java.util.Iterator;
11 10
 import java.util.LinkedList;
11
+import java.util.Map;
12 12
 import java.util.Queue;
13
+import java.util.Set;
13 14
 
14 15
 /**
15 16
  * Implements a DFA. Used as intermediate form when compiling an NFA to a
@@ -56,8 +57,8 @@ public class DFA<T>
56 57
 
57 58
         while (!todo.isEmpty()) {
58 59
             DFAState<T> current = todo.poll();
59
-
60
-            TIntIterator it = current.transitions.keySet().iterator();
60
+    
61
+            Iterator<Integer> it = current.transitions.keySet().iterator();
61 62
             while (it.hasNext()) {
62 63
                 int k = it.next();
63 64
                 DFAState<T> next = current.transitions.get(k);
@@ -70,16 +71,16 @@ public class DFA<T>
70 71
         }
71 72
 
72 73
         /* Compile */
73
-        TIntIntHashMap[] transitions = new TIntIntHashMap[counter];
74
+        Map<Integer, Integer>[] transitions = new HashMap[counter];
74 75
 		@SuppressWarnings("unchecked")
75 76
         T[] finals2 = (T[]) Array.newInstance(tokenClass, counter);
76 77
 		
77 78
         for (DFAState<T> node : nodeList) {
78 79
             int index = nodes.get(node);
79 80
             finals2[index] = node.finalCode;
80
-
81
-            transitions[index] = new TIntIntHashMap();
82
-            TIntIterator it = node.transitions.keySet().iterator();
81
+    
82
+            transitions[index] = new HashMap<>();
83
+            Iterator<Integer> it = node.transitions.keySet().iterator();
83 84
             while (it.hasNext()) {
84 85
                 int k = it.next();
85 86
                 DFAState<T> next = node.transitions.get(k);
@@ -98,13 +99,13 @@ public class DFA<T>
98 99
     public DFA<T> optimize()
99 100
 	{
100 101
         CompiledDFA<T> compiled = compile();
101
-        TIntIntHashMap[] transitions = compiled.transitions;
102
+        Map<Integer, Integer>[] transitions = compiled.transitions;
102 103
         int size = transitions.length;
103 104
 
104 105
         /* Collect all edges and determine alphabet */
105
-        TIntHashSet alphabet = new TIntHashSet();
106
+        Set<Integer> alphabet = new HashSet<>();
106 107
         for (int i = 0; i < size; i++) {
107
-            TIntIterator it = transitions[i].keySet().iterator();
108
+            Iterator<Integer> it = transitions[i].keySet().iterator();
108 109
             while (it.hasNext()) {
109 110
                 int k = it.next();
110 111
                 alphabet.add(k);
@@ -127,7 +128,7 @@ public class DFA<T>
127 128
         boolean changed;
128 129
         do {
129 130
             changed = false;
130
-            TIntIterator ita = alphabet.iterator();
131
+            Iterator<Integer> ita = alphabet.iterator();
131 132
             while (ita.hasNext()) {
132 133
                 int x = ita.next();
133 134
                 for (int i = 0; i < size; i++) {
@@ -146,7 +147,7 @@ public class DFA<T>
146 147
         } while (changed);
147 148
 
148 149
         /* Group nodes */
149
-        TIntObjectHashMap<DFAState<T>> nodeMap = new TIntObjectHashMap<>();
150
+        Map<Integer, DFAState<T>> nodeMap = new HashMap<>();
150 151
         outer: for (int i = 0; i < size; i++) {
151 152
             for (int j = 0; j < size; j++) {
152 153
                 if (!distinguishable[i][j] && nodeMap.containsKey(j)) {
@@ -165,7 +166,7 @@ public class DFA<T>
165 166
         }
166 167
 
167 168
         for (int i = 0; i < compiled.transitions.length; i++) {
168
-            TIntIterator iter = transitions[i].keySet().iterator();
169
+            Iterator<Integer> iter = transitions[i].keySet().iterator();
169 170
             while (iter.hasNext()) {
170 171
                 int k = iter.next();
171 172
 
@@ -182,9 +183,9 @@ public class DFA<T>
182 183
         StringBuilder result = new StringBuilder();
183 184
         CompiledDFA<T> dfs = compile();
184 185
         for (int i = 0; i < dfs.transitions.length; i++) {
185
-            TIntIntHashMap map = dfs.transitions[i];
186
-            
187
-            TIntIterator it = map.keySet().iterator();
186
+            Map<Integer, Integer> map = dfs.transitions[i];
187
+    
188
+            Iterator<Integer> it = map.keySet().iterator();
188 189
             while (it.hasNext()) {
189 190
                 int v = it.next();
190 191
                 result.append("edge(");
@@ -217,14 +218,15 @@ public class DFA<T>
217 218
      */
218 219
     public static class DFAState<T>
219 220
 	{
220
-        private TIntObjectHashMap<DFAState<T>> transitions;
221
+        
222
+        private Map<Integer, DFAState<T>> transitions;
221 223
         private T finalCode = null;
222 224
 
223 225
         /**
224 226
          * Creates a new DFA state.
225 227
          */
226 228
         public DFAState() {
227
-            transitions = new TIntObjectHashMap<>();
229
+            transitions = new HashMap<>();
228 230
         }
229 231
 
230 232
         /**

+ 7
- 7
Parser/src/main/java/org/openzen/zenscript/lexer/NFA.java View File

@@ -1,15 +1,15 @@
1 1
 /* Licensed under GPLv3 - https://opensource.org/licenses/GPL-3.0 */
2 2
 package org.openzen.zenscript.lexer;
3 3
 
4
-import gnu.trove.iterator.TIntIterator;
5
-import gnu.trove.set.hash.TIntHashSet;
6 4
 import java.util.ArrayList;
7 5
 import java.util.Arrays;
8 6
 import java.util.HashMap;
9 7
 import java.util.HashSet;
8
+import java.util.Iterator;
10 9
 import java.util.LinkedList;
11 10
 import java.util.List;
12 11
 import java.util.Queue;
12
+import java.util.Set;
13 13
 
14 14
 /**
15 15
  * Represents an NFA. NFAs can be compiled from a list of regular expressions.
@@ -304,7 +304,7 @@ public class NFA<T extends Comparable<T>>
304 304
             NFAState<T> head = new NFAState<>();
305 305
             NFAState<T> tail = new NFAState<>();
306 306
 
307
-            TIntIterator iter = processCharList(stream).iterator();
307
+            Iterator<Integer> iter = processCharList(stream).iterator();
308 308
             while (iter.hasNext()) {
309 309
                 tail.addTransition(iter.next(), head);
310 310
             }
@@ -325,15 +325,15 @@ public class NFA<T extends Comparable<T>>
325 325
     }
326 326
 
327 327
     /* Processes a character list */
328
-    private TIntHashSet processCharList(CharStream stream)
328
+    private Set<Integer> processCharList(CharStream stream)
329 329
 	{
330 330
         boolean invert = stream.optional('^');
331
-        TIntHashSet base = new TIntHashSet();
331
+        Set<Integer>base = new HashSet();
332 332
         do {
333 333
             processCharPartial(base, stream);
334 334
         } while (!stream.peek(']'));
335 335
         if (invert) {
336
-            TIntHashSet result = new TIntHashSet();
336
+            Set<Integer>result = new HashSet();
337 337
             for (int i = 0; i <= 256; i++) {
338 338
                 if (!base.contains(i)) result.add(i);
339 339
             }
@@ -345,7 +345,7 @@ public class NFA<T extends Comparable<T>>
345 345
 
346 346
     /* Processes a character partial, which can be a single character or a range
347 347
      * of characters. */
348
-    private void processCharPartial(TIntHashSet out, CharStream stream)
348
+    private void processCharPartial(Set<Integer>out, CharStream stream)
349 349
 	{
350 350
         if (stream.optional('.')) {
351 351
             for (int i = 0; i <= 256; i++) {

+ 3
- 2
Parser/src/main/java/org/openzen/zenscript/lexer/TokenParser.java View File

@@ -1,10 +1,11 @@
1 1
 /* Licensed under GPLv3 - https://opensource.org/licenses/GPL-3.0 */
2 2
 package org.openzen.zenscript.lexer;
3 3
 
4
-import java.io.IOException;
5 4
 import org.openzen.zencode.shared.CodePosition;
6 5
 import org.openzen.zencode.shared.SourceFile;
7 6
 
7
+import java.io.IOException;
8
+
8 9
 /**
9 10
  * Represents a token stream. A token stream reads characters from a reader and
10 11
  * presents it as a series of tokens. Can be used to implement LL(*) parsers.
@@ -93,7 +94,7 @@ public class TokenParser<T extends Token<TT>, TT extends TokenType> implements T
93 94
             while (dfa.transitions[state].containsKey(reader.peek())) {
94 95
 				char c = (char) reader.next();
95 96
                 value.append(c);
96
-                state = dfa.transitions[state].get(c);
97
+                state = dfa.transitions[state].get((int)c);
97 98
             }
98 99
 			
99 100
             if (dfa.finals[state] != null) {

+ 124
- 0
Parser/src/main/java/org/openzen/zenscript/parser/EscapableBracketParser.java View File

@@ -0,0 +1,124 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.parser;
7
+
8
+import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zencode.shared.CompileException;
10
+import org.openzen.zenscript.codemodel.OperatorType;
11
+import org.openzen.zenscript.codemodel.expression.CallArguments;
12
+import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
13
+import org.openzen.zenscript.codemodel.expression.Expression;
14
+import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
15
+import org.openzen.zenscript.codemodel.partial.IPartialExpression;
16
+import org.openzen.zenscript.codemodel.scope.ExpressionScope;
17
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
18
+import org.openzen.zenscript.codemodel.type.StringTypeID;
19
+import org.openzen.zenscript.codemodel.type.TypeID;
20
+import org.openzen.zenscript.lexer.ParseException;
21
+import org.openzen.zenscript.lexer.ZSToken;
22
+import org.openzen.zenscript.lexer.ZSTokenParser;
23
+import org.openzen.zenscript.lexer.ZSTokenType;
24
+import org.openzen.zenscript.parser.expression.ParsedExpression;
25
+import org.openzen.zenscript.parser.expression.ParsedExpressionBinary;
26
+import org.openzen.zenscript.parser.expression.ParsedExpressionString;
27
+
28
+import java.util.ArrayList;
29
+import java.util.List;
30
+
31
+/**
32
+ * @author Hoofdgebruiker and kindlich
33
+ */
34
+public class EscapableBracketParser implements BracketExpressionParser {
35
+    private final FunctionalMemberRef method;
36
+    private final TypeID targetType;
37
+
38
+    public EscapableBracketParser(GlobalTypeRegistry registry, FunctionalMemberRef method) {
39
+        if (!method.isStatic())
40
+            throw new IllegalArgumentException("Method must be static");
41
+        if (method.getHeader().getNumberOfTypeParameters() > 0)
42
+            throw new IllegalArgumentException("Method cannot have type parameters");
43
+
44
+        this.method = method;
45
+        this.targetType = registry.getForDefinition(method.getTarget().definition);
46
+    }
47
+
48
+    @Override
49
+    public ParsedExpression parse(CodePosition position, ZSTokenParser tokens) throws ParseException {
50
+        StringBuilder string = new StringBuilder();
51
+
52
+        //This list will contain the BEP calls
53
+        //If this is only a normal BEP, then it will contain exactly one String ParsedExpression.
54
+        final List<ParsedExpression> expressionList = new ArrayList<>();
55
+
56
+        while (tokens.optional(ZSTokenType.T_GREATER) == null) {
57
+            ZSToken next = tokens.next();
58
+
59
+            if (next.type != ZSTokenType.T_DOLLAR) {
60
+                string.append(next.content);
61
+                string.append(tokens.getLastWhitespace());
62
+                continue;
63
+            }
64
+
65
+            //We found a $, now check that it has a { directly after it.
66
+            final String ws = tokens.getLastWhitespace();
67
+            if (!ws.isEmpty()) {
68
+                //$  {..} is not ${..} so we print it as literal
69
+                string.append(next.content).append(ws);
70
+                continue;
71
+            }
72
+
73
+            next = tokens.next();
74
+            //Now we check if it is a {
75
+            if (next.type == ZSTokenType.T_AOPEN) {
76
+                if (string.length() != 0) {
77
+                    expressionList.add(new ParsedExpressionString(position, string.toString(), false));
78
+                    string = new StringBuilder();
79
+                }
80
+                expressionList.add(ParsedExpression.parse(tokens));
81
+                tokens.required(ZSTokenType.T_ACLOSE, "} expected.");
82
+                string.append(tokens.getLastWhitespace());
83
+            } else {
84
+                //No { after the $, so we treat them both as literal
85
+                string.append("$").append(ws); //Technically, the whitespace here is empty, but let's be sure
86
+                string.append(next.content).append(tokens.getLastWhitespace());
87
+            }
88
+
89
+        }
90
+
91
+        if (string.length() != 0) {
92
+            expressionList.add(new ParsedExpressionString(position, string.toString(), false));
93
+        }
94
+
95
+        return new StaticMethodCallExpression(position, expressionList);
96
+    }
97
+
98
+    private class StaticMethodCallExpression extends ParsedExpression {
99
+
100
+        private final ParsedExpression call;
101
+
102
+        public StaticMethodCallExpression(CodePosition position, List<ParsedExpression> expressions) {
103
+            super(position);
104
+            ParsedExpression p = null;
105
+            for (ParsedExpression expression : expressions) {
106
+                p = p == null ? expression : new ParsedExpressionBinary(expression.position, p, expression, OperatorType.ADD);
107
+            }
108
+
109
+            this.call = p;
110
+        }
111
+
112
+        @Override
113
+        public IPartialExpression compile(ExpressionScope scope) throws CompileException {
114
+            final Expression methodCall = call.compile(scope.withHint(StringTypeID.AUTO)).eval();
115
+            final CallArguments arguments = new CallArguments(methodCall);
116
+            return new CallStaticExpression(position, targetType, method, method.getHeader(), arguments);
117
+        }
118
+
119
+        @Override
120
+        public boolean hasStrongType() {
121
+            return true;
122
+        }
123
+    }
124
+}

+ 88
- 0
Parser/src/main/java/org/openzen/zenscript/parser/FolderPackage.java View File

@@ -0,0 +1,88 @@
1
+package org.openzen.zenscript.parser;
2
+
3
+import org.openzen.zencode.shared.LiteralSourceFile;
4
+import org.openzen.zencode.shared.SourceFile;
5
+import org.openzen.zenscript.codemodel.FunctionParameter;
6
+import org.openzen.zenscript.codemodel.Module;
7
+import org.openzen.zenscript.codemodel.ModuleSpace;
8
+import org.openzen.zenscript.codemodel.SemanticModule;
9
+import org.openzen.zenscript.codemodel.context.CompilingPackage;
10
+import org.openzen.zenscript.codemodel.definition.ZSPackage;
11
+import org.openzen.zenscript.lexer.ParseException;
12
+import org.openzen.zenscript.parser.logger.*;
13
+
14
+import java.io.BufferedReader;
15
+import java.io.File;
16
+import java.io.FileNotFoundException;
17
+import java.io.FileReader;
18
+import java.util.ArrayList;
19
+import java.util.HashMap;
20
+import java.util.List;
21
+import java.util.Map;
22
+import java.util.stream.Collectors;
23
+
24
+public class FolderPackage {
25
+    
26
+    private Map<String, List<SourceFile>> files = new HashMap<>();
27
+    
28
+    public FolderPackage(File file) {
29
+        ArrayList<File> foundFiles = new ArrayList<>();
30
+        getFiles(file, foundFiles);
31
+    
32
+        String srcString = File.separator + "src" + File.separator;
33
+        foundFiles.stream().filter(fil -> (fil.getPath()+File.separator).substring(file.getPath().length()+ File.separator.length()).indexOf(srcString) > 0).forEach(fil -> {
34
+            String name = (fil.getPath() + File.separator).substring(file.getPath().length() + File.separator.length());
35
+            int slash = name.indexOf(srcString);
36
+            String moduleName = name.substring(0, slash);
37
+            String filename = name.substring(slash + srcString.length());
38
+            if(!files.containsKey(moduleName))
39
+                files.put(moduleName, new ArrayList<>());
40
+            
41
+            try {
42
+                if(!fil.isDirectory())
43
+                    files.get(moduleName).add(new LiteralSourceFile(filename, new BufferedReader(new FileReader(fil)).lines().collect(Collectors.joining("\n"))));
44
+                else
45
+                    files.get(moduleName).add(new LiteralSourceFile(filename, ""));
46
+            } catch(FileNotFoundException e) {
47
+                e.printStackTrace();
48
+            }
49
+            
50
+        });
51
+    }
52
+    
53
+    public void getFiles(File parent, List<File> files) {
54
+        if(parent.isDirectory()) {
55
+            for(File file : parent.listFiles()) {
56
+                if(file.isDirectory()) {
57
+                    getFiles(file, files);
58
+                }
59
+            }
60
+        }
61
+        files.add(parent);
62
+    }
63
+	
64
+	public SemanticModule loadModule(ModuleSpace space, String name, BracketExpressionParser bracketParser, SemanticModule[] dependencies, FunctionParameter[] scriptParameters, ParserLogger logger) throws ParseException {
65
+		return loadModule(space, name, bracketParser, dependencies, scriptParameters, new ZSPackage(space.rootPackage, name), logger);
66
+	}
67
+	
68
+	public SemanticModule loadModule(ModuleSpace space, String name, BracketExpressionParser bracketParser, SemanticModule[] dependencies, FunctionParameter[] scriptParameters, ZSPackage pkg, ParserLogger logger) throws ParseException {
69
+		List<SourceFile> sourceFiles = files.get(name);
70
+		if (sourceFiles == null)
71
+			return null; // no such module
72
+		
73
+		Module scriptModule = new Module(name);
74
+		CompilingPackage scriptPackage = new CompilingPackage(pkg, scriptModule);
75
+		ParsedFile[] files = new ParsedFile[sourceFiles.size()];
76
+		for (int i = 0; i < files.length; i++)
77
+			files[i] = ParsedFile.parse(scriptPackage, bracketParser, sourceFiles.get(i));
78
+		
79
+		SemanticModule scripts = ParsedFile.compileSyntaxToSemantic(
80
+				dependencies,
81
+				scriptPackage,
82
+				files,
83
+				space,
84
+				scriptParameters,
85
+                logger);
86
+		return scripts.normalize();
87
+	}
88
+}

+ 0
- 0
Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save