Browse Source

- Added correct type variable resolution

- Fixed a number of bugs
- Upgrading build system to a more uniform system
- Improving error output (for IDE)
- Changed parser to generate line offsets differently (easier for IDE to process)
Stan Hebben 5 years ago
parent
commit
9c650d0f5b
69 changed files with 967 additions and 976 deletions
  1. 42
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  2. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java
  3. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/context/CompilingPackage.java
  4. 2
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java
  5. 4
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ExpressionVisitor.java
  6. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ExpressionVisitorWithContext.java
  7. 48
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/InvalidAssignExpression.java
  8. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/InvalidExpression.java
  9. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  10. 3
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberGroup.java
  11. 3
    2
      Constructor/src/main/java/org/openzen/zenscript/constructor/Library.java
  12. 3
    2
      Constructor/src/main/java/org/openzen/zenscript/constructor/Main.java
  13. 1
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/ParsedModule.java
  14. 4
    3
      Constructor/src/main/java/org/openzen/zenscript/constructor/Project.java
  15. 5
    4
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java
  16. 28
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceModule.java
  17. 99
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceModuleReference.java
  18. 8
    19
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourcePackage.java
  19. 129
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/directory/DirectorySourceModule.java
  20. 85
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/directory/SourceDirectoryPackage.java
  21. 0
    28
      DrawableGui/src/main/java/org/openzen/drawablegui/listeners/DummyListenerHandle.java
  22. 0
    27
      DrawableGui/src/main/java/org/openzen/drawablegui/listeners/ListenerHandle.java
  23. 0
    165
      DrawableGui/src/main/java/org/openzen/drawablegui/listeners/ListenerList.java
  24. 0
    34
      DrawableGui/src/main/java/org/openzen/drawablegui/live/ImmutableLiveBool.java
  25. 0
    31
      DrawableGui/src/main/java/org/openzen/drawablegui/live/ImmutableLiveObject.java
  26. 0
    31
      DrawableGui/src/main/java/org/openzen/drawablegui/live/ImmutableLiveString.java
  27. 0
    30
      DrawableGui/src/main/java/org/openzen/drawablegui/live/InverseLiveBool.java
  28. 0
    91
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveArrayList.java
  29. 0
    22
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveBool.java
  30. 0
    24
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveInt.java
  31. 0
    36
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveList.java
  32. 0
    22
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveObject.java
  33. 0
    22
      DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveString.java
  34. 0
    24
      DrawableGui/src/main/java/org/openzen/drawablegui/live/MutableLiveList.java
  35. 0
    46
      DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveBool.java
  36. 0
    42
      DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveInt.java
  37. 0
    43
      DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveString.java
  38. 27
    12
      DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java
  39. 38
    8
      IDE/src/main/java/org/openzen/zenscript/ide/Main.java
  40. 0
    57
      IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeSpace.java
  41. 1
    2
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDECodeError.java
  42. 16
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDECompileState.java
  43. 0
    1
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDEModule.java
  44. 3
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDETarget.java
  45. 34
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalCompileState.java
  46. 1
    1
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalModule.java
  47. 11
    30
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalPackage.java
  48. 23
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalSourceFile.java
  49. 55
    23
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java
  50. 8
    2
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java
  51. 71
    10
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java
  52. 4
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditorStyle.java
  53. 76
    41
      JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java
  54. 10
    6
      ModuleSerializer/src/main/java/org/openzen/zenscript/moduleserializer/Main.java
  55. 3
    7
      Parser/src/main/java/org/openzen/zenscript/lexer/CountingCharReader.java
  56. 14
    3
      Parser/src/main/java/org/openzen/zenscript/lexer/LLParserTokenStream.java
  57. 1
    1
      Parser/src/main/java/org/openzen/zenscript/lexer/TokenParser.java
  58. 6
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/WhitespaceFilteringParser.java
  59. 7
    6
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java
  60. 18
    5
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionAssign.java
  61. 3
    0
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedFunctionalMember.java
  62. 6
    3
      ScriptingExample/scripts/integration.zs
  63. 2
    0
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java
  64. 17
    0
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestBaseInterface.java
  65. 5
    0
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestClass.java
  66. 14
    0
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestGenericInterface.java
  67. 4
    0
      Shared/src/main/java/org/openzen/zencode/shared/CodePosition.java
  68. 3
    1
      Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java
  69. 9
    1
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java

+ 42
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

@@ -6,8 +6,6 @@
6 6
 package org.openzen.zenscript.codemodel;
7 7
 
8 8
 import java.util.Arrays;
9
-import java.util.HashMap;
10
-import java.util.List;
11 9
 import java.util.Map;
12 10
 import org.openzen.zencode.shared.CodePosition;
13 11
 import org.openzen.zenscript.codemodel.expression.CallArguments;
@@ -17,7 +15,6 @@ import org.openzen.zenscript.codemodel.type.BasicTypeID;
17 15
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
18 16
 import org.openzen.zenscript.codemodel.scope.TypeScope;
19 17
 import org.openzen.zenscript.codemodel.type.StoredType;
20
-import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
21 18
 import org.openzen.zenscript.codemodel.type.storage.AutoStorageTag;
22 19
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
23 20
 
@@ -113,6 +110,36 @@ public class FunctionHeader {
113 110
 		hasUnknowns = hasUnknowns(parameters, returnType);
114 111
 	}
115 112
 	
113
+	public boolean isVariadic() {
114
+		return parameters.length > 0 && parameters[parameters.length - 1].variadic;
115
+	}
116
+	
117
+	public boolean isVariadicCall(CallArguments arguments, TypeScope scope) {
118
+		if (!isVariadic())
119
+			return false;
120
+		if (arguments.arguments.length < parameters.length - 1)
121
+			return false;
122
+		if (arguments.arguments.length != parameters.length)
123
+			return true;
124
+		if (scope.getTypeMembers(arguments.arguments[arguments.arguments.length - 1].type).canCastImplicit(parameters[parameters.length - 1].type))
125
+			return false;
126
+		
127
+		return true;
128
+	}
129
+	
130
+	public boolean isVariadicCall(CallArguments arguments) {
131
+		if (!isVariadic())
132
+			return false;
133
+		if (arguments.arguments.length < parameters.length - 1)
134
+			return false;
135
+		if (arguments.arguments.length != parameters.length)
136
+			return true;
137
+		if (arguments.arguments[arguments.arguments.length - 1].type.equals(parameters[parameters.length - 1].type))
138
+			return false;
139
+		
140
+		return true;
141
+	}
142
+	
116 143
 	public boolean[] useTypeParameters() {
117 144
 		boolean[] useTypeParameters = new boolean[typeParameters.length];
118 145
 		for (int i = 0; i < useTypeParameters.length; i++)
@@ -132,6 +159,18 @@ public class FunctionHeader {
132 159
 		this.returnType = returnType;
133 160
 	}
134 161
 	
162
+	public StoredType getParameterType(boolean isVariadic, int index) {
163
+		return getParameter(isVariadic, index).type;
164
+	}
165
+	
166
+	public FunctionParameter getParameter(boolean isVariadic, int index) {
167
+		if (isVariadic && index >= parameters.length - 1) {
168
+			return parameters[parameters.length - 1];
169
+		} else {
170
+			return parameters[index];
171
+		}
172
+	}
173
+	
135 174
 	public boolean isDenormalized() {
136 175
 		if (!returnType.getNormalized().equals(returnType))
137 176
 			return true;

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

@@ -26,6 +26,9 @@ public class GenericMapper {
26 26
 	private final Map<TypeParameter, StoredType> mapping;
27 27
 	
28 28
 	public GenericMapper(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
29
+		if (mapping == null)
30
+			throw new IllegalArgumentException();
31
+		
29 32
 		this.position = position;
30 33
 		this.registry = registry;
31 34
 		this.mapping = mapping;

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

@@ -80,7 +80,7 @@ public class CompilingPackage {
80 80
 			return null;
81 81
 		
82 82
 		if (packages.containsKey(name.get(index).name))
83
-			return packages.get(name.get(index)).getType(context, name, index + 1);
83
+			return packages.get(name.get(index).name).getType(context, name, index + 1);
84 84
 		
85 85
 		if (types.containsKey(name.get(index).name)) {
86 86
 			CompilingType type = types.get(name.get(index).name);

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

@@ -56,8 +56,9 @@ public class CallArguments {
56 56
 	public CallArguments normalize(CodePosition position, TypeScope scope, FunctionHeader header) {
57 57
 		CallArguments result = this;
58 58
 		
59
+		boolean isVariadic = header.isVariadicCall(this, scope);
59 60
 		for (int i = 0; i < arguments.length; i++) {
60
-			arguments[i] = arguments[i].normalize(scope).castImplicit(position, scope, header.parameters[i].type);
61
+			arguments[i] = arguments[i].normalize(scope).castImplicit(position, scope, header.getParameterType(isVariadic, i));
61 62
 		}
62 63
 		
63 64
 		if (arguments.length < header.parameters.length) {

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

@@ -98,6 +98,10 @@ public interface ExpressionVisitor<T> {
98 98
 		throw new RuntimeException("Invalid expression");
99 99
 	}
100 100
 	
101
+	default T visitInvalidAssign(InvalidAssignExpression expression) {
102
+		throw new RuntimeException("Invalid expression");
103
+	}
104
+	
101 105
 	T visitIs(IsExpression expression);
102 106
 	
103 107
 	T visitMakeConst(MakeConstExpression expression);

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

@@ -96,6 +96,8 @@ public interface ExpressionVisitorWithContext<C, R> {
96 96
 	
97 97
 	R visitInvalid(C context, InvalidExpression expression);
98 98
 	
99
+	R visitInvalidAssign(C context, InvalidAssignExpression expression);
100
+	
99 101
 	R visitIs(C context, IsExpression expression);
100 102
 	
101 103
 	R visitMakeConst(C context, MakeConstExpression expression);

+ 48
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/InvalidAssignExpression.java View File

@@ -0,0 +1,48 @@
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.codemodel.expression;
7
+
8
+import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zenscript.codemodel.scope.TypeScope;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class InvalidAssignExpression extends Expression {
16
+	public final InvalidExpression target;
17
+	public final Expression source;
18
+	
19
+	public InvalidAssignExpression(CodePosition position, InvalidExpression target, Expression source) {
20
+		super(position, source.type, source.thrownType);
21
+		
22
+		this.target = target;
23
+		this.source = source;
24
+	}
25
+
26
+	@Override
27
+	public <T> T accept(ExpressionVisitor<T> visitor) {
28
+		return visitor.visitInvalidAssign(this);
29
+	}
30
+
31
+	@Override
32
+	public <C, R> R accept(C context, ExpressionVisitorWithContext<C, R> visitor) {
33
+		return visitor.visitInvalidAssign(context, this);
34
+	}
35
+
36
+	@Override
37
+	public Expression transform(ExpressionTransformer transformer) {
38
+		return new InvalidAssignExpression(
39
+				position,
40
+				target,
41
+				transformer.transform(source));
42
+	}
43
+
44
+	@Override
45
+	public Expression normalize(TypeScope scope) {
46
+		return new InvalidAssignExpression(position, target, source.normalize(scope));
47
+	}
48
+}

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.expression;
7 7
 
8
+import jdk.nashorn.internal.ir.Assignment;
8 9
 import org.openzen.zencode.shared.CodePosition;
9 10
 import org.openzen.zencode.shared.CompileException;
10 11
 import org.openzen.zencode.shared.CompileExceptionCode;
@@ -29,6 +30,11 @@ public class InvalidExpression extends Expression {
29 30
 	public InvalidExpression(StoredType type, CompileException cause) {
30 31
 		this(cause.position, type, cause.code, cause.message);
31 32
 	}
33
+	
34
+	@Override
35
+	public Expression assign(CodePosition position, TypeScope scope, Expression value) {
36
+		return new InvalidAssignExpression(position, this, value);
37
+	}
32 38
 
33 39
 	@Override
34 40
 	public <T> T accept(ExpressionVisitor<T> visitor) {

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

@@ -128,7 +128,7 @@ public class DefinitionTypeID implements TypeID {
128 128
 	public StoredType instance(GenericMapper mapper, StorageTag storage) {
129 129
 		if (!hasTypeParameters() && outer == null)
130 130
 			return stored(storage);
131
-		if (mapper.getMapping().isEmpty())
131
+		if (mapper == null || mapper.getMapping().isEmpty())
132 132
 			return stored(storage);
133 133
 		if (mapper.registry == null)
134 134
 			throw new NullPointerException();

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

@@ -293,8 +293,10 @@ public class TypeMemberGroup {
293 293
 	public Expression call(CodePosition position, TypeScope scope, Expression target, CallArguments arguments, boolean allowStaticUsage) throws CompileException {
294 294
 		FunctionalMemberRef method = selectMethod(position, scope, arguments, true, allowStaticUsage);
295 295
 		FunctionHeader instancedHeader = method.getHeader().fillGenericArguments(position, scope, arguments.typeArguments);
296
+		
297
+		boolean isVariadicCall = instancedHeader.isVariadicCall(arguments, scope);
296 298
 		for (int i = 0; i < arguments.arguments.length; i++) {
297
-			arguments.arguments[i] = arguments.arguments[i].castImplicit(position, scope, instancedHeader.parameters[i].type);
299
+			arguments.arguments[i] = arguments.arguments[i].castImplicit(position, scope, instancedHeader.getParameterType(isVariadicCall, i));
298 300
 		}
299 301
 
300 302
 		scope.getPreparer().prepare(method.getTarget());

+ 3
- 2
Constructor/src/main/java/org/openzen/zenscript/constructor/Library.java View File

@@ -8,8 +8,9 @@ package org.openzen.zenscript.constructor;
8 8
 import java.io.File;
9 9
 import org.json.JSONArray;
10 10
 import org.json.JSONObject;
11
-import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
12 11
 import org.openzen.zenscript.constructor.module.ModuleReference;
12
+import org.openzen.zenscript.constructor.module.SourceModuleReference;
13
+import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
13 14
 
14 15
 /**
15 16
  *
@@ -28,7 +29,7 @@ public class Library {
28 29
 		modules = new ModuleReference[modulesJson.length()];
29 30
 		for (int i = 0; i < modulesJson.length(); i++) {
30 31
 			String moduleName = modulesJson.getString(i);
31
-			modules[i] = new DirectoryModuleReference(moduleName, new File(this.directory, moduleName), false);
32
+			modules[i] = new SourceModuleReference(new DirectorySourceModule(moduleName, new File(this.directory, moduleName), false), false);
32 33
 		}
33 34
 	}
34 35
 }

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

@@ -6,8 +6,9 @@ import java.util.function.Consumer;
6 6
 import org.openzen.zencode.shared.CompileException;
7 7
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
8 8
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
9
-import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
10 9
 import org.openzen.zenscript.constructor.module.ModuleReference;
10
+import org.openzen.zenscript.constructor.module.SourceModuleReference;
11
+import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
11 12
 
12 13
 public class Main {
13 14
     /**
@@ -29,7 +30,7 @@ public class Main {
29 30
 		GlobalTypeRegistry registry = new GlobalTypeRegistry(stdlib);
30 31
 		
31 32
 		ModuleLoader moduleLoader = new ModuleLoader(registry, exceptionLogger);
32
-		moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
33
+		moduleLoader.register("stdlib", new SourceModuleReference(new DirectorySourceModule("stdlib", new File("../../StdLibs/stdlib"), true), true));
33 34
 		
34 35
 		Project project = new Project(currentDirectory);
35 36
 		for (Library library : project.libraries) {

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

@@ -61,7 +61,7 @@ public class ParsedModule {
61 61
 		return files.toArray(new ParsedFile[files.size()]);
62 62
 	}
63 63
 	
64
-	private void parse(List<ParsedFile> files, CompilingPackage pkg, BracketExpressionParser bracketParser, File directory) throws ParseException {
64
+	public static void parse(List<ParsedFile> files, CompilingPackage pkg, BracketExpressionParser bracketParser, File directory) throws ParseException {
65 65
 		for (File file : directory.listFiles()) {
66 66
 			if (file.getName().endsWith(".zs")) {
67 67
 				files.add(ParsedFile.parse(pkg, bracketParser, file));

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

@@ -11,10 +11,11 @@ import java.util.ArrayList;
11 11
 import java.util.List;
12 12
 import org.json.JSONArray;
13 13
 import org.json.JSONObject;
14
-import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
15 14
 import org.openzen.zenscript.constructor.module.ModuleReference;
16 15
 import org.openzen.zenscript.compiler.Target;
17 16
 import org.openzen.zenscript.compiler.TargetType;
17
+import org.openzen.zenscript.constructor.module.SourceModuleReference;
18
+import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
18 19
 
19 20
 /**
20 21
  *
@@ -55,13 +56,13 @@ public class Project {
55 56
 		for (int i = 0; i < jsonModules.length(); i++) {
56 57
 			Object module = jsonModules.get(i);
57 58
 			if (module instanceof String) {
58
-				modules[i] = new DirectoryModuleReference(module.toString(), new File(directory, module.toString()), false);
59
+				modules[i] = new SourceModuleReference(new DirectorySourceModule(module.toString(), new File(directory, module.toString())));
59 60
 			} else if (module instanceof JSONObject) {
60 61
 				JSONObject jsonModule = (JSONObject) module;
61 62
 				String name = jsonModule.getString("name");
62 63
 				switch (jsonModule.getString("type")) {
63 64
 					case "directory":
64
-						modules[i] = new DirectoryModuleReference(name, new File(directory, jsonModule.getString("directory")), false);
65
+						modules[i] = new SourceModuleReference(new DirectorySourceModule(name, new File(directory, jsonModule.getString("directory"))));
65 66
 						break;
66 67
 					default:
67 68
 						throw new ConstructorException("Invalid module type: " + jsonModule.getString("type"));

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.constructor.module;
7 7
 
8
+import org.openzen.zenscript.constructor.module.directory.SourceDirectoryPackage;
8 9
 import java.io.File;
9 10
 import java.io.IOException;
10 11
 import java.util.ArrayList;
@@ -38,7 +39,7 @@ public class DirectoryModuleReference implements ModuleReference {
38 39
 	private final String moduleName;
39 40
 	private final File directory;
40 41
 	private final boolean isStdlib;
41
-	private SourcePackage rootPackage = null;
42
+	private SourceDirectoryPackage rootPackage = null;
42 43
 	
43 44
 	public DirectoryModuleReference(String moduleName, File directory, boolean isStdlib) {
44 45
 		this.moduleName = moduleName;
@@ -120,18 +121,18 @@ public class DirectoryModuleReference implements ModuleReference {
120 121
 	}
121 122
 	
122 123
 	@Override
123
-	public SourcePackage getRootPackage() {
124
+	public SourceDirectoryPackage getRootPackage() {
124 125
 		if (rootPackage == null)
125 126
 			rootPackage = loadPackage("", new File(directory, "src"));
126 127
 		
127 128
 		return rootPackage;
128 129
 	}
129 130
 	
130
-	private SourcePackage loadPackage(String name, File directory) {
131
+	private SourceDirectoryPackage loadPackage(String name, File directory) {
131 132
 		if (!directory.exists())
132 133
 			throw new IllegalArgumentException("Directory does not exist: " + directory.getAbsolutePath());
133 134
 		
134
-		SourcePackage pkg = new SourcePackage(directory, name);
135
+		SourceDirectoryPackage pkg = new SourceDirectoryPackage(directory, name);
135 136
 		
136 137
 		for (File file : directory.listFiles()) {
137 138
 			if (file.isDirectory()) {

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

@@ -0,0 +1,28 @@
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.constructor.module;
7
+
8
+import java.util.Map;
9
+import java.util.function.Consumer;
10
+import org.openzen.zencode.shared.CompileException;
11
+import org.openzen.zenscript.codemodel.SemanticModule;
12
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
13
+import org.openzen.zenscript.codemodel.type.ISymbol;
14
+import org.openzen.zenscript.constructor.ModuleLoader;
15
+
16
+/**
17
+ *
18
+ * @author Hoofdgebruiker
19
+ */
20
+public interface SourceModule {
21
+	public String getName();
22
+	
23
+	public SourcePackage getRootPackage();
24
+	
25
+	public SemanticModule[] loadDependencies(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger);
26
+	
27
+	public Map<String, ISymbol> getGlobals(SemanticModule module);
28
+}

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

@@ -0,0 +1,99 @@
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.constructor.module;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import java.util.function.Consumer;
11
+import org.openzen.zencode.shared.CompileException;
12
+import org.openzen.zencode.shared.CompileExceptionCode;
13
+import org.openzen.zencode.shared.SourceFile;
14
+import org.openzen.zenscript.codemodel.FunctionParameter;
15
+import org.openzen.zenscript.codemodel.Module;
16
+import org.openzen.zenscript.codemodel.ModuleSpace;
17
+import org.openzen.zenscript.codemodel.SemanticModule;
18
+import org.openzen.zenscript.codemodel.context.CompilingPackage;
19
+import org.openzen.zenscript.codemodel.definition.ZSPackage;
20
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
21
+import org.openzen.zenscript.constructor.ConstructorException;
22
+import org.openzen.zenscript.constructor.ModuleLoader;
23
+import org.openzen.zenscript.codemodel.type.storage.StorageType;
24
+import org.openzen.zenscript.lexer.ParseException;
25
+import org.openzen.zenscript.parser.BracketExpressionParser;
26
+import org.openzen.zenscript.parser.ParsedFile;
27
+
28
+/**
29
+ *
30
+ * @author Hoofdgebruiker
31
+ */
32
+public class SourceModuleReference implements ModuleReference {
33
+	private final SourceModule module;
34
+	private final boolean isStdlib;
35
+	
36
+	public SourceModuleReference(SourceModule module) {
37
+		this(module, false);
38
+	}
39
+	
40
+	public SourceModuleReference(SourceModule module, boolean isStdlib) {
41
+		this.module = module;
42
+		this.isStdlib = isStdlib;
43
+	}
44
+	
45
+	@Override
46
+	public String getName() {
47
+		return module.getName();
48
+	}
49
+
50
+	@Override
51
+	public SemanticModule load(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger) {
52
+		SemanticModule[] dependencies = module.loadDependencies(loader, registry, exceptionLogger);
53
+
54
+		ModuleSpace space = new ModuleSpace(registry, new ArrayList<>(), StorageType.getStandard());
55
+		for (SemanticModule module : dependencies) {
56
+			try {
57
+				space.addModule(module.name, module);
58
+			} catch (CompileException ex) {
59
+				throw new ConstructorException("Error: exception during compilation", ex);
60
+			}
61
+		}
62
+
63
+		ZSPackage pkg = isStdlib ? registry.stdlib : new ZSPackage(null, getName());
64
+		Module module = new Module(getName());
65
+		CompilingPackage compilingPackage = new CompilingPackage(pkg, module);
66
+
67
+		ParsedFile[] parsedFiles = parse(compilingPackage, exceptionLogger);
68
+		SemanticModule result = ParsedFile.compileSyntaxToSemantic(dependencies, compilingPackage, parsedFiles, space, FunctionParameter.NONE, exceptionLogger);
69
+		result.globals.putAll(this.module.getGlobals(result));
70
+		return result;
71
+	}
72
+	
73
+	@Override
74
+	public SourcePackage getRootPackage() {
75
+		return module.getRootPackage();
76
+	}
77
+	
78
+	public ParsedFile[] parse(CompilingPackage compilingPackage, Consumer<CompileException> exceptionLogger) {
79
+		// TODO: load bracket parsers from host plugins
80
+		List<ParsedFile> files = new ArrayList<>();
81
+		parse(files, compilingPackage, null, module.getRootPackage(), exceptionLogger);
82
+		return files.toArray(new ParsedFile[files.size()]);
83
+	}
84
+	
85
+	private static void parse(List<ParsedFile> files, CompilingPackage pkg, BracketExpressionParser bracketParser, SourcePackage directory, Consumer<CompileException> exceptionLogger) {
86
+		for (SourceFile file : directory.getFiles()) {
87
+			try {
88
+				files.add(ParsedFile.parse(pkg, bracketParser, file));
89
+			} catch (ParseException ex) {
90
+				exceptionLogger.accept(new CompileException(ex.position, CompileExceptionCode.PARSE_ERROR, ex.message));
91
+			}
92
+		}
93
+		for (SourcePackage subpkg : directory.getSubPackages()) {
94
+			CompilingPackage innerPackage = pkg.getOrCreatePackage(subpkg.getName());
95
+			pkg.addPackage(subpkg.getName(), innerPackage);
96
+			parse(files, innerPackage, bracketParser, subpkg, exceptionLogger);
97
+		}
98
+	}
99
+}

+ 8
- 19
Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourcePackage.java View File

@@ -5,32 +5,21 @@
5 5
  */
6 6
 package org.openzen.zenscript.constructor.module;
7 7
 
8
-import java.io.File;
9
-import java.util.HashMap;
10
-import java.util.Map;
11
-import org.openzen.zencode.shared.FileSourceFile;
8
+import java.util.Collection;
12 9
 import org.openzen.zencode.shared.SourceFile;
13 10
 
14 11
 /**
15 12
  *
16 13
  * @author Hoofdgebruiker
17 14
  */
18
-public class SourcePackage {
19
-	public final File directory;
20
-	public final String name;
21
-	public final Map<String, SourcePackage> subPackages = new HashMap<>();
22
-	public final Map<String, SourceFile> sourceFiles = new HashMap<>();
15
+public interface SourcePackage {
16
+	public String getName();
23 17
 	
24
-	public SourcePackage(File directory, String name) {
25
-		this.directory = directory;
26
-		this.name = name;
27
-	}
18
+	public Collection<? extends SourcePackage> getSubPackages();
28 19
 	
29
-	public void addPackage(SourcePackage pkg) {
30
-		subPackages.put(pkg.name, pkg);
31
-	}
20
+	public Collection<? extends SourceFile> getFiles();
32 21
 	
33
-	public void addFile(SourceFile file) {
34
-		sourceFiles.put(file.getFilename(), file);
35
-	}
22
+	public SourcePackage createSubPackage(String name);
23
+	
24
+	public SourceFile createSourceFile(String name);
36 25
 }

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

@@ -0,0 +1,129 @@
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.constructor.module.directory;
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.HashMap;
13
+import java.util.List;
14
+import java.util.Map;
15
+import java.util.function.Consumer;
16
+import org.json.JSONArray;
17
+import org.json.JSONObject;
18
+import org.openzen.zencode.shared.CompileException;
19
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
20
+import org.openzen.zenscript.codemodel.ModuleSpace;
21
+import org.openzen.zenscript.codemodel.SemanticModule;
22
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
23
+import org.openzen.zenscript.codemodel.type.ISymbol;
24
+import org.openzen.zenscript.codemodel.type.TypeSymbol;
25
+import org.openzen.zenscript.codemodel.type.storage.StorageType;
26
+import org.openzen.zenscript.constructor.ConstructorException;
27
+import org.openzen.zenscript.constructor.JSONUtils;
28
+import org.openzen.zenscript.constructor.ModuleLoader;
29
+import org.openzen.zenscript.constructor.module.SourceModule;
30
+import org.openzen.zenscript.constructor.module.SourcePackage;
31
+
32
+/**
33
+ *
34
+ * @author Hoofdgebruiker
35
+ */
36
+public class DirectorySourceModule implements SourceModule {
37
+	private final String moduleName;
38
+	private final boolean isStdLib;
39
+	private final JSONObject json;
40
+	
41
+	private final SourcePackage rootPackage;
42
+	
43
+	public DirectorySourceModule(String moduleName, File directory) {
44
+		this(moduleName, directory, false);
45
+	}
46
+	
47
+	public DirectorySourceModule(String moduleName, File directory, boolean isStdLib) {
48
+		this.moduleName = moduleName;
49
+		this.isStdLib = isStdLib;
50
+		
51
+		this.rootPackage = new SourceDirectoryPackage(new File(directory, "src"), moduleName);
52
+		
53
+		if (!directory.exists())
54
+			throw new ConstructorException("Error: module directory not found: " + directory);
55
+		
56
+		File jsonFile = new File(directory, "module.json");
57
+		if (!jsonFile.exists())
58
+			throw new ConstructorException("Error: module.json file not found in module " + moduleName);
59
+		
60
+		try {
61
+			json = JSONUtils.load(jsonFile);
62
+		} catch (IOException ex) {
63
+			throw new ConstructorException("Error: could not load module.json: " + ex.getMessage());
64
+		}
65
+	}
66
+
67
+	@Override
68
+	public String getName() {
69
+		return moduleName;
70
+	}
71
+
72
+	@Override
73
+	public SourcePackage getRootPackage() {
74
+		return rootPackage;
75
+	}
76
+
77
+	@Override
78
+	public SemanticModule[] loadDependencies(ModuleLoader loader, GlobalTypeRegistry registry, Consumer<CompileException> exceptionLogger) {
79
+		List<String> dependencyNames = new ArrayList<>();
80
+		if (!isStdLib)
81
+			dependencyNames.add("stdlib");
82
+
83
+		JSONArray jsonDependencies = json.optJSONArray("dependencies");
84
+		if (jsonDependencies != null) {
85
+			for (int i = 0; i < jsonDependencies.length(); i++) {
86
+				dependencyNames.add(jsonDependencies.getString(i));
87
+			}
88
+		}
89
+		// TODO: annotation type registration
90
+		ModuleSpace space = new ModuleSpace(registry, new ArrayList<>(), StorageType.getStandard());
91
+		SemanticModule[] dependencies = new SemanticModule[dependencyNames.size()];
92
+		for (int i = 0; i < dependencies.length; i++) {
93
+			String dependencyName = dependencyNames.get(i);
94
+			SemanticModule module = loader.getModule(dependencyName);
95
+			dependencies[i] = module;
96
+
97
+			try {
98
+				space.addModule(dependencyName, module);
99
+			} catch (CompileException ex) {
100
+				throw new ConstructorException("Error: exception during compilation", ex);
101
+			}
102
+		}
103
+
104
+		return dependencies;
105
+	}
106
+
107
+	@Override
108
+	public Map<String, ISymbol> getGlobals(SemanticModule module) {
109
+		JSONObject jsonGlobals = json.optJSONObject("globals");
110
+		if (jsonGlobals == null)
111
+			return Collections.emptyMap();
112
+		
113
+		Map<String, ISymbol> result = new HashMap<>();
114
+		for (String key : jsonGlobals.keySet()) {
115
+			JSONObject global = jsonGlobals.getJSONObject(key);
116
+			switch (global.getString("type")) {
117
+				case "Definition":
118
+					HighLevelDefinition definition = module.definitions.getDefinition(global.getString("definition"));
119
+					if (definition == null)
120
+						throw new ConstructorException("No such definition: " + global.getString("definition"));
121
+					result.put(key, new TypeSymbol(definition));
122
+					break;
123
+				default:
124
+					throw new ConstructorException("Invalid global type: " + global.getString("type"));
125
+			}
126
+		}
127
+		return result;
128
+	}
129
+}

+ 85
- 0
Constructor/src/main/java/org/openzen/zenscript/constructor/module/directory/SourceDirectoryPackage.java View File

@@ -0,0 +1,85 @@
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.constructor.module.directory;
7
+
8
+import java.io.File;
9
+import java.io.IOException;
10
+import java.util.Collection;
11
+import java.util.HashMap;
12
+import java.util.Map;
13
+import org.openzen.zencode.shared.FileSourceFile;
14
+import org.openzen.zencode.shared.SourceFile;
15
+import org.openzen.zenscript.constructor.module.SourcePackage;
16
+
17
+/**
18
+ *
19
+ * @author Hoofdgebruiker
20
+ */
21
+public class SourceDirectoryPackage implements SourcePackage {
22
+	public final File directory;
23
+	public final String name;
24
+	public final Map<String, SourceDirectoryPackage> subPackages = new HashMap<>();
25
+	public final Map<String, SourceFile> sourceFiles = new HashMap<>();
26
+	
27
+	public SourceDirectoryPackage(File directory, String name) {
28
+		this.directory = directory;
29
+		this.name = name;
30
+		
31
+		for (File file : directory.listFiles()) {
32
+			if (file.isDirectory())
33
+				subPackages.put(file.getName(), new SourceDirectoryPackage(file, file.getName()));
34
+			else if (file.isFile() && file.getName().endsWith(".zs"))
35
+				sourceFiles.put(file.getName(), new FileSourceFile(file.getName(), file));
36
+		}
37
+	}
38
+	
39
+	public void addPackage(SourceDirectoryPackage pkg) {
40
+		subPackages.put(pkg.name, pkg);
41
+	}
42
+	
43
+	public void addFile(SourceFile file) {
44
+		sourceFiles.put(file.getFilename(), file);
45
+	}
46
+
47
+	@Override
48
+	public String getName() {
49
+		return name;
50
+	}
51
+
52
+	@Override
53
+	public Collection<? extends SourcePackage> getSubPackages() {
54
+		return subPackages.values();
55
+	}
56
+
57
+	@Override
58
+	public Collection<? extends SourceFile> getFiles() {
59
+		return sourceFiles.values();
60
+	}
61
+
62
+	@Override
63
+	public SourcePackage createSubPackage(String name) {
64
+		File file = new File(directory, name);
65
+		file.mkdir();
66
+		
67
+		SourceDirectoryPackage sourcePackage = new SourceDirectoryPackage(file, name);
68
+		subPackages.put(name, sourcePackage);
69
+		return sourcePackage;
70
+	}
71
+
72
+	@Override
73
+	public SourceFile createSourceFile(String name) {
74
+		File file = new File(directory, name);
75
+		try {
76
+			file.createNewFile();
77
+		} catch (IOException ex) {
78
+			ex.printStackTrace(); // TODO
79
+		}
80
+		
81
+		FileSourceFile sourceFile = new FileSourceFile(name, file);
82
+		sourceFiles.put(name, sourceFile);
83
+		return sourceFile;
84
+	}
85
+}

+ 0
- 28
DrawableGui/src/main/java/org/openzen/drawablegui/listeners/DummyListenerHandle.java View File

@@ -1,28 +0,0 @@
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.drawablegui.listeners;
7
-
8
-/**
9
- *
10
- * @author Hoofdgebruiker
11
- */
12
-public class DummyListenerHandle<T> implements ListenerHandle<T> {
13
-	private final T listener;
14
-
15
-	public DummyListenerHandle(T listener) {
16
-		this.listener = listener;
17
-	}
18
-
19
-	@Override
20
-	public T getListener() {
21
-		return listener;
22
-	}
23
-
24
-	@Override
25
-	public void close() {
26
-
27
-	}
28
-}

+ 0
- 27
DrawableGui/src/main/java/org/openzen/drawablegui/listeners/ListenerHandle.java View File

@@ -1,27 +0,0 @@
1
-/* Licensed under GPLv3 - https://opensource.org/licenses/GPL-3.0 */
2
-package org.openzen.drawablegui.listeners;
3
-
4
-import java.io.Closeable;
5
-
6
-/**
7
- * An EvenListenerHandle is returned when an EventListener is registered in an
8
- * EventListenerList, which can then be used to unregister the event listener.
9
- *
10
- * @param <T> Event type
11
- * @author Stan Hebben
12
- */
13
-public interface ListenerHandle<T> extends Closeable
14
-{
15
-	/**
16
-	 * Gets this handle's listener.
17
-	 *
18
-	 * @return listener
19
-	 */
20
-	public T getListener();
21
-
22
-	/**
23
-	 * Closes (unregisters) the event listener from the list it was registered to.
24
-	 */
25
-	@Override
26
-	public void close();
27
-}

+ 0
- 165
DrawableGui/src/main/java/org/openzen/drawablegui/listeners/ListenerList.java View File

@@ -1,165 +0,0 @@
1
-/* Licensed under GPLv3 - https://opensource.org/licenses/GPL-3.0 */
2
-package org.openzen.drawablegui.listeners;
3
-
4
-import java.util.function.Consumer;
5
-
6
-/**
7
- * Implements a list of event listeners. This class is thread-safe and listeners
8
- * can be added or removed concurrently, no external locking is ever needed.
9
- * Also, it's very lightweight.
10
- *
11
- * @param <T> event type
12
- * @author Stan Hebben
13
- */
14
-public class ListenerList<T>
15
-{
16
-    public static final int PRIORITY_HIGH = 100;
17
-    public static final int PRIORITY_DEFAULT = 0;
18
-    public static final int PRIORITY_LOW = -100;
19
-	
20
-	// implements a linked list of nodes
21
-	protected volatile EventListenerNode first = null;
22
-	protected EventListenerNode last = null;
23
-
24
-	/**
25
-	 * Adds an IEventListener to the list.
26
-	 *
27
-	 * @param listener event listener
28
-	 * @return event listener's handle
29
-	 */
30
-	public ListenerHandle<T> add(T listener)
31
-	{
32
-        return add(listener, PRIORITY_DEFAULT);
33
-    }
34
-
35
-    public ListenerHandle<T> add(T listener, int priority)
36
-	{
37
-		EventListenerNode node = new EventListenerNode(listener, priority);
38
-
39
-		synchronized (this) {
40
-			if (first == null) {
41
-				first = last = node;
42
-			} else {
43
-                // prioritized list: where to insert?
44
-                EventListenerNode previousNode = last;
45
-                while (previousNode != null && priority > previousNode.priority) {
46
-                    previousNode = previousNode.prev;
47
-                }
48
-
49
-                if (previousNode == null) {
50
-                    node.next = first;
51
-                    first.prev = previousNode;
52
-                    first = node;
53
-                } else {
54
-                    if (previousNode.next == null) {
55
-                        last = node;
56
-                    } else {
57
-                        previousNode.next.prev = node;
58
-                    }
59
-
60
-                    previousNode.next = node;
61
-                    node.prev = previousNode;
62
-                }
63
-            }
64
-		}
65
-
66
-		return node;
67
-	}
68
-
69
-	/**
70
-	 * Removes an IEventListener from the list.
71
-	 *
72
-	 * @param listener listener to be removed
73
-	 * @return true if the listener was removed, false it it wasn't there
74
-	 */
75
-	public synchronized boolean remove(T listener)
76
-	{
77
-		EventListenerNode current = first;
78
-
79
-		while (current != null) {
80
-			if (current.listener == listener) {
81
-				current.close();
82
-				return true;
83
-			}
84
-
85
-            current = current.next;
86
-		}
87
-
88
-		return false;
89
-	}
90
-	
91
-	/**
92
-	 * Clears this listener list.
93
-	 */
94
-	public synchronized void clear()
95
-	{
96
-		first = last = null;
97
-	}
98
-	
99
-	/**
100
-	 * Invokes the given consumer for every listener in the list.
101
-	 * 
102
-	 * @param consumer consumer to be called for each listener
103
-	 */
104
-	public void accept(Consumer<T> consumer)
105
-	{
106
-		EventListenerNode current = first;
107
-		
108
-		while (current != null) {
109
-			consumer.accept(current.listener);
110
-			current = current.next;
111
-		}
112
-	}
113
-
114
-	/**
115
-	 * Checks if there are any listeners in this list.
116
-	 *
117
-	 * @return true if empty
118
-	 */
119
-	public boolean isEmpty()
120
-	{
121
-		return first == null;
122
-	}
123
-
124
-	// #######################
125
-	// ### Private classes ###
126
-	// #######################
127
-
128
-	protected class EventListenerNode implements ListenerHandle<T>
129
-	{
130
-		protected final T listener;
131
-        protected final int priority;
132
-		protected EventListenerNode next = null;
133
-		protected EventListenerNode prev = null;
134
-
135
-		public EventListenerNode(T handler, int priority)
136
-		{
137
-			this.listener = handler;
138
-            this.priority = priority;
139
-		}
140
-
141
-		@Override
142
-		public T getListener()
143
-		{
144
-			return listener;
145
-		}
146
-
147
-		@Override
148
-		public void close()
149
-		{
150
-			synchronized (ListenerList.this) {
151
-				if (prev == null) {
152
-					first = next;
153
-				} else {
154
-					prev.next = next;
155
-				}
156
-
157
-				if (next == null) {
158
-					last = prev;
159
-				} else {
160
-					next.prev = prev;
161
-				}
162
-			}
163
-		}
164
-	}
165
-}

+ 0
- 34
DrawableGui/src/main/java/org/openzen/drawablegui/live/ImmutableLiveBool.java View File

@@ -1,34 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.DummyListenerHandle;
9
-import org.openzen.drawablegui.listeners.ListenerHandle;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public class ImmutableLiveBool implements LiveBool {
16
-	public static final ImmutableLiveBool TRUE = new ImmutableLiveBool(true);
17
-	public static final ImmutableLiveBool FALSE = new ImmutableLiveBool(false);
18
-	
19
-	private final boolean value;
20
-	
21
-	private ImmutableLiveBool(boolean value) {
22
-		this.value = value;
23
-	}
24
-
25
-	@Override
26
-	public boolean getValue() {
27
-		return value;
28
-	}
29
-
30
-	@Override
31
-	public ListenerHandle<Listener> addListener(Listener listener) {
32
-		return new DummyListenerHandle<>(listener);
33
-	}
34
-}

+ 0
- 31
DrawableGui/src/main/java/org/openzen/drawablegui/live/ImmutableLiveObject.java View File

@@ -1,31 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.DummyListenerHandle;
9
-import org.openzen.drawablegui.listeners.ListenerHandle;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public class ImmutableLiveObject<T> implements LiveObject<T> {
16
-	private final T value;
17
-	
18
-	public ImmutableLiveObject(T value) {
19
-		this.value = value;
20
-	}
21
-	
22
-	@Override
23
-	public T getValue() {
24
-		return value;
25
-	}
26
-
27
-	@Override
28
-	public ListenerHandle<Listener<T>> addListener(Listener<T> listener) {
29
-		return new DummyListenerHandle<>(listener);
30
-	}
31
-}

+ 0
- 31
DrawableGui/src/main/java/org/openzen/drawablegui/live/ImmutableLiveString.java View File

@@ -1,31 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.DummyListenerHandle;
9
-import org.openzen.drawablegui.listeners.ListenerHandle;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public class ImmutableLiveString implements LiveString {
16
-	private final String value;
17
-
18
-	public ImmutableLiveString(String value) {
19
-		this.value = value;
20
-	}
21
-	
22
-	@Override
23
-	public ListenerHandle<Listener> addListener(Listener listener) {
24
-		return new DummyListenerHandle<>(listener);
25
-	}
26
-
27
-	@Override
28
-	public String getValue() {
29
-		return value;
30
-	}
31
-}

+ 0
- 30
DrawableGui/src/main/java/org/openzen/drawablegui/live/InverseLiveBool.java View File

@@ -1,30 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-
10
-/**
11
- *
12
- * @author Hoofdgebruiker
13
- */
14
-public class InverseLiveBool implements LiveBool {
15
-	private final LiveBool source;
16
-	
17
-	public InverseLiveBool(LiveBool source) {
18
-		this.source = source;
19
-	}
20
-
21
-	@Override
22
-	public boolean getValue() {
23
-		return !source.getValue();
24
-	}
25
-
26
-	@Override
27
-	public ListenerHandle<Listener> addListener(Listener listener) {
28
-		return source.addListener((oldValue, newValue) -> listener.onChanged(!oldValue, !newValue));
29
-	}
30
-}

+ 0
- 91
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveArrayList.java View File

@@ -1,91 +0,0 @@
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.drawablegui.live;
7
-
8
-import java.util.ArrayList;
9
-import java.util.Iterator;
10
-import java.util.List;
11
-import org.openzen.drawablegui.listeners.ListenerHandle;
12
-import org.openzen.drawablegui.listeners.ListenerList;
13
-
14
-/**
15
- *
16
- * @author Hoofdgebruiker
17
- */
18
-public class LiveArrayList<T> implements MutableLiveList<T> {
19
-	private final List<T> values = new ArrayList<>();
20
-	private final ListenerList<Listener<T>> listeners = new ListenerList<>();
21
-
22
-	@Override
23
-	public void add(T value) {
24
-		int index = values.size();
25
-		values.add(value);
26
-		listeners.accept(listener -> listener.onInserted(index, value));
27
-	}
28
-
29
-	@Override
30
-	public void add(int index, T value) {
31
-		values.add(index, value);
32
-		listeners.accept(listener -> listener.onInserted(index, value));
33
-	}
34
-
35
-	@Override
36
-	public void set(int index, T value) {
37
-		T oldValue = values.set(index, value);
38
-		listeners.accept(listener -> listener.onChanged(index, oldValue, value));
39
-	}
40
-
41
-	@Override
42
-	public void remove(int index) {
43
-		T oldValue = values.remove(index);
44
-		listeners.accept(listener -> listener.onRemoved(index, oldValue));
45
-	}
46
-
47
-	@Override
48
-	public void remove(T value) {
49
-		int index = indexOf(value);
50
-		if (index < 0)
51
-			return;
52
-		
53
-		remove(index);
54
-	}
55
-	
56
-	@Override
57
-	public void clear() {
58
-		for (int i = size() - 1; i >= 0; i--)
59
-			remove(i);
60
-	}
61
-
62
-	@Override
63
-	public int indexOf(T value) {
64
-		return values.indexOf(value);
65
-	}
66
-	
67
-	@Override
68
-	public int size() {
69
-		return values.size();
70
-	}
71
-
72
-	@Override
73
-	public T get(int index) {
74
-		return values.get(index);
75
-	}
76
-	
77
-	@Override
78
-	public void close() {
79
-		// TODO: close closeables
80
-	}
81
-
82
-	@Override
83
-	public Iterator<T> iterator() {
84
-		return values.iterator();
85
-	}
86
-
87
-	@Override
88
-	public ListenerHandle<Listener<T>> addListener(Listener<T> listener) {
89
-		return listeners.add(listener);
90
-	}
91
-}

+ 0
- 22
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveBool.java View File

@@ -1,22 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-
10
-/**
11
- *
12
- * @author Hoofdgebruiker
13
- */
14
-public interface LiveBool {
15
-	public boolean getValue();
16
-	
17
-	public ListenerHandle<Listener> addListener(Listener listener);
18
-	
19
-	public interface Listener {
20
-		void onChanged(boolean oldValue, boolean newValue);
21
-	}
22
-}

+ 0
- 24
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveInt.java View File

@@ -1,24 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-
10
-/**
11
- *
12
- * @author Hoofdgebruiker
13
- */
14
-public interface LiveInt {
15
-	int getValue();
16
-	
17
-	void setValue(int value);
18
-	
19
-	ListenerHandle<Listener> addListener(Listener listener);
20
-	
21
-	interface Listener {
22
-		void onChanged(int oldValue, int newValue);
23
-	}
24
-}

+ 0
- 36
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveList.java View File

@@ -1,36 +0,0 @@
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.drawablegui.live;
7
-
8
-import java.util.Iterator;
9
-import org.openzen.drawablegui.listeners.ListenerHandle;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public interface LiveList<T> extends Iterable<T> {
16
-	int indexOf(T value);
17
-	
18
-	int size();
19
-	
20
-	T get(int index);
21
-	
22
-	void close();
23
-	
24
-	@Override
25
-	Iterator<T> iterator();
26
-	
27
-	ListenerHandle<Listener<T>> addListener(Listener<T> listener);
28
-	
29
-	interface Listener<T> {
30
-		void onInserted(int index, T value);
31
-		
32
-		void onChanged(int index, T oldValue, T newValue);
33
-		
34
-		void onRemoved(int index, T oldValue);
35
-	}
36
-}

+ 0
- 22
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveObject.java View File

@@ -1,22 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-
10
-/**
11
- *
12
- * @author Hoofdgebruiker
13
- */
14
-public interface LiveObject<T> {
15
-	public T getValue();
16
-	
17
-	public ListenerHandle<Listener<T>> addListener(Listener<T> listener);
18
-	
19
-	public interface Listener<T> {
20
-		void onUpdated(T oldValue, T newValue);
21
-	}
22
-}

+ 0
- 22
DrawableGui/src/main/java/org/openzen/drawablegui/live/LiveString.java View File

@@ -1,22 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-
10
-/**
11
- *
12
- * @author Hoofdgebruiker
13
- */
14
-public interface LiveString {
15
-	ListenerHandle<Listener> addListener(Listener listener);
16
-	
17
-	String getValue();
18
-	
19
-	interface Listener {
20
-		void onChanged(String oldValue, String newValue);
21
-	}
22
-}

+ 0
- 24
DrawableGui/src/main/java/org/openzen/drawablegui/live/MutableLiveList.java View File

@@ -1,24 +0,0 @@
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.drawablegui.live;
7
-
8
-/**
9
- *
10
- * @author Hoofdgebruiker
11
- */
12
-public interface MutableLiveList<T> extends LiveList<T> {
13
-	void add(T value);
14
-	
15
-	void add(int index, T value);
16
-	
17
-	void set(int index, T value);
18
-	
19
-	void remove(int index);
20
-	
21
-	void remove(T value);
22
-	
23
-	void clear();
24
-}

+ 0
- 46
DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveBool.java View File

@@ -1,46 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-import org.openzen.drawablegui.listeners.ListenerList;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public class SimpleLiveBool implements MutableLiveBool {
16
-	private final ListenerList<LiveBool.Listener> listeners = new ListenerList<>();
17
-	private boolean value;
18
-	
19
-	public SimpleLiveBool() {
20
-		this(false);
21
-	}
22
-	
23
-	public SimpleLiveBool(boolean value) {
24
-		this.value = value;
25
-	}
26
-	
27
-	@Override
28
-	public boolean getValue() {
29
-		return value;
30
-	}
31
-	
32
-	@Override
33
-	public void setValue(boolean value) {
34
-		if (value == this.value)
35
-			return;
36
-		
37
-		boolean oldValue = this.value;
38
-		this.value = value;
39
-		listeners.accept(listener -> listener.onChanged(oldValue, value));
40
-	}
41
-	
42
-	@Override
43
-	public ListenerHandle<LiveBool.Listener> addListener(LiveBool.Listener listener) {
44
-		return listeners.add(listener);
45
-	}
46
-}

+ 0
- 42
DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveInt.java View File

@@ -1,42 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-import org.openzen.drawablegui.listeners.ListenerList;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public class SimpleLiveInt implements LiveInt {
16
-	private final ListenerList<Listener> listeners = new ListenerList<>();
17
-	private int value;
18
-
19
-	public SimpleLiveInt(int value) {
20
-		this.value = value;
21
-	}
22
-	
23
-	@Override
24
-	public int getValue() {
25
-		return value;
26
-	}
27
-
28
-	@Override
29
-	public void setValue(int value) {
30
-		if (value == this.value)
31
-			return;
32
-		
33
-		int oldValue = this.value;
34
-		this.value = value;
35
-		listeners.accept(listener -> listener.onChanged(oldValue, value));
36
-	}
37
-
38
-	@Override
39
-	public ListenerHandle<Listener> addListener(Listener listener) {
40
-		return listeners.add(listener);
41
-	}
42
-}

+ 0
- 43
DrawableGui/src/main/java/org/openzen/drawablegui/live/SimpleLiveString.java View File

@@ -1,43 +0,0 @@
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.drawablegui.live;
7
-
8
-import org.openzen.drawablegui.listeners.ListenerHandle;
9
-import org.openzen.drawablegui.listeners.ListenerList;
10
-
11
-/**
12
- *
13
- * @author Hoofdgebruiker
14
- */
15
-public class SimpleLiveString implements MutableLiveString {
16
-	private final ListenerList<Listener> listeners = new ListenerList<>();
17
-	
18
-	private String value;
19
-	
20
-	public SimpleLiveString(String value) {
21
-		this.value = value;
22
-	}
23
-
24
-	@Override
25
-	public ListenerHandle<Listener> addListener(Listener listener) {
26
-		return listeners.add(listener);
27
-	}
28
-
29
-	@Override
30
-	public String getValue() {
31
-		return value;
32
-	}
33
-
34
-	@Override
35
-	public void setValue(String value) {
36
-		if (value.equals(this.value))
37
-			return;
38
-		
39
-		String oldValue = this.value;
40
-		this.value = value;
41
-		listeners.accept(listener -> listener.onChanged(oldValue, value));
42
-	}
43
-}

+ 27
- 12
DrawableGui/src/main/java/org/openzen/drawablegui/scroll/DScrollPane.java View File

@@ -53,6 +53,9 @@ public class DScrollPane implements DComponent, DScrollContext {
53 53
 	private final ListenerHandle<FunctionIntIntToVoid> offsetYListener;
54 54
 	private final ListenerHandle<BiConsumer<DSizing, DSizing>> contentsSizingListener;
55 55
 	
56
+	private boolean isHorizontalScrollbarVisible = true;
57
+	private boolean isVerticalScrollbarVisible = true;
58
+	
56 59
 	private DComponent hovering = null;
57 60
 	
58 61
 	private DSubSurface subSurface;
@@ -81,6 +84,7 @@ public class DScrollPane implements DComponent, DScrollContext {
81 84
 			
82 85
 			contents.setBounds(new DIRectangle(0, 0, bounds.width, Math.max(bounds.height, newPreferences.preferredHeight)));
83 86
 			contentsHeight.setValue(newPreferences.preferredHeight);
87
+			contentsWidth.setValue(newPreferences.preferredWidth);
84 88
 		});
85 89
 	}
86 90
 
@@ -136,25 +140,28 @@ public class DScrollPane implements DComponent, DScrollContext {
136 140
 		shape = context.shadowPath(0, style.shape.instance(style.margin.apply(bounds)), DTransform2D.IDENTITY, style.backgroundColor, style.shadow);
137 141
 		style.border.update(context, style.margin.apply(bounds));
138 142
 		
143
+		int scrollBarWidth = verticalScrollBar.getSizing().getValue().preferredWidth;
144
+		int scrollBarHeight = horizontalScrollBar.getSizing().getValue().preferredHeight;
145
+		int scrollBarMarginX = isHorizontalScrollbarVisible ? scrollBarWidth : 0;
146
+		int scrollBarMarginY = isVerticalScrollbarVisible ? scrollBarHeight : 0;
147
+		
139 148
 		int width = Math.max(
140
-				bounds.width - style.border.getPaddingHorizontal(),
149
+				bounds.width - style.border.getPaddingHorizontal() - scrollBarMarginX,
141 150
 				contents.getSizing().getValue().preferredWidth);
142 151
 		int height = Math.max(
143
-				bounds.height - style.border.getPaddingHorizontal(),
152
+				bounds.height - style.border.getPaddingHorizontal() - scrollBarMarginY,
144 153
 				contents.getSizing().getValue().preferredHeight);
145
-		int scrollBarWidth = verticalScrollBar.getSizing().getValue().preferredWidth;
146
-		int scrollBarHeight = horizontalScrollBar.getSizing().getValue().preferredHeight;
147
-
154
+		
148 155
 		verticalScrollBar.setBounds(new DIRectangle(
149 156
 				bounds.x + bounds.width - scrollBarWidth - style.border.getPaddingRight() - style.margin.right,
150 157
 				bounds.y + style.border.getPaddingTop() + style.margin.top,
151 158
 				scrollBarWidth,
152
-				bounds.height - style.border.getPaddingVertical() - style.margin.getVertical()));
159
+				bounds.height - style.border.getPaddingVertical() - style.margin.getVertical() - scrollBarMarginY));
153 160
 		
154 161
 		horizontalScrollBar.setBounds(new DIRectangle(
155 162
 				bounds.x + style.border.getPaddingLeft() + style.margin.left,
156 163
 				bounds.y + bounds.height - scrollBarHeight - style.border.getPaddingBottom() - style.margin.bottom,
157
-				bounds.width - style.border.getPaddingHorizontal() - style.margin.getHorizontal(),
164
+				bounds.width - style.border.getPaddingHorizontal() - style.margin.getHorizontal() - scrollBarMarginX,
158 165
 				scrollBarHeight));
159 166
 		
160 167
 		contents.setBounds(new DIRectangle(0, 0, width, height));
@@ -171,7 +178,10 @@ public class DScrollPane implements DComponent, DScrollContext {
171 178
 	
172 179
 	@Override
173 180
 	public void onMouseScroll(DMouseEvent e) {
174
-		offsetY.setValue(offsetY.getValue() + e.deltaZ * 50);
181
+		if (e.has(DMouseEvent.SHIFT))
182
+			offsetX.setValue(offsetX.getValue() + e.deltaZ * 50);
183
+		else
184
+			offsetY.setValue(offsetY.getValue() + e.deltaZ * 50);
175 185
 	}
176 186
 	
177 187
 	@Override
@@ -318,9 +328,14 @@ public class DScrollPane implements DComponent, DScrollContext {
318 328
 
319 329
 		@Override
320 330
 		public void invoke(int oldValue, int newValue) {
331
+			int scrollBarWidth = verticalScrollBar.getSizing().getValue().preferredWidth;
332
+			int scrollBarHeight = horizontalScrollBar.getSizing().getValue().preferredHeight;
333
+			int scrollBarMarginX = isHorizontalScrollbarVisible ? scrollBarWidth : 0;
334
+			int scrollBarMarginY = isVerticalScrollbarVisible ? scrollBarHeight : 0;
335
+			
321 336
 			int valueX = offsetX.getValue();
322
-			if (valueX > contentsWidth.getValue() - bounds.width)
323
-				valueX = contentsWidth.getValue() - bounds.width;
337
+			if (valueX > contentsWidth.getValue() - (bounds.width - scrollBarMarginX))
338
+				valueX = contentsWidth.getValue() - (bounds.width - scrollBarMarginX);
324 339
 			if (valueX < 0)
325 340
 				valueX = 0;
326 341
 			
@@ -328,8 +343,8 @@ public class DScrollPane implements DComponent, DScrollContext {
328 343
 				offsetX.setValue(valueX);
329 344
 			
330 345
 			int valueY = offsetY.getValue();
331
-			if (valueY > contentsHeight.getValue() - bounds.height)
332
-				valueY = contentsHeight.getValue() - bounds.height;
346
+			if (valueY > contentsHeight.getValue() - (bounds.height - scrollBarMarginY))
347
+				valueY = contentsHeight.getValue() - (bounds.height - scrollBarMarginY);
333 348
 			if (valueY < 0)
334 349
 				valueY = 0;
335 350
 			

+ 38
- 8
IDE/src/main/java/org/openzen/zenscript/ide/Main.java View File

@@ -1,18 +1,24 @@
1 1
 package org.openzen.zenscript.ide;
2 2
 
3
+import java.awt.GraphicsEnvironment;
4
+import java.awt.Rectangle;
3 5
 import java.awt.event.WindowAdapter;
4 6
 import java.awt.event.WindowEvent;
5 7
 import java.io.File;
6 8
 import java.io.IOException;
7 9
 import javax.swing.JFrame;
10
+import live.LiveObject;
8 11
 import live.MutableLiveBool;
12
+import live.SimpleLiveObject;
9 13
 import org.openzen.drawablegui.DUIWindow;
10 14
 import org.openzen.zenscript.ide.host.DevelopmentHost;
11 15
 import org.openzen.zenscript.ide.host.local.LocalProjectDevelopmentHost;
12 16
 import org.openzen.drawablegui.swing.SwingWindow;
13 17
 import org.openzen.zenscript.constructor.Project;
18
+import org.openzen.zenscript.ide.host.IDECompileState;
14 19
 import org.openzen.zenscript.ide.host.IDEPropertyDirectory;
15 20
 import org.openzen.zenscript.ide.host.IDEPropertyStore;
21
+import org.openzen.zenscript.ide.host.IDETarget;
16 22
 import org.openzen.zenscript.ide.ui.IDEWindow;
17 23
 import org.openzen.zenscript.ide.ui.view.WindowView;
18 24
 
@@ -23,7 +29,8 @@ public class Main {
23 29
     public static void main(String... args) throws IOException {
24 30
 		if (args.length == 0) {
25 31
 			// testing environment - TODO project chooser/creator
26
-			args = new String[] { "../../ZenCode", "SharedJavaSource" };
32
+			//args = new String[] { "../../ZenCode", "SharedJavaSource" };
33
+			args = new String[] { "../../ZenCode", "CodeModelJavaSource" };
27 34
 		}
28 35
 		
29 36
 		Arguments arguments = new Arguments(args);
@@ -43,19 +50,42 @@ public class Main {
43 50
 		if (target == null && host.getTargets().getLength() > 0)
44 51
 			target = host.getTargets().getAt(0).getName();
45 52
 		
53
+		IDETarget targetObject = null;
54
+		for (IDETarget t : host.getTargets())
55
+			if (t.getName().equals(target))
56
+				targetObject = t;
57
+		
58
+		if (targetObject == null)
59
+			throw new IllegalStateException("No target specified");
60
+		
61
+		LiveObject<IDETarget> liveTarget = new SimpleLiveObject<>(targetObject);
62
+		LiveObject<IDECompileState> compileState = liveTarget.getValue().load(); // TODO: update this when target changes
63
+		
46 64
 		IDEPropertyDirectory uiState = properties.getRoot().getSubdirectory("uiState");
47 65
 		IDEWindow window = new IDEWindow(host, target);
48
-		WindowView root = new WindowView(window, host, uiState);
66
+		WindowView root = new WindowView(window, host, uiState, compileState);
49 67
 		
50 68
 		int pixelPerInch = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
51 69
 		MutableLiveBool maximized = uiState.getLiveBool("maximized", false);
52 70
 		SwingWindow swingWindow = new SwingWindow("ZenCode IDE - " + host.getName(), root, false);
53
-		swingWindow.setSize(
54
-				uiState.getInt("width", 800 * pixelPerInch / 96),
55
-				uiState.getInt("height", 600 * pixelPerInch / 96));
56
-		swingWindow.setLocation(
57
-				uiState.getInt("x", 0),
58
-				uiState.getInt("y", 0));
71
+		
72
+		int x = uiState.getInt("x", 0);
73
+		int y = uiState.getInt("y", 0);
74
+		int width = uiState.getInt("width", 800 * pixelPerInch / 96);
75
+		int height = uiState.getInt("height", 600 * pixelPerInch / 96);
76
+		GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
77
+		Rectangle bounds = env.getMaximumWindowBounds();
78
+		if (x < bounds.x)
79
+			x = bounds.x;
80
+		if (y < bounds.y)
81
+			y = bounds.y;
82
+		if (width > bounds.width)
83
+			width = bounds.width;
84
+		if (height > bounds.height)
85
+			height = bounds.height;
86
+		
87
+		swingWindow.setSize(width, height);
88
+		swingWindow.setLocation(x, y);
59 89
 		swingWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
60 90
 		swingWindow.setExtendedState(maximized.getValue() ? JFrame.MAXIMIZED_BOTH : JFrame.NORMAL);
61 91
 		swingWindow.setVisible(true);

+ 0
- 57
IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeSpace.java View File

@@ -1,57 +0,0 @@
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.ide.codemodel;
7
-
8
-import java.util.ArrayList;
9
-import java.util.Collections;
10
-import java.util.HashMap;
11
-import java.util.List;
12
-import java.util.Map;
13
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
14
-import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
15
-import org.openzen.zenscript.constructor.ModuleLoader;
16
-import org.openzen.zenscript.ide.host.DevelopmentHost;
17
-import org.openzen.zenscript.ide.host.IDEModule;
18
-import org.openzen.zenscript.ide.host.IDESourceFile;
19
-
20
-/**
21
- *
22
- * @author Hoofdgebruiker
23
- */
24
-public class IDECodeSpace {
25
-	private final DevelopmentHost host;
26
-	private final Map<IDESourceFile, List<IDECodeError>> sourceFileErrors = new HashMap<>();
27
-	
28
-	public IDECodeSpace(DevelopmentHost host) {
29
-		this.host = host;
30
-		
31
-		ZSPackage root = ZSPackage.createRoot();
32
-		ZSPackage stdlib = new ZSPackage(root, "stdlib");
33
-		GlobalTypeRegistry registry = new GlobalTypeRegistry(stdlib);
34
-		ModuleLoader loader = new ModuleLoader(registry, exception -> {
35
-			exception.printStackTrace();
36
-		});
37
-		for (IDEModule module : host.getModules()) {
38
-			module.prebuild(loader, this::addError);
39
-		}
40
-	}
41
-	
42
-	public void onSaved(IDESourceFile file) {
43
-		
44
-	}
45
-	
46
-	public List<IDECodeError> getErrors(IDESourceFile file) {
47
-		return sourceFileErrors.getOrDefault(file, Collections.emptyList());
48
-	}
49
-	
50
-	private void addError(IDECodeError error) {
51
-		if (error.file == null)
52
-			return;
53
-		if (!sourceFileErrors.containsKey(error.file))
54
-			sourceFileErrors.put(error.file, new ArrayList<>());
55
-		sourceFileErrors.get(error.file).add(error);
56
-	}
57
-}

IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeError.java → IDE/src/main/java/org/openzen/zenscript/ide/host/IDECodeError.java View File

@@ -3,10 +3,9 @@
3 3
  * To change this template file, choose Tools | Templates
4 4
  * and open the template in the editor.
5 5
  */
6
-package org.openzen.zenscript.ide.codemodel;
6
+package org.openzen.zenscript.ide.host;
7 7
 
8 8
 import org.openzen.zencode.shared.CodePosition;
9
-import org.openzen.zenscript.ide.host.IDESourceFile;
10 9
 
11 10
 /**
12 11
  *

+ 16
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/IDECompileState.java View File

@@ -0,0 +1,16 @@
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.ide.host;
7
+
8
+import live.LiveList;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public interface IDECompileState {
15
+	public LiveList<IDECodeError> getErrors(IDESourceFile file);
16
+}

+ 0
- 1
IDE/src/main/java/org/openzen/zenscript/ide/host/IDEModule.java View File

@@ -7,7 +7,6 @@ package org.openzen.zenscript.ide.host;
7 7
 
8 8
 import java.util.function.Consumer;
9 9
 import org.openzen.zenscript.constructor.ModuleLoader;
10
-import org.openzen.zenscript.ide.codemodel.IDECodeError;
11 10
 
12 11
 /**
13 12
  *

+ 3
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/IDETarget.java View File

@@ -6,6 +6,7 @@
6 6
 package org.openzen.zenscript.ide.host;
7 7
 
8 8
 import java.util.function.Consumer;
9
+import live.LiveObject;
9 10
 import org.openzen.zenscript.ide.ui.view.output.OutputLine;
10 11
 
11 12
 /**
@@ -19,6 +20,8 @@ public interface IDETarget {
19 20
 	
20 21
 	boolean canRun();
21 22
 	
23
+	LiveObject<IDECompileState> load();
24
+	
22 25
 	void build(Consumer<OutputLine> output);
23 26
 	
24 27
 	void run(Consumer<OutputLine> output);

+ 34
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalCompileState.java View File

@@ -0,0 +1,34 @@
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.ide.host.local;
7
+
8
+import java.util.HashMap;
9
+import java.util.Map;
10
+import live.LiveArrayList;
11
+import live.LiveList;
12
+import org.openzen.zenscript.ide.host.IDECodeError;
13
+import org.openzen.zenscript.ide.host.IDECompileState;
14
+import org.openzen.zenscript.ide.host.IDESourceFile;
15
+
16
+/**
17
+ *
18
+ * @author Hoofdgebruiker
19
+ */
20
+public class LocalCompileState implements IDECompileState {
21
+	private final Map<IDESourceFile, LiveArrayList<IDECodeError>> errors = new HashMap<>();
22
+
23
+	public void addError(IDESourceFile file, IDECodeError error) {
24
+		if (!errors.containsKey(file))
25
+			errors.put(file, new LiveArrayList<>());
26
+		
27
+		errors.get(file).add(error);
28
+	}
29
+	
30
+	@Override
31
+	public LiveList<IDECodeError> getErrors(IDESourceFile file) {
32
+		return errors.getOrDefault(file, new LiveArrayList<>());
33
+	}
34
+}

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

@@ -9,7 +9,7 @@ import java.util.function.Consumer;
9 9
 import org.openzen.zenscript.codemodel.SemanticModule;
10 10
 import org.openzen.zenscript.constructor.ModuleLoader;
11 11
 import org.openzen.zenscript.constructor.module.ModuleReference;
12
-import org.openzen.zenscript.ide.codemodel.IDECodeError;
12
+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;

+ 11
- 30
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalPackage.java View File

@@ -8,6 +8,7 @@ package org.openzen.zenscript.ide.host.local;
8 8
 import java.io.File;
9 9
 import java.io.IOException;
10 10
 import java.util.Arrays;
11
+import java.util.Collection;
11 12
 
12 13
 import live.LiveArrayList;
13 14
 import live.LiveList;
@@ -16,6 +17,7 @@ import live.SortedLiveList;
16 17
 
17 18
 import org.openzen.zencode.shared.FileSourceFile;
18 19
 import org.openzen.zencode.shared.SourceFile;
20
+import org.openzen.zenscript.constructor.module.directory.SourceDirectoryPackage;
19 21
 import org.openzen.zenscript.constructor.module.SourcePackage;
20 22
 import org.openzen.zenscript.ide.host.IDEPackage;
21 23
 import org.openzen.zenscript.ide.host.IDESourceFile;
@@ -35,20 +37,11 @@ public class LocalPackage implements IDEPackage {
35 37
 	public LocalPackage(SourcePackage pkg) {
36 38
 		this.pkg = pkg;
37 39
 		
38
-		String[] subPackageKeys = pkg.subPackages.keySet()
39
-				.toArray(new String[pkg.subPackages.size()]);
40
-		Arrays.sort(subPackageKeys);
41
-		
42
-		String[] sourceFileKeys = pkg.sourceFiles.keySet()
43
-				.toArray(new String[pkg.sourceFiles.size()]);
44
-		Arrays.sort(sourceFileKeys);
45
-		
46
-		for (SourcePackage subPackage : pkg.subPackages.values()) {
40
+		for (SourcePackage subPackage : pkg.getSubPackages())
47 41
 			subPackages.add(new LocalPackage(subPackage));
48
-		}
49
-		for (SourceFile sourceFile : pkg.sourceFiles.values()) {
42
+		
43
+		for (SourceFile sourceFile : pkg.getFiles())
50 44
 			sourceFiles.add(new LocalSourceFile(sourceFile));
51
-		}
52 45
 		
53 46
 		subPackagesSorted = new SortedLiveList<>(subPackages, (a, b) -> a.getName().compareTo(b.getName()));
54 47
 		sourceFilesSorted = new SortedLiveList<>(sourceFiles, (a, b) -> a.getName().getValue().compareTo(b.getName().getValue()));
@@ -56,7 +49,7 @@ public class LocalPackage implements IDEPackage {
56 49
 	
57 50
 	@Override
58 51
 	public String getName() {
59
-		return pkg.name;
52
+		return pkg.getName();
60 53
 	}
61 54
 
62 55
 	@Override
@@ -71,28 +64,16 @@ public class LocalPackage implements IDEPackage {
71 64
 	
72 65
 	@Override
73 66
 	public IDEPackage createSubPackage(String name) {
74
-		File file = new File(this.pkg.directory, name);
75
-		file.mkdir();
76
-		
77
-		SourcePackage sourcePackage = new SourcePackage(file, name);
78
-		IDEPackage pkg = new LocalPackage(sourcePackage);
79
-		this.pkg.subPackages.put(name, sourcePackage);
80
-		subPackages.add(pkg);
81
-		return pkg;
67
+		SourcePackage subpkg = this.pkg.createSubPackage(name);
68
+		LocalPackage local = new LocalPackage(subpkg);
69
+		subPackages.add(local);
70
+		return local;
82 71
 	}
83 72
 	
84 73
 	@Override
85 74
 	public IDESourceFile createSourceFile(String name) {
86
-		File file = new File(this.pkg.directory, name);
87
-		try {
88
-			file.createNewFile();
89
-		} catch (IOException ex) {
90
-			ex.printStackTrace(); // TODO
91
-		}
92
-		
93
-		FileSourceFile sourceFile = new FileSourceFile(name, file);
75
+		SourceFile sourceFile = pkg.createSourceFile(name);
94 76
 		IDESourceFile localSourceFile = new LocalSourceFile(sourceFile);
95
-		this.pkg.sourceFiles.put(name, sourceFile);
96 77
 		sourceFiles.add(localSourceFile);
97 78
 		return localSourceFile;
98 79
 	}

+ 23
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalSourceFile.java View File

@@ -11,6 +11,7 @@ import java.io.IOException;
11 11
 import java.io.OutputStreamWriter;
12 12
 import java.io.Writer;
13 13
 import java.nio.charset.StandardCharsets;
14
+import java.util.Objects;
14 15
 
15 16
 import live.LiveString;
16 17
 import live.MutableLiveString;
@@ -57,4 +58,26 @@ public class LocalSourceFile implements IDESourceFile {
57 58
 			ex.printStackTrace();
58 59
 		}
59 60
 	}
61
+
62
+	@Override
63
+	public int hashCode() {
64
+		int hash = 3;
65
+		hash = 83 * hash + Objects.hashCode(this.file);
66
+		return hash;
67
+	}
68
+
69
+	@Override
70
+	public boolean equals(Object obj) {
71
+		if (this == obj) {
72
+			return true;
73
+		}
74
+		if (obj == null) {
75
+			return false;
76
+		}
77
+		if (getClass() != obj.getClass()) {
78
+			return false;
79
+		}
80
+		final LocalSourceFile other = (LocalSourceFile) obj;
81
+		return file == other.file;
82
+	}
60 83
 }

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

@@ -10,6 +10,8 @@ import java.util.HashSet;
10 10
 import java.util.Set;
11 11
 import java.util.Stack;
12 12
 import java.util.function.Consumer;
13
+import live.LiveObject;
14
+import live.SimpleLiveObject;
13 15
 import org.openzen.zenscript.codemodel.SemanticModule;
14 16
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
15 17
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -18,8 +20,12 @@ import org.openzen.zenscript.compiler.ZenCodeCompiler;
18 20
 import org.openzen.zenscript.constructor.Library;
19 21
 import org.openzen.zenscript.constructor.ModuleLoader;
20 22
 import org.openzen.zenscript.constructor.Project;
21
-import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
23
+import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
22 24
 import org.openzen.zenscript.constructor.module.ModuleReference;
25
+import org.openzen.zenscript.constructor.module.SourceModuleReference;
26
+import org.openzen.zenscript.ide.host.IDECodeError;
27
+import org.openzen.zenscript.ide.host.IDECompileState;
28
+import org.openzen.zenscript.ide.host.IDESourceFile;
23 29
 import org.openzen.zenscript.ide.host.IDETarget;
24 30
 import org.openzen.zenscript.ide.ui.view.output.ErrorOutputSpan;
25 31
 import org.openzen.zenscript.ide.ui.view.output.OutputLine;
@@ -34,6 +40,7 @@ import stdlib.Strings;
34 40
 public class LocalTarget implements IDETarget {
35 41
 	private final Project project;
36 42
 	private final Target target;
43
+	private final SimpleLiveObject<IDECompileState> state = new SimpleLiveObject<>(null);
37 44
 	
38 45
 	public LocalTarget(Project project, Target target) {
39 46
 		this.project = project;
@@ -54,31 +61,49 @@ public class LocalTarget implements IDETarget {
54 61
 	public boolean canRun() {
55 62
 		return target.canRun();
56 63
 	}
64
+	
65
+	@Override
66
+	public LiveObject<IDECompileState> load() {
67
+		if (state.getValue() == null)
68
+			state.setValue(precompile());
69
+		
70
+		return state;
71
+	}
57 72
 
58 73
 	@Override
59 74
 	public void build(Consumer<OutputLine> output) {
60
-		buildInternal(output);
75
+		buildInternal(output, new LocalCompileState(), true);
61 76
 	}
62 77
 
63 78
 	@Override
64 79
 	public void run(Consumer<OutputLine> output) {
65
-		ZenCodeCompiler compiler = buildInternal(output);
80
+		ZenCodeCompiler compiler = buildInternal(output, new LocalCompileState(), true);
66 81
 		if (compiler != null)
67 82
 			compiler.run();
68 83
 	}
69 84
 	
70
-	private ZenCodeCompiler buildInternal(Consumer<OutputLine> output) {
85
+	private IDECompileState precompile() {
86
+		LocalCompileState result = new LocalCompileState();
87
+		buildInternal(line -> {}, result, false);
88
+		return result;
89
+	}
90
+	
91
+	private ZenCodeCompiler buildInternal(Consumer<OutputLine> output, LocalCompileState state, boolean compile) {
71 92
 		ZSPackage root = ZSPackage.createRoot();
72 93
 		ZSPackage stdlibPackage = new ZSPackage(root, "stdlib");
73 94
 		GlobalTypeRegistry registry = new GlobalTypeRegistry(stdlibPackage);
74 95
 		
75 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
+			
76 100
 			String[] lines = Strings.split(exception.getMessage(), '\n');
77 101
 			for (String line : lines) {
78 102
 				output.accept(new OutputLine(new ErrorOutputSpan(line)));
79 103
 			}
80 104
 		});
81
-		moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
105
+		//moduleLoader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
106
+		moduleLoader.register("stdlib", new SourceModuleReference(new DirectorySourceModule("stdlib", new File("../../StdLibs/stdlib"), true), true));
82 107
 		Set<String> compiledModules = new HashSet<>();
83 108
 		
84 109
 		Consumer<ValidationLogEntry> validationLogger = entry -> {
@@ -86,6 +111,9 @@ public class LocalTarget implements IDETarget {
86 111
 			output.accept(new OutputLine(new ErrorOutputSpan(entry.kind + " " + entry.position.toString() + ": " + message[0])));
87 112
 			for (int i = 1; i < message.length; i++)
88 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));
89 117
 		};
90 118
 		try {
91 119
 			for (Library library : project.libraries) {
@@ -99,25 +127,29 @@ public class LocalTarget implements IDETarget {
99 127
 			SemanticModule module = moduleLoader.getModule(target.getModule());
100 128
 			module = Validator.validate(module.normalize(), validationLogger);
101 129
 			
102
-			ZenCodeCompiler compiler = target.createCompiler(module);
103
-			if (!module.isValid())
104
-				return compiler;
105
-			
106
-			SemanticModule stdlib = moduleLoader.getModule("stdlib");
107
-			stdlib = Validator.validate(stdlib.normalize(), validationLogger);
108
-			if (!stdlib.isValid())
109
-				return compiler;
110
-			
111
-			compiler.addModule(stdlib);
112
-			compiledModules.add(stdlib.name);
113
-			
114
-			boolean isValid = compileDependencies(moduleLoader, compiler, compiledModules, new Stack<>(), module, validationLogger);
115
-			if (!isValid)
130
+			if (compile) {
131
+				ZenCodeCompiler compiler = target.createCompiler(module);
132
+				if (!module.isValid())
133
+					return compiler;
134
+
135
+				SemanticModule stdlib = moduleLoader.getModule("stdlib");
136
+				stdlib = Validator.validate(stdlib.normalize(), validationLogger);
137
+				if (!stdlib.isValid())
138
+					return compiler;
139
+
140
+				compiler.addModule(stdlib);
141
+				compiledModules.add(stdlib.name);
142
+
143
+				boolean isValid = compileDependencies(moduleLoader, compiler, compiledModules, new Stack<>(), module, validationLogger);
144
+				if (!isValid)
145
+					return compiler;
146
+
147
+				compiler.addModule(module);
148
+				compiler.finish();
116 149
 				return compiler;
117
-			
118
-			compiler.addModule(module);
119
-			compiler.finish();
120
-			return compiler;
150
+			} else {
151
+				return null;
152
+			}
121 153
 		} catch (Exception ex) {
122 154
 			ex.printStackTrace();
123 155
 			

+ 8
- 2
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/WindowView.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.ui.view;
7 7
 
8
+import live.LiveObject;
8 9
 import live.LiveString;
9 10
 import live.SimpleLiveObject;
10 11
 import live.SimpleLiveString;
@@ -19,8 +20,10 @@ import org.openzen.drawablegui.style.DShadow;
19 20
 import org.openzen.drawablegui.style.DStyleClass;
20 21
 import org.openzen.drawablegui.style.DStylesheetBuilder;
21 22
 import org.openzen.zenscript.ide.host.DevelopmentHost;
23
+import org.openzen.zenscript.ide.host.IDECompileState;
22 24
 import org.openzen.zenscript.ide.host.IDEPropertyDirectory;
23 25
 import org.openzen.zenscript.ide.host.IDESourceFile;
26
+import org.openzen.zenscript.ide.host.IDETarget;
24 27
 import org.openzen.zenscript.ide.ui.IDEDockWindow;
25 28
 import org.openzen.zenscript.ide.ui.IDEWindow;
26 29
 import org.openzen.zenscript.ide.ui.view.aspectbar.AspectBarView;
@@ -38,11 +41,14 @@ public final class WindowView extends DSideLayout {
38 41
 	public final LiveString status = new SimpleLiveString("IDE initialized");
39 42
 	private final ProjectBrowser projectBrowser;
40 43
 	
41
-	public WindowView(IDEWindow window, DevelopmentHost host, IDEPropertyDirectory settings) {
44
+	private final LiveObject<IDECompileState> compileState;
45
+	
46
+	public WindowView(IDEWindow window, DevelopmentHost host, IDEPropertyDirectory settings, LiveObject<IDECompileState> compileState) {
42 47
 		super(DStyleClass.inline(
43 48
 				new DStylesheetBuilder().color("backgroundColor", 0xFFEEEEEE).build()),
44 49
 				DEmptyView.INSTANCE);
45 50
 		this.window = window;
51
+		this.compileState = compileState;
46 52
 		
47 53
 		projectBrowser = new ProjectBrowser(window, host, settings.getSubdirectory("projectBrowserExpansionState"));
48 54
 		
@@ -69,7 +75,7 @@ public final class WindowView extends DSideLayout {
69 75
 	private class DockWindowListener implements IDEDockWindow.Listener {
70 76
 		@Override
71 77
 		public void onOpen(IDESourceFile sourceFile) {
72
-			SourceEditor editor = new SourceEditor(DStyleClass.EMPTY, window, sourceFile);
78
+			SourceEditor editor = new SourceEditor(DStyleClass.EMPTY, window, sourceFile, compileState);
73 79
 			DScalableSize size = new DScalableSize(new DDpDimension(280), new DDpDimension(280));
74 80
 			TabbedViewComponent tab = new TabbedViewComponent(
75 81
 					sourceFile.getName(),

+ 71
- 10
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java View File

@@ -15,6 +15,7 @@ import live.ImmutableLiveString;
15 15
 import live.InverseLiveBool;
16 16
 import live.LiveObject;
17 17
 import live.LiveBool;
18
+import live.LiveList;
18 19
 import live.MutableLiveObject;
19 20
 import live.SimpleLiveBool;
20 21
 
@@ -43,6 +44,8 @@ import org.openzen.drawablegui.draw.DDrawnRectangle;
43 44
 import org.openzen.drawablegui.draw.DDrawnShape;
44 45
 import org.openzen.drawablegui.draw.DDrawnText;
45 46
 import org.openzen.drawablegui.style.DStyleClass;
47
+import org.openzen.zenscript.ide.host.IDECodeError;
48
+import org.openzen.zenscript.ide.host.IDECompileState;
46 49
 import org.openzen.zenscript.ide.ui.icons.SaveIcon;
47 50
 import org.openzen.zenscript.ide.ui.icons.ShadedCodeIcon;
48 51
 import org.openzen.zenscript.ide.ui.icons.ShadedSaveIcon;
@@ -85,6 +88,9 @@ public class SourceEditor implements DComponent {
85 88
 	private final IDEWindow window;
86 89
 	private final IDEAspectToolbar editToolbar = new IDEAspectToolbar(0, ShadedCodeIcon.BLUE, "Edit", "Source code editor");
87 90
 	
91
+	private final LiveList<IDECodeError> errors;
92
+	private ListenerHandle<LiveList.Listener<IDECodeError>> errorListListener = null;
93
+	
88 94
 	private final LiveBool updated;
89 95
 	
90 96
 	private DDrawnRectangle background;
@@ -96,10 +102,9 @@ public class SourceEditor implements DComponent {
96 102
 	private final List<DDrawnRectangle> multiLineSelection = new ArrayList<>();
97 103
 	private final List<DDrawnText> lineNumbers = new ArrayList<>();
98 104
 	private final List<List<DDrawnText>> drawnTokens = new ArrayList<>();
105
+	private final List<DDrawnShape> errorLines = new ArrayList<>();
99 106
 	
100
-	//private DDrawnShape test;
101
-	
102
-	public SourceEditor(DStyleClass styleClass, IDEWindow window, IDESourceFile sourceFile) {
107
+	public SourceEditor(DStyleClass styleClass, IDEWindow window, IDESourceFile sourceFile, LiveObject<IDECompileState> compileState) {
103 108
 		this.styleClass = styleClass;
104 109
 		this.window = window;
105 110
 		this.sourceFile = sourceFile;
@@ -121,6 +126,10 @@ public class SourceEditor implements DComponent {
121 126
 		} catch (IOException ex) {
122 127
 			ex.printStackTrace();
123 128
 		}
129
+		
130
+		errors = compileState.getValue().getErrors(sourceFile);
131
+		errors.addListener(new ErrorListListener());
132
+		System.out.println("Code errors: " + errors.getLength());
124 133
 	}
125 134
 	
126 135
 	public LiveBool isUpdated() {
@@ -132,6 +141,9 @@ public class SourceEditor implements DComponent {
132 141
 		if (blinkTimer != null)
133 142
 			blinkTimer.close();
134 143
 		
144
+		if (errorListListener != null)
145
+			errorListListener.close();
146
+		
135 147
 		tokenListener.close();
136 148
 	}
137 149
 
@@ -196,11 +208,6 @@ public class SourceEditor implements DComponent {
196 208
 			cursor = null;
197 209
 		}
198 210
 		
199
-		/*if (test != null) {
200
-			test.close();
201
-			test = null;
202
-		}*/
203
-		
204 211
 		if (blinkTimer != null)
205 212
 			blinkTimer.close();
206 213
 		
@@ -213,6 +220,14 @@ public class SourceEditor implements DComponent {
213 220
 				token.close();
214 221
 		drawnTokens.clear();
215 222
 		
223
+		if (errorListListener != null) {
224
+			errorListListener.close();
225
+			errorListListener = null;
226
+		}
227
+		for (DDrawnShape shape : errorLines)
228
+			shape.close();
229
+		errorLines.clear();
230
+		
216 231
 		clearMultilineSelection();
217 232
 	}
218 233
 	
@@ -264,7 +279,15 @@ public class SourceEditor implements DComponent {
264 279
 					bounds.y + style.selectionPaddingTop + i * fullLineHeight + fontMetrics.getAscent());
265 280
 		}
266 281
 		
267
-		//test = surface.strokePath(z + 4, new WavyLine(bounds.x + 50, bounds.y + 50, 100, surface.getContext().dp(2), surface.getContext().dp(3)), DTransform2D.IDENTITY, IDEStyling.ERROR_RED, surface.getScale());
282
+		for (DDrawnShape shape : errorLines)
283
+			shape.close();
284
+		errorLines.clear();
285
+		if (errorListListener != null)
286
+			errorListListener.close();
287
+		
288
+		for (IDECodeError error : errors)
289
+			errorLines.add(createShapeForError(error));
290
+		errorListListener = errors.addListener(new ErrorListListener());
268 291
 		
269 292
 		layoutLines(0);
270 293
 	}
@@ -767,7 +790,7 @@ public class SourceEditor implements DComponent {
767 790
 		
768 791
 		DSizing sizing = new DSizing(width + lineBarWidth, fullLineHeight * tokens.getLineCount());
769 792
 		this.sizing.setValue(sizing);
770
-		System.out.println("Preferred size: " + sizing.preferredWidth + " x " + sizing.preferredHeight);
793
+		//System.out.println("Preferred size: " + sizing.preferredWidth + " x " + sizing.preferredHeight);
771 794
 	}
772 795
 	
773 796
 	private class TokenListener implements TokenModel.Listener {
@@ -934,4 +957,42 @@ public class SourceEditor implements DComponent {
934 957
 			}
935 958
 		}
936 959
 	}
960
+	
961
+	private DDrawnShape createShapeForError(IDECodeError error) {
962
+		SourcePosition fromPosition = new SourcePosition(tokens, error.position.fromLine - 1, error.position.fromLineOffset);
963
+		int fromX = getX(fromPosition);
964
+		int fromY = getY(fromPosition);
965
+		
966
+		SourcePosition toPosition = new SourcePosition(tokens, error.position.toLine - 1, error.position.toLineOffset);
967
+		int toX = getX(toPosition);
968
+		int toY = getY(toPosition);
969
+		
970
+		int length = Math.max((int)(10 * context.getScale()), toX - fromX);
971
+		
972
+		int height = (int)(2 * context.getScale());
973
+		int offset = fullLineHeight - height - (int)(1.5 * context.getScale());
974
+		WavyLine line = new WavyLine(fromX, fromY + offset, length, height, 3 * context.getScale());
975
+		return context.strokePath(
976
+				context.z + 4,
977
+				line, DTransform2D.IDENTITY, style.errorWavyLineColor, context.getScale());
978
+	}
979
+	
980
+	private class ErrorListListener implements LiveList.Listener<IDECodeError> {
981
+
982
+		@Override
983
+		public void onInserted(int index, IDECodeError value) {
984
+			errorLines.add(index, createShapeForError(value));
985
+		}
986
+
987
+		@Override
988
+		public void onChanged(int index, IDECodeError oldValue, IDECodeError newValue) {
989
+			errorLines.get(index).close();
990
+			errorLines.set(index, createShapeForError(newValue));
991
+		}
992
+
993
+		@Override
994
+		public void onRemoved(int index, IDECodeError oldValue) {
995
+			errorLines.remove(index).close();
996
+		}
997
+	}
937 998
 }

+ 4
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditorStyle.java View File

@@ -31,6 +31,8 @@ public class SourceEditorStyle {
31 31
 	public final int cursorWidth;
32 32
 	public final int cursorColor;
33 33
 	
34
+	public final int errorWavyLineColor;
35
+	
34 36
 	public SourceEditorStyle(DStyleDefinition style) {
35 37
 		this.backgroundColor = style.getColor("backgroundColor", 0xFFFFFFFF);
36 38
 		this.lineBarBackgroundColor = style.getColor("lineBarBackgroundColor", 0xFFE9E8E2);
@@ -50,5 +52,7 @@ public class SourceEditorStyle {
50 52
 		
51 53
 		this.cursorWidth = style.getDimension("cursorWidth", new DDpDimension(1));
52 54
 		this.cursorColor = style.getColor("cursorColor", 0xFF000000);
55
+		
56
+		this.errorWavyLineColor = style.getColor("errorWavyLineColor", 0xFFFF0000);
53 57
 	}
54 58
 }

+ 76
- 41
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java View File

@@ -155,6 +155,7 @@ public class JavaNativeModule {
155 155
 		JavaClass jcls = JavaClass.fromInternalName(getInternalName(cls), JavaClass.Kind.CLASS);
156 156
 		compiled.setClassInfo(definition, jcls);
157 157
 		StoredType thisType = registry.getForMyDefinition(definition).stored();
158
+		TypeVariableContext context = new TypeVariableContext();
158 159
 		
159 160
 		for (Field field : cls.getDeclaredFields()) {
160 161
 			if (!field.isAnnotationPresent(ZenCodeGlobals.Global.class))
@@ -163,7 +164,7 @@ public class JavaNativeModule {
163 164
 				continue;
164 165
 			
165 166
 			ZenCodeGlobals.Global global = field.getAnnotation(ZenCodeGlobals.Global.class);
166
-			StoredType type = loadStoredType(field.getAnnotatedType());
167
+			StoredType type = loadStoredType(context, field.getAnnotatedType());
167 168
 			String name = global.value().isEmpty() ? field.getName() : global.value();
168 169
 			FieldMember fieldMember = new FieldMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, name, thisType, type, registry, Modifiers.PUBLIC, 0, null);
169 170
 			definition.addMember(fieldMember);
@@ -181,7 +182,7 @@ public class JavaNativeModule {
181 182
 			
182 183
 			ZenCodeGlobals.Global global = method.getAnnotation(ZenCodeGlobals.Global.class);
183 184
 			String name = global.value().isEmpty() ? method.getName() : global.value();
184
-			MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, name, getHeader(method), null);
185
+			MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, name, getHeader(context, method), null);
185 186
 			definition.addMember(methodMember);
186 187
 			
187 188
 			boolean isGenericResult = methodMember.header.getReturnType().isGeneric();
@@ -200,7 +201,8 @@ public class JavaNativeModule {
200 201
 		HighLevelDefinition definition = addClass(method.getDeclaringClass());
201 202
 		JavaClass jcls = JavaClass.fromInternalName(getInternalName(method.getDeclaringClass()), JavaClass.Kind.CLASS);
202 203
 		
203
-		MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, method.getName(), getHeader(method), null);
204
+		TypeVariableContext context = new TypeVariableContext();
205
+		MethodMember methodMember = new MethodMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC | Modifiers.STATIC, method.getName(), getHeader(context, method), null);
204 206
 		definition.addMember(methodMember);
205 207
 		boolean isGenericResult = methodMember.header.getReturnType().isGeneric();
206 208
 		compiled.setMethodInfo(methodMember, new JavaMethod(jcls, JavaMethod.Kind.STATIC, method.getName(), false, getMethodDescriptor(method), method.getModifiers(), isGenericResult));
@@ -242,16 +244,18 @@ public class JavaNativeModule {
242 244
 		ZSPackage classPkg = getPackage(className);
243 245
 		className = className.contains(".") ? className.substring(className.lastIndexOf('.') + 1) : className;
244 246
 		
247
+		TypeVariableContext context = new TypeVariableContext();
245 248
 		TypeVariable<Class<T>>[] javaTypeParameters = cls.getTypeParameters();
246 249
 		TypeParameter[] typeParameters = new TypeParameter[cls.getTypeParameters().length];
247 250
 		for (int i = 0; i < javaTypeParameters.length; i++) {
248 251
 			TypeVariable<Class<T>> typeVariable = javaTypeParameters[i];
249 252
 			TypeParameter parameter = new TypeParameter(CodePosition.NATIVE, typeVariable.getName());
250 253
 			for (AnnotatedType bound : typeVariable.getAnnotatedBounds()) {
251
-				TypeID type = loadType(bound);
254
+				TypeID type = loadType(context, bound);
252 255
 				parameter.addBound(new ParameterTypeBound(CodePosition.NATIVE, type));
253 256
 			}
254 257
 			typeParameters[i] = parameter;
258
+			context.put(typeVariable, parameter);
255 259
 		}
256 260
 		
257 261
 		HighLevelDefinition definition;
@@ -270,14 +274,14 @@ public class JavaNativeModule {
270 274
 			definition = new ClassDefinition(CodePosition.NATIVE, module, classPkg, className, Modifiers.PUBLIC);
271 275
 			javaClass = JavaClass.fromInternalName(internalName, JavaClass.Kind.CLASS);
272 276
 			
273
-			if (cls.getSuperclass() != null && shouldLoadClass(cls.getSuperclass())) {
274
-				definition.setSuperType(loadType(cls.getSuperclass(), false, false));
277
+			if (cls.getAnnotatedSuperclass() != null && shouldLoadType(cls.getAnnotatedSuperclass().getType())) {
278
+				definition.setSuperType(loadType(context, cls.getAnnotatedSuperclass()));
275 279
 			}
276 280
 		}
277 281
 		
278
-		for (Class<?> iface : cls.getInterfaces()) {
279
-			if (shouldLoadClass(iface)) {
280
-				TypeID type = loadType(iface, false, false);
282
+		for (AnnotatedType iface : cls.getAnnotatedInterfaces()) {
283
+			if (shouldLoadType(iface.getType())) {
284
+				TypeID type = loadType(context, iface);
281 285
 				ImplementationMember member = new ImplementationMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC, type);
282 286
 				definition.members.add(member);
283 287
 				compiled.setImplementationInfo(member, new JavaImplementation(true, javaClass));
@@ -298,7 +302,7 @@ public class JavaNativeModule {
298 302
 			
299 303
 			final String fieldName = annotation.value().isEmpty() ? field.getName() : annotation.value();
300 304
 			
301
-			StoredType fieldType = loadStoredType(field.getAnnotatedType());
305
+			StoredType fieldType = loadStoredType(context, field.getAnnotatedType());
302 306
 			FieldMember member = new FieldMember(CodePosition.NATIVE, definition, Modifiers.PUBLIC, fieldName, thisType, fieldType, registry, 0, 0, null);
303 307
 			definition.addMember(member);
304 308
 			compiled.setFieldInfo(member, new JavaField(javaClass, field.getName(), getDescriptor(field.getType())));
@@ -308,7 +312,7 @@ public class JavaNativeModule {
308 312
 		for (java.lang.reflect.Constructor constructor : cls.getConstructors()) {
309 313
 			ZenCodeType.Constructor constructorAnnotation = (ZenCodeType.Constructor) constructor.getAnnotation(ZenCodeType.Constructor.class);
310 314
 			if (constructorAnnotation != null) {
311
-				ConstructorMember member = asConstructor(definition, constructor);
315
+				ConstructorMember member = asConstructor(context, definition, constructor);
312 316
 				definition.addMember(member);
313 317
 				compiled.setMethodInfo(member, getMethod(javaClass, constructor));
314 318
 				hasConstructor = true;
@@ -324,7 +328,7 @@ public class JavaNativeModule {
324 328
 		for (Method method : cls.getDeclaredMethods()) {
325 329
 			ZenCodeType.Method methodAnnotation = method.getAnnotation(ZenCodeType.Method.class);
326 330
 			if (methodAnnotation != null) {
327
-				MethodMember member = asMethod(definition, method, methodAnnotation);
331
+				MethodMember member = asMethod(context, definition, method, methodAnnotation);
328 332
 				definition.addMember(member);
329 333
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
330 334
 				continue;
@@ -332,28 +336,28 @@ public class JavaNativeModule {
332 336
 			
333 337
 			ZenCodeType.Getter getter = method.getAnnotation(ZenCodeType.Getter.class);
334 338
 			if (getter != null) {
335
-				GetterMember member = asGetter(definition, method, getter);
339
+				GetterMember member = asGetter(context, definition, method, getter);
336 340
 				definition.addMember(member);
337 341
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.getType()));
338 342
 			}
339 343
 			
340 344
 			ZenCodeType.Setter setter = method.getAnnotation(ZenCodeType.Setter.class);
341 345
 			if (setter != null) {
342
-				SetterMember member = asSetter(definition, method, setter);
346
+				SetterMember member = asSetter(context, definition, method, setter);
343 347
 				definition.addMember(member);
344 348
 				compiled.setMethodInfo(member, getMethod(javaClass, method, BasicTypeID.VOID.stored));
345 349
 			}
346 350
 			
347 351
 			ZenCodeType.Operator operator = method.getAnnotation(ZenCodeType.Operator.class);
348 352
 			if (operator != null) {
349
-				OperatorMember member = asOperator(definition, method, operator);
353
+				OperatorMember member = asOperator(context, definition, method, operator);
350 354
 				definition.addMember(member);
351 355
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.header.getReturnType()));
352 356
 			}
353 357
 			
354 358
 			ZenCodeType.Caster caster = method.getAnnotation(ZenCodeType.Caster.class);
355 359
 			if (caster != null) {
356
-				CasterMember member = asCaster(definition, method, caster);
360
+				CasterMember member = asCaster(context, definition, method, caster);
357 361
 				definition.addMember(member);
358 362
 				compiled.setMethodInfo(member, getMethod(javaClass, method, member.toType));
359 363
 			}
@@ -368,6 +372,15 @@ public class JavaNativeModule {
368 372
 		return definition;
369 373
 	}
370 374
 	
375
+	private boolean shouldLoadType(Type type) {
376
+		if (type instanceof Class)
377
+			return shouldLoadClass((Class<?>)type);
378
+		if (type instanceof ParameterizedType)
379
+			return shouldLoadType(((ParameterizedType)type).getRawType());
380
+		
381
+		return false;
382
+	}
383
+	
371 384
 	private boolean shouldLoadClass(Class<?> cls) {
372 385
 		return isInBasePackage(cls.getName());
373 386
 	}
@@ -390,8 +403,8 @@ public class JavaNativeModule {
390 403
 		return name;
391 404
 	}
392 405
 	
393
-	private ConstructorMember asConstructor(HighLevelDefinition definition, java.lang.reflect.Constructor method) {
394
-		FunctionHeader header = getHeader(method);
406
+	private ConstructorMember asConstructor(TypeVariableContext context, HighLevelDefinition definition, java.lang.reflect.Constructor method) {
407
+		FunctionHeader header = getHeader(context, method);
395 408
 		return new ConstructorMember(
396 409
 				CodePosition.NATIVE,
397 410
 				definition,
@@ -400,9 +413,9 @@ public class JavaNativeModule {
400 413
 				null);
401 414
 	}
402 415
 	
403
-	private MethodMember asMethod(HighLevelDefinition definition, Method method, ZenCodeType.Method annotation) {
416
+	private MethodMember asMethod(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Method annotation) {
404 417
 		String name = annotation != null && !annotation.value().isEmpty() ? annotation.value() : method.getName();
405
-		FunctionHeader header = getHeader(method);
418
+		FunctionHeader header = getHeader(context, method);
406 419
 		return new MethodMember(
407 420
 				CodePosition.NATIVE,
408 421
 				definition,
@@ -412,8 +425,8 @@ public class JavaNativeModule {
412 425
 				null);
413 426
 	}
414 427
 	
415
-	private OperatorMember asOperator(HighLevelDefinition definition, Method method, ZenCodeType.Operator annotation) {
416
-		FunctionHeader header = getHeader(method);
428
+	private OperatorMember asOperator(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Operator annotation) {
429
+		FunctionHeader header = getHeader(context, method);
417 430
 		if (isStatic(method.getModifiers()))
418 431
 			throw new IllegalArgumentException("operator method cannot be static");
419 432
 		
@@ -429,8 +442,8 @@ public class JavaNativeModule {
429 442
 				null);
430 443
 	}
431 444
 	
432
-	private GetterMember asGetter(HighLevelDefinition definition, Method method, ZenCodeType.Getter annotation) {
433
-		StoredType type = loadStoredType(method.getAnnotatedReturnType());
445
+	private GetterMember asGetter(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Getter annotation) {
446
+		StoredType type = loadStoredType(context, method.getAnnotatedReturnType());
434 447
 		String name = null;
435 448
 		if (annotation != null && !annotation.value().isEmpty())
436 449
 			name = annotation.value();
@@ -440,11 +453,11 @@ public class JavaNativeModule {
440 453
 		return new GetterMember(CodePosition.NATIVE, definition, getMethodModifiers(method), name, type, null);
441 454
 	}
442 455
 	
443
-	private SetterMember asSetter(HighLevelDefinition definition, Method method, ZenCodeType.Setter annotation) {
456
+	private SetterMember asSetter(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Setter annotation) {
444 457
 		if (method.getParameterCount() != 1)
445 458
 			throw new IllegalArgumentException("Illegal setter: must have exactly 1 parameter");
446 459
 		
447
-		StoredType type = loadStoredType(method.getAnnotatedParameterTypes()[0]);
460
+		StoredType type = loadStoredType(context, method.getAnnotatedParameterTypes()[0]);
448 461
 		String name = null;
449 462
 		if (annotation != null && !annotation.value().isEmpty())
450 463
 			name = annotation.value();
@@ -454,26 +467,28 @@ public class JavaNativeModule {
454 467
 		return new SetterMember(CodePosition.NATIVE, definition, getMethodModifiers(method), name, type, null);
455 468
 	}
456 469
 	
457
-	private CasterMember asCaster(HighLevelDefinition definition, Method method, ZenCodeType.Caster annotation) {
470
+	private CasterMember asCaster(TypeVariableContext context, HighLevelDefinition definition, Method method, ZenCodeType.Caster annotation) {
458 471
 		boolean implicit = annotation != null && annotation.implicit();
459 472
 		int modifiers = Modifiers.PUBLIC;
460 473
 		if (implicit)
461 474
 			modifiers |= Modifiers.IMPLICIT;
462 475
 		
463
-		StoredType toType = loadStoredType(method.getAnnotatedReturnType());
476
+		StoredType toType = loadStoredType(context, method.getAnnotatedReturnType());
464 477
 		return new CasterMember(CodePosition.NATIVE, definition, modifiers, toType, null);
465 478
 	}
466 479
 	
467
-	private FunctionHeader getHeader(java.lang.reflect.Constructor constructor) {
480
+	private FunctionHeader getHeader(TypeVariableContext context, java.lang.reflect.Constructor constructor) {
468 481
 		return getHeader(
482
+				context,
469 483
 				null,
470 484
 				constructor.getAnnotatedParameterTypes(),
471 485
 				constructor.getTypeParameters(),
472 486
 				constructor.getAnnotatedExceptionTypes());
473 487
 	}
474 488
 	
475
-	private FunctionHeader getHeader(Method method) {
489
+	private FunctionHeader getHeader(TypeVariableContext context, Method method) {
476 490
 		return getHeader(
491
+				context,
477 492
 				method.getAnnotatedReturnType(),
478 493
 				method.getAnnotatedParameterTypes(),
479 494
 				method.getTypeParameters(),
@@ -481,39 +496,41 @@ public class JavaNativeModule {
481 496
 	}
482 497
 	
483 498
 	private FunctionHeader getHeader(
499
+			TypeVariableContext context,
484 500
 			AnnotatedType javaReturnType,
485 501
 			AnnotatedType[] parameterTypes,
486 502
 			TypeVariable<Method>[] javaTypeParameters,
487 503
 			AnnotatedType[] exceptionTypes) {
488
-		StoredType returnType = javaReturnType == null ? BasicTypeID.VOID.stored : loadStoredType(javaReturnType);
504
+		StoredType returnType = javaReturnType == null ? BasicTypeID.VOID.stored : loadStoredType(context, javaReturnType);
489 505
 		
490 506
 		FunctionParameter[] parameters = new FunctionParameter[parameterTypes.length];
491 507
 		for (int i = 0; i < parameters.length; i++) {
492
-			parameters[i] = new FunctionParameter(loadStoredType(parameterTypes[i]));
508
+			parameters[i] = new FunctionParameter(loadStoredType(context, parameterTypes[i]));
493 509
 		}
494 510
 		
495 511
 		TypeParameter[] typeParameters = new TypeParameter[javaTypeParameters.length];
496 512
 		for (int i = 0; i < javaTypeParameters.length; i++) {
497 513
 			TypeVariable<Method> javaTypeParameter = javaTypeParameters[i];
498 514
 			typeParameters[i] = new TypeParameter(CodePosition.UNKNOWN, javaTypeParameter.getName());
515
+			context.put(javaTypeParameter, typeParameters[i]);
499 516
 			
500 517
 			for (AnnotatedType bound : javaTypeParameter.getAnnotatedBounds())
501
-				typeParameters[i].addBound(new ParameterTypeBound(CodePosition.NATIVE, loadType(bound)));
518
+				typeParameters[i].addBound(new ParameterTypeBound(CodePosition.NATIVE, loadType(context, bound)));
502 519
 		}
503 520
 		
504 521
 		if (exceptionTypes.length > 1)
505 522
 			throw new IllegalArgumentException("A method can only throw a single exception type!");
506 523
 		
507
-		StoredType thrownType = exceptionTypes.length == 0 ? null : loadStoredType(exceptionTypes[0]);
524
+		StoredType thrownType = exceptionTypes.length == 0 ? null : loadStoredType(context, exceptionTypes[0]);
508 525
 		return new FunctionHeader(typeParameters, returnType, thrownType, AutoStorageTag.INSTANCE, parameters);
509 526
 	}
510 527
 	
511
-	private StoredType loadStoredType(AnnotatedType annotatedType) {
512
-		TypeID baseType = loadType(annotatedType);
528
+	private StoredType loadStoredType(TypeVariableContext context, AnnotatedType annotatedType) {
529
+		TypeID baseType = loadType(context, annotatedType);
513 530
 		return baseType.stored();
514 531
 	}
515 532
 	
516
-	private TypeID loadType(AnnotatedType annotatedType) {
533
+	private TypeID loadType(TypeVariableContext context, AnnotatedType annotatedType) {
517 534
 		if (annotatedType.isAnnotationPresent(ZenCodeType.USize.class))
518 535
 			return BasicTypeID.USIZE;
519 536
 		else if (annotatedType.isAnnotationPresent(ZenCodeType.NullableUSize.class))
@@ -523,10 +540,10 @@ public class JavaNativeModule {
523 540
 		boolean unsigned = annotatedType.isAnnotationPresent(ZenCodeType.Unsigned.class);
524 541
 		
525 542
 		Type type = annotatedType.getType();
526
-		return loadType(type, nullable, unsigned);
543
+		return loadType(context, type, nullable, unsigned);
527 544
 	}
528 545
 	
529
-	private TypeID loadType(Type type, boolean nullable, boolean unsigned) {
546
+	private TypeID loadType(TypeVariableContext context, Type type, boolean nullable, boolean unsigned) {
530 547
 		if (type instanceof Class) {
531 548
 			Class<?> classType = (Class<?>) type;
532 549
 			if (unsigned) {
@@ -535,7 +552,7 @@ public class JavaNativeModule {
535 552
 				else
536 553
 					throw new IllegalArgumentException("This class cannot be used as unsigned: " + classType);
537 554
 			} else if (classType.isArray()) {
538
-				return registry.getArray(loadType(classType.getComponentType(), false, false).stored(), 1);
555
+				return registry.getArray(loadType(context, classType.getComponentType(), false, false).stored(), 1);
539 556
 			}
540 557
 			
541 558
 			if (typeByClass.containsKey(classType))
@@ -551,9 +568,12 @@ public class JavaNativeModule {
551 568
 			Type[] parameters = parameterizedType.getActualTypeArguments();
552 569
 			StoredType[] codeParameters = new StoredType[parameters.length];
553 570
 			for (int i = 0; i < parameters.length; i++)
554
-				codeParameters[i] = loadType(parameters[i], false, false).stored();
571
+				codeParameters[i] = loadType(context, parameters[i], false, false).stored();
555 572
 			
556 573
 			return registry.getForDefinition(definition, codeParameters);
574
+		} else if (type instanceof TypeVariable) {
575
+			TypeVariable variable = (TypeVariable)type;
576
+			return registry.getGeneric(context.get(variable));
557 577
 		} else {
558 578
 			throw new IllegalArgumentException("Could not analyze type: " + type);
559 579
 		}
@@ -621,4 +641,19 @@ public class JavaNativeModule {
621 641
 		
622 642
 		return new JavaMethod(cls, kind, method.getName(), false, getMethodDescriptor(method), method.getModifiers(), result.isGeneric());
623 643
 	}
644
+	
645
+	private static class TypeVariableContext {
646
+		private final Map<TypeVariable, TypeParameter> typeVariables = new HashMap<>();
647
+		
648
+		public void put(TypeVariable variable, TypeParameter parameter) {
649
+			typeVariables.put(variable, parameter);
650
+		}
651
+		
652
+		public TypeParameter get(TypeVariable variable) {
653
+			if (!typeVariables.containsKey(variable))
654
+				throw new IllegalStateException("Could not find type variable " + variable.getName());
655
+			
656
+			return typeVariables.get(variable);
657
+		}
658
+	}
624 659
 }

+ 10
- 6
ModuleSerializer/src/main/java/org/openzen/zenscript/moduleserializer/Main.java View File

@@ -9,10 +9,12 @@ import java.io.File;
9 9
 import java.io.IOException;
10 10
 import java.nio.file.Files;
11 11
 import java.util.Collections;
12
-import org.openzen.zenscript.compiler.CompilationUnit;
13
-import org.openzen.zenscript.compiler.SemanticModule;
12
+import org.openzen.zenscript.codemodel.SemanticModule;
13
+import org.openzen.zenscript.codemodel.definition.ZSPackage;
14
+import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
14 15
 import org.openzen.zenscript.constructor.ModuleLoader;
15
-import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
16
+import org.openzen.zenscript.constructor.module.SourceModuleReference;
17
+import org.openzen.zenscript.constructor.module.directory.DirectorySourceModule;
16 18
 
17 19
 /**
18 20
  *
@@ -20,9 +22,11 @@ import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
20 22
  */
21 23
 public class Main {
22 24
 	public static void main(String[] args) throws IOException {
23
-		CompilationUnit compilationUnit = new CompilationUnit();
24
-		ModuleLoader loader = new ModuleLoader(compilationUnit, exception -> exception.printStackTrace());
25
-		loader.register("stdlib", new DirectoryModuleReference("stdlib", new File("../../StdLibs/stdlib"), true));
25
+		ZSPackage root = ZSPackage.createRoot();
26
+		ZSPackage stdlib = new ZSPackage(root, "stdlib");
27
+		GlobalTypeRegistry registry = new GlobalTypeRegistry(stdlib);
28
+		ModuleLoader loader = new ModuleLoader(registry, exception -> exception.printStackTrace());
29
+		loader.register("stdlib", new SourceModuleReference(new DirectorySourceModule("stdlib", new File("../../StdLibs/stdlib"), true), true));
26 30
 		
27 31
 		SemanticModule module = loader.getModule("stdlib");
28 32
 		ModuleSerializer serializer = new ModuleSerializer(new SerializationOptions(

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

@@ -17,19 +17,17 @@ import org.openzen.zencode.shared.SourceFile;
17 17
 public class CountingCharReader implements CharReader {
18 18
 	private final CharReader reader;
19 19
 	private final SourceFile file;
20
-	private final int tabSize;
21 20
 	
22 21
 	private int line;
23 22
 	private int lineOffset;
24 23
 	
25
-	public CountingCharReader(CharReader reader, SourceFile file, int tabSize)
24
+	public CountingCharReader(CharReader reader, SourceFile file)
26 25
 	{
27 26
 		this.reader = reader;
28 27
 		this.file = file;
29
-		this.tabSize = tabSize;
30 28
 		
31 29
 		line = 1;
32
-		lineOffset = 1;
30
+		lineOffset = 0;
33 31
 	}
34 32
 	
35 33
 	public CodePosition getPosition() {
@@ -51,9 +49,7 @@ public class CountingCharReader implements CharReader {
51 49
 		
52 50
 		if (ch == '\n') {
53 51
 			line++;
54
-			lineOffset = 1;
55
-		} else if (ch == '\t') {
56
-			lineOffset += tabSize;
52
+			lineOffset = 0;
57 53
 		} else {
58 54
 			lineOffset++;
59 55
 		}

+ 14
- 3
Parser/src/main/java/org/openzen/zenscript/lexer/LLParserTokenStream.java View File

@@ -59,7 +59,7 @@ public class LLParserTokenStream<TT extends TokenType, T extends Token<TT>> exte
59 59
             if (marks.isEmpty()) {
60 60
                 tokenMemoryOffset++;
61 61
             } else {
62
-                tokenMemory.add(new PositionedToken(getPosition(), result));
62
+                tokenMemory.add(new PositionedToken(getPosition(), getPositionBeforeWhitespace(), result));
63 63
             }
64 64
             tokenMemoryCurrent++;
65 65
 			return result;
@@ -75,6 +75,15 @@ public class LLParserTokenStream<TT extends TokenType, T extends Token<TT>> exte
75 75
         }
76 76
 	}
77 77
 	
78
+	@Override
79
+	public CodePosition getPositionBeforeWhitespace() {
80
+		if (tokenMemoryCurrent < tokenMemoryOffset + tokenMemory.size()) {
81
+            return tokenMemory.get((tokenMemoryCurrent) - tokenMemoryOffset).positionBeforeWhitespace;
82
+        } else {
83
+            return super.getPositionBeforeWhitespace();
84
+        }
85
+	}
86
+	
78 87
 	public boolean isNext(TT type) {
79 88
 		return peek().getType() == type;
80 89
 	}
@@ -92,7 +101,7 @@ public class LLParserTokenStream<TT extends TokenType, T extends Token<TT>> exte
92 101
         if (t.getType() == type) {
93 102
             return next();
94 103
         } else {
95
-			throw new ParseException(getPosition(), error);
104
+			throw new ParseException(getPosition().withLength(t.getContent().length()), error);
96 105
         }
97 106
     }
98 107
 	
@@ -113,10 +122,12 @@ public class LLParserTokenStream<TT extends TokenType, T extends Token<TT>> exte
113 122
 	
114 123
 	private class PositionedToken {
115 124
 		public final CodePosition position;
125
+		public final CodePosition positionBeforeWhitespace;
116 126
 		public final T token;
117 127
 		
118
-		public PositionedToken(CodePosition position, T token) {
128
+		public PositionedToken(CodePosition position, CodePosition positionBeforeWhitespace, T token) {
119 129
 			this.position = position;
130
+			this.positionBeforeWhitespace = positionBeforeWhitespace;
120 131
 			this.token = token;
121 132
 		}
122 133
 	}

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

@@ -42,7 +42,7 @@ public class TokenParser<T extends Token<TT>, TT extends TokenType> implements T
42 42
 		if (eof.isWhitespace()) // important for the advance() method
43 43
 			throw new IllegalArgumentException("EOF cannot be whitespace");
44 44
 		
45
-        this.reader = new CountingCharReader(reader, file, 4);
45
+        this.reader = new CountingCharReader(reader, file);
46 46
         this.dfa = dfa;
47 47
 		this.eof = eof;
48 48
 		this.invalid = invalid;

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

@@ -15,6 +15,7 @@ public class WhitespaceFilteringParser<TT extends TokenType, T extends Token<TT>
15 15
 	private final TokenStream<TT, T> stream;
16 16
 	private T next;
17 17
 	private CodePosition position;
18
+	private CodePosition positionBeforeWhitespace;
18 19
 	private String whitespace;
19 20
 	
20 21
 	public WhitespaceFilteringParser(TokenStream<TT, T> stream) throws ParseException {
@@ -64,6 +65,10 @@ public class WhitespaceFilteringParser<TT extends TokenType, T extends Token<TT>
64 65
 	public CodePosition getPosition() {
65 66
 		return position;
66 67
 	}
68
+	
69
+	public CodePosition getPositionBeforeWhitespace() {
70
+		return positionBeforeWhitespace;
71
+	}
67 72
 
68 73
 	@Override
69 74
 	public TT getEOF() {
@@ -73,6 +78,7 @@ public class WhitespaceFilteringParser<TT extends TokenType, T extends Token<TT>
73 78
 	private void advance() throws ParseException {
74 79
 		whitespace = "";
75 80
 		position = stream.getPosition();
81
+		positionBeforeWhitespace = position;
76 82
 		next = stream.next();
77 83
 		while (next.getType().isWhitespace()) {
78 84
 			whitespace += next.getContent();

+ 7
- 6
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java View File

@@ -370,9 +370,9 @@ public abstract class ParsedExpression {
370 370
 				ZSToken indexString = parser.optional(T_IDENTIFIER);
371 371
 				if (indexString != null) {
372 372
 					List<IParsedType> genericParameters = IParsedType.parseTypeArguments(parser);
373
-					base = new ParsedExpressionMember(position, base, indexString.content, genericParameters);
373
+					base = new ParsedExpressionMember(position.until(parser.getPositionBeforeWhitespace()), base, indexString.content, genericParameters);
374 374
 				} else if (parser.optional(T_DOLLAR) != null) {
375
-					base = new ParsedExpressionOuter(position, base);
375
+					base = new ParsedExpressionOuter(position.until(parser.getPositionBeforeWhitespace()), base);
376 376
 				} else {
377 377
 					ZSToken indexString2 = parser.optional(T_STRING_SQ);
378 378
 					if (indexString2 == null)
@@ -380,15 +380,16 @@ public abstract class ParsedExpression {
380 380
 					
381 381
 					if (indexString2 != null) {
382 382
 						// TODO: handle this properly
383
-						base = new ParsedExpressionMember(position, base, unescape(indexString2.content).orElse("INVALID STRING"), Collections.emptyList());
383
+						base = new ParsedExpressionMember(position.until(parser.getPositionBeforeWhitespace()), base, unescape(indexString2.content).orElse("INVALID STRING"), Collections.emptyList());
384 384
 					} else {
385
+						position = parser.getPosition();
385 386
 						ZSToken last = parser.next();
386
-						throw new ParseException(parser.getPosition(), "Invalid expression, last token: " + last.content);
387
+						throw new ParseException(position.until(parser.getPositionBeforeWhitespace()), "Invalid expression, last token: " + last.content);
387 388
 					}
388 389
 				}
389 390
 			} else if (parser.optional(T_DOT2) != null) {
390 391
 				ParsedExpression to = readAssignExpression(parser, options);
391
-				return new ParsedExpressionRange(position, base, to);
392
+				return new ParsedExpressionRange(position.until(parser.getPositionBeforeWhitespace()), base, to);
392 393
 			} else if (parser.optional(T_SQOPEN) != null) {
393 394
 				List<ParsedExpression> indexes = new ArrayList<>();
394 395
 				do {
@@ -443,7 +444,7 @@ public abstract class ParsedExpression {
443 444
 					name = name.substring(1);
444 445
 				
445 446
 				List<IParsedType> genericParameters = IParsedType.parseTypeArguments(parser);
446
-				return new ParsedExpressionVariable(position, name, genericParameters);
447
+				return new ParsedExpressionVariable(position.until(parser.getPositionBeforeWhitespace()), name, genericParameters);
447 448
 			}
448 449
 			case T_LOCAL_IDENTIFIER: {
449 450
 				String name = parser.next().content.substring(1);

+ 18
- 5
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionAssign.java View File

@@ -10,8 +10,11 @@ import java.util.List;
10 10
 import org.openzen.zencode.shared.CodePosition;
11 11
 import org.openzen.zencode.shared.CompileException;
12 12
 import org.openzen.zenscript.codemodel.expression.Expression;
13
+import org.openzen.zenscript.codemodel.expression.InvalidAssignExpression;
14
+import org.openzen.zenscript.codemodel.expression.InvalidExpression;
13 15
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
14 16
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
17
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
15 18
 import org.openzen.zenscript.codemodel.type.StoredType;
16 19
 
17 20
 /**
@@ -31,11 +34,21 @@ public class ParsedExpressionAssign extends ParsedExpression {
31 34
 
32 35
 	@Override
33 36
 	public IPartialExpression compile(ExpressionScope scope) throws CompileException {
34
-		IPartialExpression cLeft = left.compile(scope);
35
-		List<StoredType> resultHints = cLeft.getAssignHints();
36
-		
37
-		Expression cRight = right.compile(scope.withHints(resultHints)).eval();
38
-		return cLeft.assign(position, scope, cRight);
37
+		try {
38
+			IPartialExpression cLeft = left.compile(scope);
39
+			List<StoredType> resultHints = cLeft.getAssignHints();
40
+			Expression cRight = right.compile(scope.withHints(resultHints)).eval();
41
+			return cLeft.assign(position, scope, cRight);
42
+		} catch (CompileException ex) {
43
+			InvalidExpression invalid = new InvalidExpression(BasicTypeID.VOID.stored, ex);
44
+			Expression cRight;
45
+			try {
46
+				cRight = right.compile(scope).eval();
47
+			} catch (CompileException ex2) {
48
+				cRight = new InvalidExpression(BasicTypeID.VOID.stored, ex2);
49
+			}
50
+			return new InvalidAssignExpression(position, invalid, cRight);
51
+		}
39 52
 	}
40 53
 
41 54
 	@Override

+ 3
- 0
Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedFunctionalMember.java View File

@@ -76,6 +76,9 @@ public abstract class ParsedFunctionalMember extends ParsedDefinitionMember {
76 76
 		getCompiled().setBody(body.compile(innerScope, getCompiled().header));
77 77
 		
78 78
 		if (getCompiled().header.getReturnType().isBasic(BasicTypeID.UNDETERMINED)) {
79
+			if (getCompiled().body == null)
80
+				throw new CompileException(position, CompileExceptionCode.CANNOT_INFER_RETURN_TYPE, "Method return type could not be inferred");
81
+			
79 82
 			StoredType returnType = getCompiled().body.getReturnType();
80 83
 			if (returnType == null) {
81 84
 				throw new CompileException(position, CompileExceptionCode.CANNOT_INFER_RETURN_TYPE, "Method return type could not be inferred");

+ 6
- 3
ScriptingExample/scripts/integration.zs View File

@@ -5,6 +5,9 @@ val instance = new TestClass("Instance");
5 5
 println("Name: " + instance.name);
6 6
 instance.dump();
7 7
 
8
+var generated = instance.generate();
9
+println(generated.getValue());
10
+
8 11
 class TestOperators {
9 12
 	public (name as string) as void {
10 13
 		println("MyTestClass: " + name);
@@ -14,11 +17,11 @@ class TestOperators {
14 17
 	//	=> "key " + key;
15 18
 }
16 19
 
17
-class TestImplementation {
20
+/*class TestImplementation {
18 21
 	public implements TestInterface {
19 22
 		interfaceMethod() => "TestImplementation";
20 23
 	}
21
-}
24
+}*/
22 25
 
23 26
 val testInstance = new TestOperators();
24 27
 //testInstance("something");
@@ -32,7 +35,7 @@ printMany(objects);
32 35
 println(<test string>);
33 36
 println(<test string>.name);
34 37
 println(<test string>.interfaceMethod());
35
-println(new TestImplementation().interfaceMethod());
38
+//println(new TestImplementation().interfaceMethod());
36 39
 
37 40
 var diamond = <item:minecraft:diamond>;
38 41
 var dirt = <item:minecraft:dirt>;

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

@@ -24,6 +24,8 @@ public class Main {
24 24
 		
25 25
 		JavaNativeModule example = scriptingEngine.createNativeModule("example", "org.openzen.zenscript.scriptingexample");
26 26
 		example.addGlobals(Globals.class);
27
+		example.addClass(TestBaseInterface.class);
28
+		example.addClass(TestGenericInterface.class);
27 29
 		example.addClass(TestClass.class);
28 30
 		example.addClass(TestInterface.class);
29 31
 		scriptingEngine.registerNativeProvided(example);

+ 17
- 0
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestBaseInterface.java View File

@@ -0,0 +1,17 @@
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.scriptingexample;
7
+
8
+import org.openzen.zencode.java.ZenCodeType;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public interface TestBaseInterface<T> extends ZenCodeType {
15
+	@Method
16
+	T getValue();
17
+}

+ 5
- 0
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestClass.java View File

@@ -42,4 +42,9 @@ public class TestClass implements TestInterface {
42 42
 	public String interfaceMethod() {
43 43
 		return "Interface method of " + name;
44 44
 	}
45
+	
46
+	@Method
47
+	public TestGenericInterface<String> generate() {
48
+		return () -> name;
49
+	}
45 50
 }

+ 14
- 0
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/TestGenericInterface.java View File

@@ -0,0 +1,14 @@
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.scriptingexample;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public interface TestGenericInterface<T> extends TestBaseInterface<T> {
13
+	
14
+}

+ 4
- 0
Shared/src/main/java/org/openzen/zencode/shared/CodePosition.java View File

@@ -37,6 +37,10 @@ public final class CodePosition {
37 37
             throw new AssertionError("From and to positions must be in the same file!");
38 38
         return new CodePosition(file, fromLine, fromLineOffset, to.toLine, to.toLineOffset);
39 39
     }
40
+	
41
+	public CodePosition withLength(int characters) {
42
+		return new CodePosition(file, fromLine, fromLineOffset, fromLine, fromLineOffset + characters);
43
+	}
40 44
     
41 45
     public String toString() {
42 46
         return fromLine == 0 && fromLineOffset == 0 ? file.getFilename() : file.getFilename() + ":" + Integer.toString(fromLine) + ":" + Integer.toString(fromLineOffset);

+ 3
- 1
Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java View File

@@ -75,5 +75,7 @@ public enum CompileExceptionCode {
75 75
 	INVALID_STORAGE_TYPE_ARGUMENTS,
76 76
 	STORAGE_NOT_SUPPORTED,
77 77
 	INCOMPATIBLE_STORAGE_TAG,
78
-	INVALID_TYPE_ARGUMENTS
78
+	INVALID_TYPE_ARGUMENTS,
79
+	
80
+	PARSE_ERROR
79 81
 }

+ 9
- 1
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java View File

@@ -362,6 +362,13 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
362 362
 		validator.logError(ValidationLogEntry.Code.INVALID_EXPRESSION, expression.position, expression.message);
363 363
 		return null;
364 364
 	}
365
+	
366
+	@Override
367
+	public Void visitInvalidAssign(InvalidAssignExpression expression) {
368
+		expression.target.accept(this);
369
+		expression.source.accept(this);
370
+		return null;
371
+	}
365 372
 
366 373
 	@Override
367 374
 	public Void visitIs(IsExpression expression) {
@@ -748,6 +755,7 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
748 755
 	private void checkCallArguments(CodePosition position, FunctionHeader originalHeader, FunctionHeader instancedHeader, CallArguments arguments) {
749 756
 		ValidationUtils.validateTypeArguments(validator, position, originalHeader.typeParameters, arguments.typeArguments);
750 757
 		
758
+		boolean isVariadic = instancedHeader.isVariadicCall(arguments);
751 759
 		for (int i = 0; i < arguments.arguments.length; i++) {
752 760
 			Expression argument = arguments.arguments[i];
753 761
 			argument.accept(this);
@@ -766,7 +774,7 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
766 774
 				}
767 775
 			}
768 776
 			
769
-			FunctionParameter parameter = instancedHeader.parameters[i];
777
+			FunctionParameter parameter = instancedHeader.getParameter(isVariadic, i);
770 778
 			if (!parameter.type.equals(argument.type)) {
771 779
 				validator.logError(
772 780
 						ValidationLogEntry.Code.INVALID_CALL_ARGUMENT,

Loading…
Cancel
Save