Browse Source

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

kindlich 6 years ago
parent
commit
5efd13e077
No known key found for this signature in database
99 changed files with 3266 additions and 601 deletions
  1. 15
    12
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java
  2. 3
    3
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/StatementFormatter.java
  3. 1
    1
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/TypeFormatter.java
  4. 49
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  5. 5
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java
  6. 30
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/Modifiers.java
  7. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/FunctionDefinition.java
  8. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/definition/ZSPackage.java
  9. 4
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ArrayExpression.java
  10. 0
    31
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/EqualsExpression.java
  11. 4
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ExpressionVisitor.java
  12. 31
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GlobalCallExpression.java
  13. 8
    6
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GlobalExpression.java
  14. 3
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/CallerMember.java
  15. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/CasterMember.java
  16. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ConstructorMember.java
  17. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/CustomIteratorMember.java
  18. 8
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/DefinitionMember.java
  19. 3
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/EnumConstantMember.java
  20. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/EqualsMember.java
  21. 4
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FieldMember.java
  22. 3
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FunctionalMember.java
  23. 4
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/GetterMember.java
  24. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ImplementationMember.java
  25. 7
    7
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/InnerDefinitionMember.java
  26. 9
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/InstancedInnerDefinitionMember.java
  27. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/MethodMember.java
  28. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/OperatorMember.java
  29. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/SetterMember.java
  30. 3
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/TranslatedOperatorMember.java
  31. 58
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialGlobalExpression.java
  32. 3
    7
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/TryCatchStatement.java
  33. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ArrayTypeID.java
  34. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/AssocTypeID.java
  35. 18
    25
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/BasicTypeID.java
  36. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ConstTypeID.java
  37. 4
    9
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  38. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/FunctionTypeID.java
  39. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java
  40. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GlobalTypeRegistry.java
  41. 0
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java
  42. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/IteratorTypeID.java
  43. 0
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java
  44. 0
    11
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/RangeTypeID.java
  45. 134
    123
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinTypeMembers.java
  46. 104
    99
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  47. 5
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java
  48. 1
    4
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java
  49. 10
    18
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  50. 111
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaOptionalTypeClassVisitor.java
  51. 2
    1
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeClassVisitor.java
  52. 1
    1
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
  53. 6
    3
      Linker/src/main/java/org/openzen/zenscript/linker/FileScope.java
  54. 2
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java
  55. 2
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java
  56. 29
    17
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java
  57. 1
    1
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/BaseParsedDefinition.java
  58. 8
    4
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedAlias.java
  59. 3
    5
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedClass.java
  60. 9
    7
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedEnum.java
  61. 6
    4
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedEnumConstant.java
  62. 6
    8
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedExpansion.java
  63. 3
    1
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunctionHeader.java
  64. 15
    7
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedGenericParameter.java
  65. 4
    6
      Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedStruct.java
  66. 1
    1
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java
  67. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedCaller.java
  68. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedCaster.java
  69. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedConstructor.java
  70. 21
    16
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedDefinitionMember.java
  71. 18
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedField.java
  72. 4
    2
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedFunctionalMember.java
  73. 5
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedGetter.java
  74. 11
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedImplementation.java
  75. 11
    10
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedInnerDefinition.java
  76. 11
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedIterator.java
  77. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedMethod.java
  78. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedOperator.java
  79. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedSetter.java
  80. 6
    1
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementTryCatch.java
  81. 1
    0
      ScriptingExample/build.gradle
  82. 0
    15
      ScriptingExample/scripts/enums.zs
  83. 3
    1
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/GlobalRegistry.java
  84. 24
    5
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java
  85. 3
    1
      ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/SemanticModule.java
  86. 18
    0
      Validator/build.gradle
  87. 64
    0
      Validator/src/main/java/org/openzen/zenscript/validator/ValidationLogEntry.java
  88. 14
    0
      Validator/src/main/java/org/openzen/zenscript/validator/ValidationSettings.java
  89. 87
    0
      Validator/src/main/java/org/openzen/zenscript/validator/Validator.java
  90. 35
    0
      Validator/src/main/java/org/openzen/zenscript/validator/analysis/ExpressionScope.java
  91. 25
    0
      Validator/src/main/java/org/openzen/zenscript/validator/analysis/StatementScope.java
  92. 390
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionMemberValidator.java
  93. 208
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionValidator.java
  94. 663
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java
  95. 304
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/StatementValidator.java
  96. 93
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/SuperclassValidator.java
  97. 90
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/SupertypeValidator.java
  98. 114
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/TypeValidator.java
  99. 246
    0
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ValidationUtils.java

+ 15
- 12
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java View File

@@ -36,7 +36,6 @@ import org.openzen.zenscript.codemodel.expression.ConstantUShortExpression;
36 36
 import org.openzen.zenscript.codemodel.expression.ConstructorSuperCallExpression;
37 37
 import org.openzen.zenscript.codemodel.expression.ConstructorThisCallExpression;
38 38
 import org.openzen.zenscript.codemodel.expression.EnumConstantExpression;
39
-import org.openzen.zenscript.codemodel.expression.EqualsExpression;
40 39
 import org.openzen.zenscript.codemodel.expression.Expression;
41 40
 import org.openzen.zenscript.codemodel.expression.ExpressionVisitor;
42 41
 import org.openzen.zenscript.codemodel.expression.FunctionExpression;
@@ -46,12 +45,13 @@ import org.openzen.zenscript.codemodel.expression.GetFunctionParameterExpression
46 45
 import org.openzen.zenscript.codemodel.expression.GetLocalVariableExpression;
47 46
 import org.openzen.zenscript.codemodel.expression.GetStaticFieldExpression;
48 47
 import org.openzen.zenscript.codemodel.expression.GetterExpression;
48
+import org.openzen.zenscript.codemodel.expression.GlobalCallExpression;
49
+import org.openzen.zenscript.codemodel.expression.GlobalExpression;
49 50
 import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
50 51
 import org.openzen.zenscript.codemodel.expression.IsExpression;
51 52
 import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
52 53
 import org.openzen.zenscript.codemodel.expression.MapExpression;
53 54
 import org.openzen.zenscript.codemodel.expression.NewExpression;
54
-import org.openzen.zenscript.codemodel.expression.NotExpression;
55 55
 import org.openzen.zenscript.codemodel.expression.NullExpression;
56 56
 import org.openzen.zenscript.codemodel.expression.OrOrExpression;
57 57
 import org.openzen.zenscript.codemodel.expression.RangeExpression;
@@ -427,11 +427,6 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
427 427
 		return new ExpressionString(expression.type.accept(typeFormatter) + "." + expression.value.name, OperatorPriority.MEMBER);
428 428
 	}
429 429
 
430
-	@Override
431
-	public ExpressionString visitEquals(EqualsExpression expression) {
432
-		return binary(expression.left, expression.right, OperatorPriority.COMPARE, " === ");
433
-	}
434
-
435 430
 	@Override
436 431
 	public ExpressionString visitFunction(FunctionExpression expression) {
437 432
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
@@ -478,6 +473,19 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
478 473
 		result.append(expression.getter.name);
479 474
 		return new ExpressionString(result.toString(), OperatorPriority.MEMBER);
480 475
 	}
476
+	
477
+	@Override
478
+	public ExpressionString visitGlobal(GlobalExpression expression) {
479
+		return new ExpressionString(expression.name, OperatorPriority.PRIMARY);
480
+	}
481
+	
482
+	@Override
483
+	public ExpressionString visitGlobalCall(GlobalCallExpression expression) {
484
+		StringBuilder result = new StringBuilder();
485
+		result.append(expression.name);
486
+		format(result, expression.arguments);
487
+		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
488
+	}
481 489
 
482 490
 	@Override
483 491
 	public ExpressionString visitInterfaceCast(InterfaceCastExpression expression) {
@@ -526,11 +534,6 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
526 534
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
527 535
 	}
528 536
 
529
-	@Override
530
-	public ExpressionString visitNot(NotExpression expression) {
531
-		return unaryPrefix(expression.value, OperatorPriority.NOT, "!");
532
-	}
533
-
534 537
 	@Override
535 538
 	public ExpressionString visitNull(NullExpression expression) {
536 539
 		return new ExpressionString("null", OperatorPriority.PRIMARY);

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

@@ -189,10 +189,10 @@ public class StatementFormatter implements StatementVisitor<Void> {
189 189
 	public Void visitTryCatch(TryCatchStatement statement) {
190 190
 		beginSingleLine();
191 191
 		result.append("try");
192
-		if (statement.resourceName != null) {
193
-			result.append(' ').append(statement.resourceName);
192
+		if (statement.resource != null) {
193
+			result.append(' ').append(statement.resource.name);
194 194
 			result.append(" = ");
195
-			result.append(statement.resourceInitializer.accept(expressionFormatter).value);
195
+			result.append(statement.resource.initializer.accept(expressionFormatter).value);
196 196
 		}
197 197
 		
198 198
 		format(ParentStatementType.TRY, statement.content);

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

@@ -133,7 +133,7 @@ public class TypeFormatter implements ITypeVisitor<String>, GenericParameterBoun
133 133
 
134 134
 	@Override
135 135
 	public String visitOptional(OptionalTypeID optional) {
136
-		return optional.accept(this) + "?";
136
+		return optional.baseType.accept(this) + "?";
137 137
 	}
138 138
 	
139 139
 	private void formatTypeParameters(StringBuilder result, TypeParameter[] parameters) {

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

@@ -135,12 +135,51 @@ public class FunctionHeader {
135 135
 		return true;
136 136
 	}
137 137
 	
138
+	/**
139
+	 * Checks if two function headers are equivalent. Functions headers are
140
+	 * equivalent if their types are the same.
141
+	 * 
142
+	 * @param other
143
+	 * @return 
144
+	 */
138 145
 	public boolean isEquivalentTo(FunctionHeader other) {
139 146
 		if (parameters.length != other.parameters.length)
140 147
 			return false;
141 148
 		
142 149
 		for (int i = 0; i < parameters.length; i++) {
143
-			if (parameters[i] != other.parameters[i])
150
+			if (parameters[i].type != other.parameters[i].type)
151
+				return false;
152
+		}
153
+		
154
+		return true;
155
+	}
156
+	
157
+	/**
158
+	 * Checks if two function headers are similar. "similar" means that there
159
+	 * exists a set of parameters for which there is no way to determine which
160
+	 * one to call.
161
+	 * 
162
+	 * Note that this does not mean that there is never confusion about which
163
+	 * method to call. There can be confusion due to implicit conversions. This
164
+	 * can be resolved by performing the conversions explicitly.
165
+	 * 
166
+	 * It is illegal to have two similar methods with the same name.
167
+	 * 
168
+	 * @param other
169
+	 * @return 
170
+	 */
171
+	public boolean isSimilarTo(FunctionHeader other) {
172
+		int common = Math.min(parameters.length, other.parameters.length);
173
+		for (int i = 0; i < common; i++) {
174
+			if (parameters[i].type != other.parameters[i].type)
175
+				return false;
176
+		}
177
+		for (int i = common; i < parameters.length; i++) {
178
+			if (parameters[i].defaultValue == null)
179
+				return false;
180
+		}
181
+		for (int i = common; i < other.parameters.length; i++) {
182
+			if (other.parameters[i].defaultValue == null)
144 183
 				return false;
145 184
 		}
146 185
 		
@@ -184,6 +223,15 @@ public class FunctionHeader {
184 223
 		//return this;
185 224
 	}
186 225
 	
226
+	public FunctionParameter getVariadicParameter() {
227
+		if (parameters.length == 0)
228
+			return null;
229
+		if (parameters[parameters.length - 1].variadic)
230
+			return parameters[parameters.length - 1];
231
+		
232
+		return null;
233
+	}
234
+	
187 235
 	public String explainWhyIncompatible(TypeScope scope, CallArguments arguments) {
188 236
 		if (this.parameters.length != arguments.arguments.length)
189 237
 			return parameters.length + " parameters expected but " + arguments.arguments.length + " given.";

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

@@ -21,12 +21,14 @@ import org.openzen.zenscript.shared.Taggable;
21 21
  * @author Hoofdgebruiker
22 22
  */
23 23
 public abstract class HighLevelDefinition extends Taggable {
24
+	private static final TypeParameter[] NO_PARAMETERS = new TypeParameter[0];
25
+	
24 26
 	public final CodePosition position;
25 27
 	public final ZSPackage pkg;
26 28
 	public final String name;
27 29
 	public final int modifiers;
28 30
 	public final List<IDefinitionMember> members = new ArrayList<>();
29
-	public final List<TypeParameter> genericParameters = new ArrayList<>();
31
+	public TypeParameter[] genericParameters = NO_PARAMETERS;
30 32
 	
31 33
 	public HighLevelDefinition outerDefinition;
32 34
 	public ITypeID superType;
@@ -52,8 +54,8 @@ public abstract class HighLevelDefinition extends Taggable {
52 54
 			members.add(member);
53 55
 	}
54 56
 	
55
-	public void addGenericParameter(TypeParameter parameter) {
56
-		genericParameters.add(parameter);
57
+	public void setTypeParameters(TypeParameter[] typeParameters) {
58
+		this.genericParameters = typeParameters;
57 59
 	}
58 60
 	
59 61
 	public List<FieldMember> getFields() {

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

@@ -22,6 +22,24 @@ public class Modifiers {
22 22
 	public static final int STATIC = 128;
23 23
 	public static final int PROTECTED = 256;
24 24
 	public static final int IMPLICIT = 512;
25
+	public static final int VIRTUAL = 1024;
26
+	public static final int EXTERN = 2048;
27
+	
28
+	public static boolean isPublic(int modifiers) {
29
+		return (modifiers & PUBLIC) > 0;
30
+	}
31
+	
32
+	public static boolean isExport(int modifiers) {
33
+		return (modifiers & EXPORT) > 0;
34
+	}
35
+	
36
+	public static boolean isProtected(int modifiers) {
37
+		return (modifiers & PROTECTED) > 0;
38
+	}
39
+	
40
+	public static boolean isPrivate(int modifiers) {
41
+		return (modifiers & PRIVATE) > 0;
42
+	}
25 43
 	
26 44
 	public static boolean isAbstract(int modifiers) {
27 45
 		return (modifiers & ABSTRACT) > 0;
@@ -35,6 +53,10 @@ public class Modifiers {
35 53
 		return (modifiers & CONST) > 0;
36 54
 	}
37 55
 	
56
+	public static boolean isConstOptional(int modifiers) {
57
+		return (modifiers & CONST_OPTIONAL) > 0;
58
+	}
59
+	
38 60
 	public static boolean isStatic(int modifiers) {
39 61
 		return (modifiers & STATIC) > 0;
40 62
 	}
@@ -42,4 +64,12 @@ public class Modifiers {
42 64
 	public static boolean isImplicit(int modifiers) {
43 65
 		return (modifiers & IMPLICIT) > 0;
44 66
 	}
67
+	
68
+	public static boolean isVirtual(int modifiers) {
69
+		return (modifiers & VIRTUAL) > 0;
70
+	}
71
+	
72
+	public static boolean isExtern(int modifiers) {
73
+		return (modifiers & EXTERN) > 0;
74
+	}
45 75
 }

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

@@ -37,7 +37,7 @@ public class FunctionDefinition extends HighLevelDefinition {
37 37
 	
38 38
 	public void setHeader(FunctionHeader header) {
39 39
 		this.header = header;
40
-		addMember(caller = new OperatorMember(position, modifiers | Modifiers.STATIC, OperatorType.CALL, header));
40
+		addMember(caller = new OperatorMember(position, this, modifiers | Modifiers.STATIC, OperatorType.CALL, header));
41 41
 		callerGroup.addMethod(caller, TypeMemberPriority.SPECIFIED);
42 42
 	}
43 43
 	

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

@@ -39,7 +39,7 @@ public class ZSPackage {
39 39
 			return new PartialPackageExpression(position, subPackages.get(name.name));
40 40
 		
41 41
 		if (types.containsKey(name.name)) {
42
-			if (types.get(name.name).genericParameters.size() != name.arguments.size())
42
+			if (types.get(name.name).genericParameters.length != name.arguments.size())
43 43
 				throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_INVALID_NUMBER, "Invalid number of type arguments");
44 44
 			
45 45
 			return new PartialTypeExpression(position, registry.getForDefinition(types.get(name.name), name.arguments));

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

@@ -5,7 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.expression;
7 7
 
8
-import org.openzen.zenscript.codemodel.type.ITypeID;
8
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
9 9
 import org.openzen.zenscript.shared.CodePosition;
10 10
 
11 11
 /**
@@ -14,11 +14,13 @@ import org.openzen.zenscript.shared.CodePosition;
14 14
  */
15 15
 public class ArrayExpression extends Expression {
16 16
 	public final Expression[] expressions;
17
+	public final ArrayTypeID arrayType;
17 18
 	
18
-	public ArrayExpression(CodePosition position, Expression[] expressions, ITypeID type) {
19
+	public ArrayExpression(CodePosition position, Expression[] expressions, ArrayTypeID type) {
19 20
 		super(position, type);
20 21
 		
21 22
 		this.expressions = expressions;
23
+		this.arrayType = type;
22 24
 	}
23 25
 
24 26
 	@Override

+ 0
- 31
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/EqualsExpression.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.zenscript.codemodel.expression;
7
-
8
-import org.openzen.zenscript.codemodel.type.BasicTypeID;
9
-import org.openzen.zenscript.shared.CodePosition;
10
-
11
-/**
12
- * Checks if two values are identical (===).
13
- * 
14
- * @author Hoofdgebruiker
15
- */
16
-public class EqualsExpression extends Expression {
17
-	public final Expression left;
18
-	public final Expression right;
19
-	
20
-	public EqualsExpression(CodePosition position, Expression left, Expression right) {
21
-		super(position, BasicTypeID.BOOL);
22
-		
23
-		this.left = left;
24
-		this.right = right;
25
-	}
26
-
27
-	@Override
28
-	public <T> T accept(ExpressionVisitor<T> visitor) {
29
-		return visitor.visitEquals(this);
30
-	}
31
-}

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

@@ -70,8 +70,6 @@ public interface ExpressionVisitor<T> {
70 70
 	
71 71
 	public T visitEnumConstant(EnumConstantExpression expression);
72 72
 	
73
-	public T visitEquals(EqualsExpression expression);
74
-	
75 73
 	public T visitFunction(FunctionExpression expression);
76 74
 	
77 75
 	public T visitGenericCompare(GenericCompareExpression expression);
@@ -86,6 +84,10 @@ public interface ExpressionVisitor<T> {
86 84
 	
87 85
 	public T visitGetter(GetterExpression expression);
88 86
 	
87
+	public T visitGlobal(GlobalExpression expression);
88
+	
89
+	public T visitGlobalCall(GlobalCallExpression expression);
90
+	
89 91
 	public T visitInterfaceCast(InterfaceCastExpression expression);
90 92
 	
91 93
 	public T visitIs(IsExpression expression);
@@ -96,8 +98,6 @@ public interface ExpressionVisitor<T> {
96 98
 	
97 99
 	public T visitNew(NewExpression expression);
98 100
 	
99
-	public T visitNot(NotExpression expression);
100
-	
101 101
 	public T visitNull(NullExpression expression);
102 102
 	
103 103
 	public T visitOrOr(OrOrExpression expression);

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

@@ -0,0 +1,31 @@
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.zenscript.shared.CodePosition;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class GlobalCallExpression extends Expression {
15
+	public final String name;
16
+	public final CallArguments arguments;
17
+	public final Expression resolution;
18
+	
19
+	public GlobalCallExpression(CodePosition position, String name, CallArguments arguments, Expression resolution) {
20
+		super(position, resolution.type);
21
+		
22
+		this.name = name;
23
+		this.arguments = arguments;
24
+		this.resolution = resolution;
25
+	}
26
+
27
+	@Override
28
+	public <T> T accept(ExpressionVisitor<T> visitor) {
29
+		return visitor.visitGlobalCall(this);
30
+	}
31
+}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/NotExpression.java → CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/GlobalExpression.java View File

@@ -11,17 +11,19 @@ import org.openzen.zenscript.shared.CodePosition;
11 11
  *
12 12
  * @author Hoofdgebruiker
13 13
  */
14
-public class NotExpression extends Expression {
15
-	public final Expression value;
14
+public class GlobalExpression extends Expression {
15
+	public final String name;
16
+	public final Expression resolution;
16 17
 	
17
-	public NotExpression(CodePosition position, Expression value) {
18
-		super(position, value.type);
18
+	public GlobalExpression(CodePosition position, String name, Expression resolution) {
19
+		super(position, resolution.type);
19 20
 		
20
-		this.value = value;
21
+		this.name = name;
22
+		this.resolution = resolution;
21 23
 	}
22 24
 
23 25
 	@Override
24 26
 	public <T> T accept(ExpressionVisitor<T> visitor) {
25
-		return visitor.visitNot(this);
27
+		return visitor.visitGlobal(this);
26 28
 	}
27 29
 }

+ 3
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/CallerMember.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
11 12
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
12 13
 import org.openzen.zenscript.codemodel.type.ITypeID;
@@ -19,8 +20,8 @@ import org.openzen.zenscript.shared.CodePosition;
19 20
  * @author Hoofdgebruiker
20 21
  */
21 22
 public class CallerMember extends FunctionalMember {
22
-	public CallerMember(CodePosition position, int modifiers, FunctionHeader header) {
23
-		super(position, modifiers, "()", header);
23
+	public CallerMember(CodePosition position, HighLevelDefinition definition, int modifiers, FunctionHeader header) {
24
+		super(position, definition, modifiers, "()", header);
24 25
 	}
25 26
 
26 27
 	@Override

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.Modifiers;
11 12
 import org.openzen.zenscript.codemodel.expression.CallArguments;
12 13
 import org.openzen.zenscript.codemodel.expression.CastExpression;
@@ -25,8 +26,8 @@ import org.openzen.zenscript.shared.CodePosition;
25 26
 public class CasterMember extends FunctionalMember implements ICasterMember {
26 27
 	public final ITypeID toType;
27 28
 	
28
-	public CasterMember(CodePosition position, int modifiers, ITypeID toType) {
29
-		super(position, modifiers, "as", new FunctionHeader(toType));
29
+	public CasterMember(CodePosition position, HighLevelDefinition definition, int modifiers, ITypeID toType) {
30
+		super(position, definition, modifiers, "as", new FunctionHeader(toType));
30 31
 		
31 32
 		this.toType = toType;
32 33
 	}
@@ -43,7 +44,7 @@ public class CasterMember extends FunctionalMember implements ICasterMember {
43 44
 
44 45
 	@Override
45 46
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
46
-		return new CasterMember(position, modifiers, toType.withGenericArguments(registry, mapping));
47
+		return new CasterMember(position, definition, modifiers, toType.withGenericArguments(registry, mapping));
47 48
 	}
48 49
 	
49 50
 	@Override

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
11 12
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
12 13
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -20,8 +21,8 @@ import org.openzen.zenscript.shared.CodePosition;
20 21
  * @author Hoofdgebruiker
21 22
  */
22 23
 public class ConstructorMember extends FunctionalMember {
23
-	public ConstructorMember(CodePosition position, int modifiers, FunctionHeader header) {
24
-		super(position, modifiers, "this", new FunctionHeader(header.typeParameters, BasicTypeID.VOID, header.parameters));
24
+	public ConstructorMember(CodePosition position, HighLevelDefinition definition, int modifiers, FunctionHeader header) {
25
+		super(position, definition, modifiers, "this", new FunctionHeader(header.typeParameters, BasicTypeID.VOID, header.parameters));
25 26
 	}
26 27
 
27 28
 	@Override
@@ -32,7 +33,7 @@ public class ConstructorMember extends FunctionalMember {
32 33
 
33 34
 	@Override
34 35
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
35
-		return new ConstructorMember(position, modifiers, header.instance(registry, mapping));
36
+		return new ConstructorMember(position, definition, modifiers, header.instance(registry, mapping));
36 37
 	}
37 38
 
38 39
 	@Override

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.List;
9 9
 import java.util.Map;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
11 12
 import org.openzen.zenscript.codemodel.iterator.ForeachIteratorVisitor;
12 13
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -24,8 +25,8 @@ public class CustomIteratorMember extends DefinitionMember implements IIteratorM
24 25
 	private final ITypeID[] iteratorTypes;
25 26
 	private List<Statement> content;
26 27
 	
27
-	public CustomIteratorMember(CodePosition position, int modifiers, ITypeID[] iteratorTypes) {
28
-		super(position, modifiers);
28
+	public CustomIteratorMember(CodePosition position, HighLevelDefinition definition, int modifiers, ITypeID[] iteratorTypes) {
29
+		super(position, definition, modifiers);
29 30
 		
30 31
 		this.iteratorTypes = iteratorTypes;
31 32
 	}
@@ -54,7 +55,7 @@ public class CustomIteratorMember extends DefinitionMember implements IIteratorM
54 55
 		ITypeID[] newIteratorTypes = new ITypeID[iteratorTypes.length];
55 56
 		for (int i = 0; i < newIteratorTypes.length; i++)
56 57
 			newIteratorTypes[i] = iteratorTypes[i].withGenericArguments(registry, mapping);
57
-		return new CustomIteratorMember(position, modifiers, newIteratorTypes);
58
+		return new CustomIteratorMember(position, definition, modifiers, newIteratorTypes);
58 59
 	}
59 60
 
60 61
 	@Override

+ 8
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/DefinitionMember.java View File

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.Modifiers;
9 10
 import org.openzen.zenscript.shared.CodePosition;
10 11
 import org.openzen.zenscript.shared.Taggable;
@@ -15,10 +16,12 @@ import org.openzen.zenscript.shared.Taggable;
15 16
  */
16 17
 public abstract class DefinitionMember extends Taggable implements IDefinitionMember {
17 18
 	public final CodePosition position;
19
+	public final HighLevelDefinition definition;
18 20
 	public final int modifiers;
19 21
 	
20
-	public DefinitionMember(CodePosition position, int modifiers) {
22
+	public DefinitionMember(CodePosition position, HighLevelDefinition definition, int modifiers) {
21 23
 		this.position = position;
24
+		this.definition = definition;
22 25
 		this.modifiers = modifiers;
23 26
 	}
24 27
 	
@@ -34,4 +37,8 @@ public abstract class DefinitionMember extends Taggable implements IDefinitionMe
34 37
 	public boolean isFinal() {
35 38
 		return Modifiers.isFinal(modifiers);
36 39
 	}
40
+	
41
+	public boolean isExtern() {
42
+		return Modifiers.isExtern(modifiers);
43
+	}
37 44
 }

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

@@ -6,8 +6,8 @@
6 6
 package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
9 10
 import org.openzen.zenscript.codemodel.Modifiers;
10
-import org.openzen.zenscript.codemodel.expression.CallExpression;
11 11
 import org.openzen.zenscript.codemodel.expression.NewExpression;
12 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
13 13
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -26,8 +26,8 @@ public class EnumConstantMember extends DefinitionMember {
26 26
 	
27 27
 	public NewExpression constructor;
28 28
 	
29
-	public EnumConstantMember(CodePosition position, String name, int value) {
30
-		super(position, Modifiers.STATIC);
29
+	public EnumConstantMember(CodePosition position, HighLevelDefinition definition, String name, int value) {
30
+		super(position, definition, Modifiers.STATIC);
31 31
 		
32 32
 		this.name = name;
33 33
 		this.value = value;

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/EqualsMember.java View File

@@ -10,8 +10,8 @@ import org.openzen.zenscript.codemodel.CompareType;
10 10
 import org.openzen.zenscript.codemodel.FunctionHeader;
11 11
 import org.openzen.zenscript.codemodel.FunctionParameter;
12 12
 import org.openzen.zenscript.codemodel.OperatorType;
13
+import org.openzen.zenscript.codemodel.expression.BasicCompareExpression;
13 14
 import org.openzen.zenscript.codemodel.expression.CallArguments;
14
-import org.openzen.zenscript.codemodel.expression.EqualsExpression;
15 15
 import org.openzen.zenscript.codemodel.expression.Expression;
16 16
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
17 17
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
@@ -47,7 +47,7 @@ public class EqualsMember extends Taggable implements ICallableMember {
47 47
 
48 48
 	@Override
49 49
 	public Expression call(CodePosition position, Expression target, FunctionHeader instancedHeader, CallArguments arguments) {
50
-		return new EqualsExpression(position, target, arguments.arguments[0]);
50
+		return new BasicCompareExpression(position, target, arguments.arguments[0], CompareType.EQ);
51 51
 	}
52 52
 
53 53
 	@Override

+ 4
- 4
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FieldMember.java View File

@@ -6,7 +6,7 @@
6 6
 package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9
-import org.openzen.zenscript.codemodel.Modifiers;
9
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 10
 import org.openzen.zenscript.codemodel.expression.Expression;
11 11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 12
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -24,8 +24,8 @@ public class FieldMember extends DefinitionMember {
24 24
 	public final ITypeID type;
25 25
 	public Expression initializer;
26 26
 	
27
-	public FieldMember(CodePosition position, int modifiers, String name, ITypeID type) {
28
-		super(position, modifiers);
27
+	public FieldMember(CodePosition position, HighLevelDefinition definition, int modifiers, String name, ITypeID type) {
28
+		super(position, definition, modifiers);
29 29
 		
30 30
 		this.name = name;
31 31
 		this.type = type;
@@ -42,7 +42,7 @@ public class FieldMember extends DefinitionMember {
42 42
 
43 43
 	@Override
44 44
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
45
-		return new FieldMember(position, modifiers, name, type.withGenericArguments(registry, mapping));
45
+		return new FieldMember(position, definition, modifiers, name, type.withGenericArguments(registry, mapping));
46 46
 	}
47 47
 
48 48
 	@Override

+ 3
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FunctionalMember.java View File

@@ -8,6 +8,7 @@ package org.openzen.zenscript.codemodel.member;
8 8
 import java.util.List;
9 9
 import org.openzen.zenscript.codemodel.CompareType;
10 10
 import org.openzen.zenscript.codemodel.FunctionHeader;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11 12
 import org.openzen.zenscript.codemodel.expression.CallArguments;
12 13
 import org.openzen.zenscript.codemodel.expression.CallExpression;
13 14
 import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
@@ -25,8 +26,8 @@ public abstract class FunctionalMember extends DefinitionMember implements ICall
25 26
 	public final String name;
26 27
 	public List<Statement> body;
27 28
 	
28
-	public FunctionalMember(CodePosition position, int modifiers, String name, FunctionHeader header) {
29
-		super(position, modifiers);
29
+	public FunctionalMember(CodePosition position, HighLevelDefinition definition, int modifiers, String name, FunctionHeader header) {
30
+		super(position, definition, modifiers);
30 31
 		
31 32
 		this.name = name;
32 33
 		this.header = header;

+ 4
- 5
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/GetterMember.java View File

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.expression.Expression;
11 12
 import org.openzen.zenscript.codemodel.expression.GetterExpression;
12 13
 import org.openzen.zenscript.codemodel.expression.StaticGetterExpression;
@@ -25,10 +26,8 @@ public class GetterMember extends FunctionalMember implements IGettableMember {
25 26
 	public final String name;
26 27
 	public final ITypeID type;
27 28
 	
28
-	public String compiledName;
29
-	
30
-	public GetterMember(CodePosition position, int modifiers, String name, ITypeID type) {
31
-		super(position, modifiers, name, new FunctionHeader(type));
29
+	public GetterMember(CodePosition position, HighLevelDefinition definition, int modifiers, String name, ITypeID type) {
30
+		super(position, definition, modifiers, name, new FunctionHeader(type));
32 31
 		
33 32
 		this.name = name;
34 33
 		this.type = type;
@@ -61,7 +60,7 @@ public class GetterMember extends FunctionalMember implements IGettableMember {
61 60
 
62 61
 	@Override
63 62
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
64
-		return new GetterMember(position, modifiers, name, type.withGenericArguments(registry, mapping));
63
+		return new GetterMember(position, definition, modifiers, name, type.withGenericArguments(registry, mapping));
65 64
 	}
66 65
 
67 66
 	@Override

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

@@ -8,6 +8,7 @@ package org.openzen.zenscript.codemodel.member;
8 8
 import java.util.ArrayList;
9 9
 import java.util.List;
10 10
 import java.util.Map;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 13
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
13 14
 import org.openzen.zenscript.codemodel.type.member.TypeMembers;
@@ -23,8 +24,8 @@ public class ImplementationMember extends DefinitionMember {
23 24
 	public final ITypeID type;
24 25
 	public final List<IDefinitionMember> members = new ArrayList<>();
25 26
 	
26
-	public ImplementationMember(CodePosition position, int modifiers, ITypeID type) {
27
-		super(position, modifiers);
27
+	public ImplementationMember(CodePosition position, HighLevelDefinition definition, int modifiers, ITypeID type) {
28
+		super(position, definition, modifiers);
28 29
 		
29 30
 		this.type = type;
30 31
 	}
@@ -44,7 +45,7 @@ public class ImplementationMember extends DefinitionMember {
44 45
 	@Override
45 46
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
46 47
 		ITypeID instancedType = type.withGenericArguments(registry, mapping);
47
-		ImplementationMember result = new ImplementationMember(position, modifiers, instancedType);
48
+		ImplementationMember result = new ImplementationMember(position, definition, modifiers, instancedType);
48 49
 		for (IDefinitionMember member : members)
49 50
 			result.addMember(member.instance(registry, mapping));
50 51
 		return result;

+ 7
- 7
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/InnerDefinitionMember.java View File

@@ -19,17 +19,17 @@ import org.openzen.zenscript.shared.CodePosition;
19 19
  * @author Hoofdgebruiker
20 20
  */
21 21
 public class InnerDefinitionMember extends DefinitionMember {
22
-	private final HighLevelDefinition definition;
22
+	public final HighLevelDefinition innerDefinition;
23 23
 	
24
-	public InnerDefinitionMember(CodePosition position, int modifiers, HighLevelDefinition definition) {
25
-		super(position, modifiers);
24
+	public InnerDefinitionMember(CodePosition position, HighLevelDefinition outer, int modifiers, HighLevelDefinition definition) {
25
+		super(position, outer, modifiers);
26 26
 		
27
-		this.definition = definition;
27
+		this.innerDefinition = definition;
28 28
 	}
29 29
 
30 30
 	@Override
31 31
 	public void registerTo(TypeMembers type, TypeMemberPriority priority) {
32
-		type.addInnerType(definition.name, new InnerDefinition(definition));
32
+		type.addInnerType(innerDefinition.name, new InnerDefinition(innerDefinition));
33 33
 	}
34 34
 
35 35
 	@Override
@@ -37,13 +37,13 @@ public class InnerDefinitionMember extends DefinitionMember {
37 37
 		if (this.isStatic()) {
38 38
 			return this;
39 39
 		} else {
40
-			return new InstancedInnerDefinitionMember(position, modifiers, definition, mapping);
40
+			return new InstancedInnerDefinitionMember(position, definition, modifiers, innerDefinition, mapping);
41 41
 		}
42 42
 	}
43 43
 
44 44
 	@Override
45 45
 	public String describe() {
46
-		return "inner type " + definition.name;
46
+		return "inner type " + innerDefinition.name;
47 47
 	}
48 48
 
49 49
 	@Override

+ 9
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/InstancedInnerDefinitionMember.java View File

@@ -27,8 +27,14 @@ public class InstancedInnerDefinitionMember extends DefinitionMember {
27 27
 	public final HighLevelDefinition definition;
28 28
 	public final Map<TypeParameter, ITypeID> outerMapping;
29 29
 	
30
-	public InstancedInnerDefinitionMember(CodePosition position, int modifiers, HighLevelDefinition definition, Map<TypeParameter, ITypeID> outerMapping) {
31
-		super(position, modifiers);
30
+	public InstancedInnerDefinitionMember(
31
+			CodePosition position,
32
+			HighLevelDefinition outer,
33
+			int modifiers,
34
+			HighLevelDefinition definition,
35
+			Map<TypeParameter, ITypeID> outerMapping)
36
+	{
37
+		super(position, outer, modifiers);
32 38
 		this.definition = definition;
33 39
 		this.outerMapping = outerMapping;
34 40
 	}
@@ -49,7 +55,7 @@ public class InstancedInnerDefinitionMember extends DefinitionMember {
49 55
 			for (Map.Entry<TypeParameter, ITypeID> entry : mapping.entrySet())
50 56
 				totalMap.put(entry.getKey(), entry.getValue());
51 57
 			
52
-			return new InstancedInnerDefinitionMember(position, modifiers, definition, totalMap);
58
+			return new InstancedInnerDefinitionMember(position, definition, modifiers, definition, totalMap);
53 59
 		}
54 60
 	}
55 61
 

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
11 12
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
12 13
 import org.openzen.zenscript.codemodel.type.ITypeID;
@@ -19,8 +20,8 @@ import org.openzen.zenscript.shared.CodePosition;
19 20
  * @author Hoofdgebruiker
20 21
  */
21 22
 public class MethodMember extends FunctionalMember {
22
-	public MethodMember(CodePosition position, int modifiers, String name, FunctionHeader header) {
23
-		super(position, modifiers, name, header);
23
+	public MethodMember(CodePosition position, HighLevelDefinition definition, int modifiers, String name, FunctionHeader header) {
24
+		super(position, definition, modifiers, name, header);
24 25
 	}
25 26
 
26 27
 	@Override
@@ -30,7 +31,7 @@ public class MethodMember extends FunctionalMember {
30 31
 
31 32
 	@Override
32 33
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
33
-		return new MethodMember(position, modifiers, name, header.instance(registry, mapping));
34
+		return new MethodMember(position, definition, modifiers, name, header.instance(registry, mapping));
34 35
 	}
35 36
 
36 37
 	@Override

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 11
 import org.openzen.zenscript.codemodel.OperatorType;
11 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 13
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -22,8 +23,8 @@ import org.openzen.zenscript.shared.CodePosition;
22 23
 public class OperatorMember extends FunctionalMember {
23 24
 	public final OperatorType operator;
24 25
 	
25
-	public OperatorMember(CodePosition position, int modifiers, OperatorType operator, FunctionHeader header) {
26
-		super(position, modifiers, operator.operator, header);
26
+	public OperatorMember(CodePosition position, HighLevelDefinition definition, int modifiers, OperatorType operator, FunctionHeader header) {
27
+		super(position, definition, modifiers, operator.operator, header);
27 28
 		
28 29
 		this.operator = operator;
29 30
 	}
@@ -35,7 +36,7 @@ public class OperatorMember extends FunctionalMember {
35 36
 
36 37
 	@Override
37 38
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
38
-		return new OperatorMember(position, modifiers, operator, header.instance(registry, mapping));
39
+		return new OperatorMember(position, definition, modifiers, operator, header.instance(registry, mapping));
39 40
 	}
40 41
 
41 42
 	@Override

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

@@ -8,6 +8,7 @@ package org.openzen.zenscript.codemodel.member;
8 8
 import java.util.Map;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10 10
 import org.openzen.zenscript.codemodel.FunctionParameter;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 13
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
13 14
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
@@ -24,8 +25,8 @@ public class SetterMember extends FunctionalMember {
24 25
 	public final String name;
25 26
 	public final ITypeID type;
26 27
 	
27
-	public SetterMember(CodePosition position, int modifiers, String name, ITypeID type) {
28
-		super(position, modifiers, name, new FunctionHeader(BasicTypeID.VOID, new FunctionParameter(type, "$")));
28
+	public SetterMember(CodePosition position, HighLevelDefinition definition, int modifiers, String name, ITypeID type) {
29
+		super(position, definition, modifiers, name, new FunctionHeader(BasicTypeID.VOID, new FunctionParameter(type, "$")));
29 30
 		
30 31
 		this.name = name;
31 32
 		this.type = type;
@@ -38,7 +39,7 @@ public class SetterMember extends FunctionalMember {
38 39
 
39 40
 	@Override
40 41
 	public DefinitionMember instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
41
-		return new SetterMember(position, modifiers, name, type.withGenericArguments(registry, mapping));
42
+		return new SetterMember(position, definition, modifiers, name, type.withGenericArguments(registry, mapping));
42 43
 	}
43 44
 
44 45
 	@Override

+ 3
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/TranslatedOperatorMember.java View File

@@ -6,6 +6,7 @@
6 6
 package org.openzen.zenscript.codemodel.member;
7 7
 
8 8
 import org.openzen.zenscript.codemodel.FunctionHeader;
9
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
9 10
 import org.openzen.zenscript.codemodel.OperatorType;
10 11
 import org.openzen.zenscript.codemodel.expression.CallArguments;
11 12
 import org.openzen.zenscript.codemodel.expression.CallTranslator;
@@ -19,8 +20,8 @@ import org.openzen.zenscript.shared.CodePosition;
19 20
 public class TranslatedOperatorMember extends OperatorMember {
20 21
 	private final CallTranslator translator;
21 22
 	
22
-	public TranslatedOperatorMember(CodePosition position, int modifiers, OperatorType operator, FunctionHeader header, CallTranslator translator) {
23
-		super(position, modifiers, operator, header);
23
+	public TranslatedOperatorMember(CodePosition position, HighLevelDefinition definition, int modifiers, OperatorType operator, FunctionHeader header, CallTranslator translator) {
24
+		super(position, definition, modifiers, operator, header);
24 25
 		
25 26
 		this.translator = translator;
26 27
 	}

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

@@ -0,0 +1,58 @@
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.partial;
7
+
8
+import java.util.List;
9
+import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.expression.CallArguments;
11
+import org.openzen.zenscript.codemodel.expression.Expression;
12
+import org.openzen.zenscript.codemodel.expression.GlobalCallExpression;
13
+import org.openzen.zenscript.codemodel.expression.GlobalExpression;
14
+import org.openzen.zenscript.codemodel.scope.TypeScope;
15
+import org.openzen.zenscript.codemodel.type.GenericName;
16
+import org.openzen.zenscript.codemodel.type.ITypeID;
17
+import org.openzen.zenscript.shared.CodePosition;
18
+
19
+/**
20
+ *
21
+ * @author Hoofdgebruiker
22
+ */
23
+public class PartialGlobalExpression implements IPartialExpression {
24
+	private final CodePosition position;
25
+	private final String name;
26
+	private final IPartialExpression resolution;
27
+	
28
+	public PartialGlobalExpression(CodePosition position, String name, IPartialExpression resolution) {
29
+		this.position = position;
30
+		this.name = name;
31
+		this.resolution = resolution;
32
+	}
33
+	
34
+	@Override
35
+	public Expression eval() {
36
+		return new GlobalExpression(position, name, resolution.eval());
37
+	}
38
+
39
+	@Override
40
+	public List<ITypeID>[] predictCallTypes(TypeScope scope, List<ITypeID> hints, int arguments) {
41
+		return resolution.predictCallTypes(scope, hints, arguments);
42
+	}
43
+
44
+	@Override
45
+	public List<FunctionHeader> getPossibleFunctionHeaders(TypeScope scope, List<ITypeID> hints, int arguments) {
46
+		return resolution.getPossibleFunctionHeaders(scope, hints, arguments);
47
+	}
48
+
49
+	@Override
50
+	public IPartialExpression getMember(CodePosition position, TypeScope scope, List<ITypeID> hints, GenericName name) {
51
+		return eval().getMember(position, scope, hints, name);
52
+	}
53
+
54
+	@Override
55
+	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
56
+		return new GlobalCallExpression(position, name, arguments, resolution.call(position, scope, hints, arguments));
57
+	}
58
+}

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

@@ -6,7 +6,6 @@
6 6
 package org.openzen.zenscript.codemodel.statement;
7 7
 
8 8
 import java.util.List;
9
-import org.openzen.zenscript.codemodel.expression.Expression;
10 9
 import org.openzen.zenscript.shared.CodePosition;
11 10
 
12 11
 /**
@@ -14,23 +13,20 @@ import org.openzen.zenscript.shared.CodePosition;
14 13
  * @author Hoofdgebruiker
15 14
  */
16 15
 public class TryCatchStatement extends Statement {
17
-	public final String resourceName;
18
-	public final Expression resourceInitializer;
16
+	public final VarStatement resource;
19 17
 	public final Statement content;
20 18
 	public final List<CatchClause> catchClauses;
21 19
 	public final Statement finallyClause;
22 20
 	
23 21
 	public TryCatchStatement(
24 22
 			CodePosition position,
25
-			String resourceName,
26
-			Expression resourceInitializer,
23
+			VarStatement resource,
27 24
 			Statement content,
28 25
 			List<CatchClause> catchClauses,
29 26
 			Statement finallyClause) {
30 27
 		super(position);
31 28
 		
32
-		this.resourceName = resourceName;
33
-		this.resourceInitializer = resourceInitializer;
29
+		this.resource = resource;
34 30
 		this.content = content;
35 31
 		this.catchClauses = catchClauses;
36 32
 		this.finallyClause = finallyClause;

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

@@ -51,11 +51,6 @@ public class ArrayTypeID implements ITypeID {
51 51
 		return elementType.hasInferenceBlockingTypeParameters(parameters);
52 52
 	}
53 53
 
54
-	@Override
55
-	public String toCamelCaseName() {
56
-		return elementType.toCamelCaseName() + "Array";
57
-	}
58
-
59 54
 	@Override
60 55
 	public int hashCode() {
61 56
 		int hash = 7;

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

@@ -53,11 +53,6 @@ public class AssocTypeID implements ITypeID {
53 53
 		return keyType.hasInferenceBlockingTypeParameters(parameters) || valueType.hasInferenceBlockingTypeParameters(parameters);
54 54
 	}
55 55
 
56
-	@Override
57
-	public String toCamelCaseName() {
58
-		return keyType.toCamelCaseName() + valueType.toCamelCaseName() + "Map";
59
-	}
60
-
61 56
 	@Override
62 57
 	public int hashCode() {
63 58
 		int hash = 7;

+ 18
- 25
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/BasicTypeID.java View File

@@ -15,33 +15,31 @@ import org.openzen.zenscript.codemodel.generic.TypeParameter;
15 15
  * @author Hoofdgebruiker
16 16
  */
17 17
 public enum BasicTypeID implements ITypeID {
18
-	VOID("void", "Void"),
19
-	NULL("null", "Null"),
20
-	ANY("any", "Any"),
21
-	BOOL("bool", "Bool"),
22
-	BYTE("byte", "Byte"),
23
-	SBYTE("sbyte", "SByte"),
24
-	SHORT("short", "Short"),
25
-	USHORT("ushort", "UShort"),
26
-	INT("int", "Int"),
27
-	UINT("uint", "UInt"),
28
-	LONG("long", "Long"),
29
-	ULONG("ulong", "ULong"),
30
-	FLOAT("float", "Float"),
31
-	DOUBLE("double", "Double"),
32
-	CHAR("char", "Char"),
33
-	STRING("string", "String"),
18
+	VOID("void"),
19
+	NULL("null"),
20
+	ANY("any"),
21
+	BOOL("bool"),
22
+	BYTE("byte"),
23
+	SBYTE("sbyte"),
24
+	SHORT("short"),
25
+	USHORT("ushort"),
26
+	INT("int"),
27
+	UINT("uint"),
28
+	LONG("long"),
29
+	ULONG("ulong"),
30
+	FLOAT("float"),
31
+	DOUBLE("double"),
32
+	CHAR("char"),
33
+	STRING("string"),
34 34
 	
35
-	UNDETERMINED("undetermined", "Undetermined");
35
+	UNDETERMINED("undetermined");
36 36
 	
37 37
 	public static final List<ITypeID> HINT_BOOL = Collections.singletonList(BOOL);
38 38
 	
39 39
 	public final String name;
40
-	public final String camelCaseName;
41 40
 	
42
-	BasicTypeID(String name, String camelCaseName) {
41
+	BasicTypeID(String name) {
43 42
 		this.name = name;
44
-		this.camelCaseName = camelCaseName;
45 43
 	}
46 44
 	
47 45
 	@Override
@@ -78,9 +76,4 @@ public enum BasicTypeID implements ITypeID {
78 76
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {
79 77
 		return false;
80 78
 	}
81
-
82
-	@Override
83
-	public String toCamelCaseName() {
84
-		return camelCaseName;
85
-	}
86 79
 }

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

@@ -56,11 +56,6 @@ public class ConstTypeID implements ITypeID {
56 56
 		return baseType.hasInferenceBlockingTypeParameters(parameters);
57 57
 	}
58 58
 
59
-	@Override
60
-	public String toCamelCaseName() {
61
-		return "Const" + baseType.toCamelCaseName();
62
-	}
63
-
64 59
 	@Override
65 60
 	public int hashCode() {
66 61
 		int hash = 3;

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

@@ -21,7 +21,7 @@ import org.openzen.zenscript.codemodel.generic.TypeParameter;
21 21
  */
22 22
 public class DefinitionTypeID implements ITypeID {
23 23
 	public static DefinitionTypeID forType(HighLevelDefinition definition) {
24
-		if (!definition.genericParameters.isEmpty())
24
+		if (definition.genericParameters.length > 0)
25 25
 			throw new IllegalArgumentException("Definition has type arguments!");
26 26
 		
27 27
 		return new DefinitionTypeID(definition, NO_TYPE_PARAMETERS);
@@ -57,7 +57,7 @@ public class DefinitionTypeID implements ITypeID {
57 57
 			Arrays.sort(outerTypeEntries, (a, b) -> a.parameter.name.compareTo(b.parameter.name));
58 58
 		}
59 59
 		
60
-		if (typeParameters.length != definition.genericParameters.size())
60
+		if (typeParameters.length != definition.genericParameters.length)
61 61
 			throw new RuntimeException("Invalid number of type parameters");
62 62
 	}
63 63
 	
@@ -66,7 +66,7 @@ public class DefinitionTypeID implements ITypeID {
66 66
 		if (superType != null && typeParameters.length > 0) {
67 67
 			Map<TypeParameter, ITypeID> genericSuperArguments = new HashMap<>();
68 68
 			for (int i = 0; i < typeParameters.length; i++)
69
-				genericSuperArguments.put(definition.genericParameters.get(i), typeParameters[i]);
69
+				genericSuperArguments.put(definition.genericParameters[i], typeParameters[i]);
70 70
 			
71 71
 			superType = definition.superType.withGenericArguments(registry, genericSuperArguments);
72 72
 		}
@@ -81,11 +81,6 @@ public class DefinitionTypeID implements ITypeID {
81 81
 		this.outerTypeParameters = Collections.emptyMap();
82 82
 		this.outerTypeEntries = NO_OUTER_ENTRIES;
83 83
 	}
84
-
85
-	@Override
86
-	public String toCamelCaseName() {
87
-		return definition.name;
88
-	}
89 84
 	
90 85
 	@Override
91 86
 	public ITypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments) {
@@ -94,7 +89,7 @@ public class DefinitionTypeID implements ITypeID {
94 89
 		
95 90
 		List<ITypeID> instancedArguments = new ArrayList<>();
96 91
 		for (int i = 0; i < typeParameters.length; i++) {
97
-			instancedArguments.add(arguments.containsKey(definition.genericParameters.get(i)) ? arguments.get(definition.genericParameters.get(i)) : typeParameters[i].withGenericArguments(registry, arguments));
92
+			instancedArguments.add(arguments.containsKey(definition.genericParameters[i]) ? arguments.get(definition.genericParameters[i]) : typeParameters[i].withGenericArguments(registry, arguments));
98 93
 		}
99 94
 		Map<TypeParameter, ITypeID> instancedOuter;
100 95
 		if (outerTypeParameters.isEmpty()) {

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

@@ -52,11 +52,6 @@ public class FunctionTypeID implements ITypeID {
52 52
 		return header.hasInferenceBlockingTypeParameters(parameters);
53 53
 	}
54 54
 
55
-	@Override
56
-	public String toCamelCaseName() {
57
-		return "Function"; // not unique, though
58
-	}
59
-
60 55
 	@Override
61 56
 	public int hashCode() {
62 57
 		int hash = 5;

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

@@ -48,11 +48,6 @@ public class GenericTypeID implements ITypeID {
48 48
 		return false;
49 49
 	}
50 50
 
51
-	@Override
52
-	public String toCamelCaseName() {
53
-		return parameter.name;
54
-	}
55
-
56 51
 	@Override
57 52
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {
58 53
 		for (TypeParameter parameter : parameters)

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

@@ -99,7 +99,7 @@ public class GlobalTypeRegistry {
99 99
 	
100 100
 	public DefinitionTypeID getForDefinition(HighLevelDefinition definition, List<ITypeID> typeParameters, Map<TypeParameter, ITypeID> outerInstance) {
101 101
 		DefinitionTypeID id;
102
-		if (definition.genericParameters.size() > 0 && typeParameters.isEmpty() && outerInstance.isEmpty()) {
102
+		if (definition.genericParameters.length > 0 && typeParameters.isEmpty() && outerInstance.isEmpty()) {
103 103
 			// make it a static one
104 104
 			id = new StaticDefinitionTypeID(definition);
105 105
 		} else {

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

@@ -33,8 +33,6 @@ public interface ITypeID {
33 33
 		return this;
34 34
 	}
35 35
 	
36
-	public String toCamelCaseName();
37
-	
38 36
 	public ITypeID withGenericArguments(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> arguments);
39 37
 	
40 38
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters);

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

@@ -58,11 +58,6 @@ public class IteratorTypeID implements ITypeID {
58 58
 		return false;
59 59
 	}
60 60
 
61
-	@Override
62
-	public String toCamelCaseName() {
63
-		return "Iterator" + (iteratorTypes.length == 1 ? "" : iteratorTypes.length);
64
-	}
65
-
66 61
 	@Override
67 62
 	public int hashCode() {
68 63
 		int hash = 5;

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

@@ -61,11 +61,6 @@ public class OptionalTypeID implements ITypeID {
61 61
 		return baseType.hasInferenceBlockingTypeParameters(parameters);
62 62
 	}
63 63
 
64
-	@Override
65
-	public String toCamelCaseName() {
66
-		return "Optional" + baseType.toCamelCaseName();
67
-	}
68
-
69 64
 	@Override
70 65
 	public int hashCode() {
71 66
 		int hash = 7;

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

@@ -53,17 +53,6 @@ public class RangeTypeID implements ITypeID {
53 53
 		return from.hasInferenceBlockingTypeParameters(parameters) || to.hasInferenceBlockingTypeParameters(parameters);
54 54
 	}
55 55
 
56
-	@Override
57
-	public String toCamelCaseName() {
58
-		if (from == BasicTypeID.INT && to == BasicTypeID.INT) {
59
-			return "Range";
60
-		} else if (from == to) {
61
-			return from.toCamelCaseName() + "Range";
62
-		} else {
63
-			return from.toCamelCaseName() + to.toCamelCaseName() + "Range";
64
-		}
65
-	}
66
-
67 56
 	@Override
68 57
 	public int hashCode() {
69 58
 		int hash = 5;

+ 134
- 123
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinTypeMembers.java View File

@@ -9,6 +9,7 @@ import org.openzen.zenscript.codemodel.FunctionHeader;
9 9
 import org.openzen.zenscript.codemodel.FunctionParameter;
10 10
 import org.openzen.zenscript.codemodel.Modifiers;
11 11
 import org.openzen.zenscript.codemodel.OperatorType;
12
+import org.openzen.zenscript.codemodel.definition.ClassDefinition;
12 13
 import org.openzen.zenscript.codemodel.expression.ConstantIntExpression;
13 14
 import org.openzen.zenscript.codemodel.expression.ConstantLongExpression;
14 15
 import org.openzen.zenscript.codemodel.member.CasterMember;
@@ -34,144 +35,154 @@ public class BuiltinTypeMembers {
34 35
 	public static final ConstantGetterMember LONG_GET_MIN_VALUE = new ConstantGetterMember("MIN_VALUE", position -> new ConstantLongExpression(position, Long.MIN_VALUE));
35 36
 	public static final ConstantGetterMember LONG_GET_MAX_VALUE = new ConstantGetterMember("MAX_VALUE", position -> new ConstantLongExpression(position, Long.MAX_VALUE));
36 37
 	
37
-	public static final OperatorMember BOOL_NOT = not(BOOL);
38
-	
39
-	public static final OperatorMember BYTE_NOT = not(BYTE);
40
-	public static final OperatorMember SBYTE_NOT = not(SBYTE);
41
-	public static final OperatorMember SHORT_NOT = not(SHORT);
42
-	public static final OperatorMember USHORT_NOT = not(USHORT);
43
-	public static final OperatorMember INT_NOT = not(INT);
44
-	public static final OperatorMember UINT_NOT = not(UINT);
45
-	public static final OperatorMember LONG_NOT = not(LONG);
46
-	public static final OperatorMember ULONG_NOT = not(ULONG);
47
-	
48
-	public static final OperatorMember BYTE_NEG = neg(BYTE);
49
-	public static final OperatorMember SBYTE_NEG = neg(SBYTE);
50
-	public static final OperatorMember SHORT_NEG = neg(SHORT);
51
-	public static final OperatorMember USHORT_NEG = neg(USHORT);
52
-	public static final OperatorMember INT_NEG = neg(INT);
53
-	public static final OperatorMember UINT_NEG = neg(UINT);
54
-	public static final OperatorMember LONG_NEG = neg(LONG);
55
-	public static final OperatorMember ULONG_NEG = neg(ULONG);
56
-	public static final OperatorMember FLOAT_NEG = neg(FLOAT);
57
-	public static final OperatorMember DOUBLE_NEG = neg(DOUBLE);
58
-	
59
-	public static final OperatorMember BYTE_ADD_BYTE = add(BYTE, BYTE);
60
-	public static final OperatorMember SBYTE_ADD_SBYTE = add(SBYTE, SBYTE);
61
-	public static final OperatorMember SHORT_ADD_SHORT = add(SHORT, SHORT);
62
-	public static final OperatorMember USHORT_ADD_USHORT = add(USHORT, USHORT);
63
-	public static final OperatorMember INT_ADD_INT = add(INT, INT);
64
-	public static final OperatorMember UINT_ADD_UINT = add(UINT, UINT);
65
-	public static final OperatorMember LONG_ADD_LONG = add(LONG, LONG);
66
-	public static final OperatorMember ULONG_ADD_ULONG = add(ULONG, ULONG);
67
-	public static final OperatorMember FLOAT_ADD_FLOAT = add(FLOAT, FLOAT);
68
-	public static final OperatorMember DOUBLE_ADD_DOUBLE = add(DOUBLE, DOUBLE);
69
-	public static final OperatorMember STRING_ADD_STRING = add(STRING, STRING);
70
-	
71
-	public static final OperatorMember BYTE_SUB_BYTE = sub(BYTE, BYTE);
72
-	public static final OperatorMember SBYTE_SUB_SBYTE = sub(SBYTE, SBYTE);
73
-	public static final OperatorMember SHORT_SUB_SHORT = sub(SHORT, SHORT);
74
-	public static final OperatorMember USHORT_SUB_USHORT = sub(USHORT, USHORT);
75
-	public static final OperatorMember INT_SUB_INT = sub(INT, INT);
76
-	public static final OperatorMember UINT_SUB_UINT = sub(UINT, UINT);
77
-	public static final OperatorMember LONG_SUB_LONG = sub(LONG, LONG);
78
-	public static final OperatorMember ULONG_SUB_ULONG = sub(ULONG, ULONG);
79
-	public static final OperatorMember FLOAT_SUB_FLOAT = sub(FLOAT, FLOAT);
80
-	public static final OperatorMember DOUBLE_SUB_DOUBLE = sub(DOUBLE, DOUBLE);
81
-	
82
-	public static final OperatorMember BYTE_MUL_BYTE = mul(BYTE, BYTE);
83
-	public static final OperatorMember SBYTE_MUL_SBYTE = mul(SBYTE, SBYTE);
84
-	public static final OperatorMember SHORT_MUL_SHORT = mul(SHORT, SHORT);
85
-	public static final OperatorMember USHORT_MUL_USHORT = mul(USHORT, USHORT);
86
-	public static final OperatorMember INT_MUL_INT = mul(INT, INT);
87
-	public static final OperatorMember UINT_MUL_UINT = mul(UINT, UINT);
88
-	public static final OperatorMember LONG_MUL_LONG = mul(LONG, LONG);
89
-	public static final OperatorMember ULONG_MUL_ULONG = mul(ULONG, ULONG);
90
-	public static final OperatorMember FLOAT_MUL_FLOAT = mul(FLOAT, FLOAT);
91
-	public static final OperatorMember DOUBLE_MUL_DOUBLE = mul(DOUBLE, DOUBLE);
92
-	
93
-	public static final OperatorMember BYTE_DIV_BYTE = div(BYTE, BYTE);
94
-	public static final OperatorMember SBYTE_DIV_SBYTE = div(SBYTE, SBYTE);
95
-	public static final OperatorMember SHORT_DIV_SHORT = div(SHORT, SHORT);
96
-	public static final OperatorMember USHORT_DIV_USHORT = div(USHORT, USHORT);
97
-	public static final OperatorMember INT_DIV_INT = div(INT, INT);
98
-	public static final OperatorMember UINT_DIV_UINT = div(UINT, UINT);
99
-	public static final OperatorMember LONG_DIV_LONG = div(LONG, LONG);
100
-	public static final OperatorMember ULONG_DIV_ULONG = div(ULONG, ULONG);
101
-	public static final OperatorMember FLOAT_DIV_FLOAT = div(FLOAT, FLOAT);
102
-	public static final OperatorMember DOUBLE_DIV_DOUBLE = div(DOUBLE, DOUBLE);
103
-	
104
-	public static final OperatorMember BYTE_MOD_BYTE = mod(BYTE, BYTE);
105
-	public static final OperatorMember SBYTE_MOD_SBYTE = mod(SBYTE, SBYTE);
106
-	public static final OperatorMember SHORT_MOD_SHORT = mod(SHORT, SHORT);
107
-	public static final OperatorMember USHORT_MOD_USHORT = mod(USHORT, USHORT);
108
-	public static final OperatorMember INT_MOD_INT = mod(INT, INT);
109
-	public static final OperatorMember UINT_MOD_UINT = mod(UINT, UINT);
110
-	public static final OperatorMember LONG_MOD_LONG = mod(LONG, LONG);
111
-	public static final OperatorMember ULONG_MOD_ULONG = mod(ULONG, ULONG);
112
-	
113
-	public static final CasterMember INT_TO_BYTE = castExplicit(BYTE);
114
-	public static final CasterMember INT_TO_SBYTE = castExplicit(SBYTE);
115
-	public static final CasterMember INT_TO_SHORT = castExplicit(SHORT);
116
-	public static final CasterMember INT_TO_USHORT = castExplicit(USHORT);
117
-	public static final CasterMember INT_TO_UINT = castImplicit(UINT);
118
-	public static final CasterMember INT_TO_LONG = castImplicit(LONG);
119
-	public static final CasterMember INT_TO_ULONG = castImplicit(ULONG);
120
-	public static final CasterMember INT_TO_FLOAT = castImplicit(FLOAT);
121
-	public static final CasterMember INT_TO_DOUBLE = castImplicit(DOUBLE);
122
-	public static final CasterMember INT_TO_CHAR = castExplicit(CHAR);
123
-	public static final CasterMember INT_TO_STRING = castImplicit(STRING);
124
-	
125
-	public static final CasterMember LONG_TO_BYTE = castExplicit(BYTE);
126
-	public static final CasterMember LONG_TO_SBYTE = castExplicit(SBYTE);
127
-	public static final CasterMember LONG_TO_SHORT = castExplicit(SHORT);
128
-	public static final CasterMember LONG_TO_USHORT = castExplicit(USHORT);
129
-	public static final CasterMember LONG_TO_INT = castExplicit(INT);
130
-	public static final CasterMember LONG_TO_UINT = castExplicit(UINT);
131
-	public static final CasterMember LONG_TO_ULONG = castImplicit(ULONG);
132
-	public static final CasterMember LONG_TO_FLOAT = castImplicit(FLOAT);
133
-	public static final CasterMember LONG_TO_DOUBLE = castImplicit(DOUBLE);
134
-	public static final CasterMember LONG_TO_CHAR = castExplicit(CHAR);
135
-	public static final CasterMember LONG_TO_STRING = castImplicit(STRING);
136
-	
137
-	public static final GetterMember FLOAT_BITS = new GetterMember(BUILTIN, 0, "bits", UINT);
138
-	public static final GetterMember DOUBLE_BITS = new GetterMember(BUILTIN, 0, "bits", ULONG);
139
-	public static final MethodMember FLOAT_FROMBITS = new MethodMember(BUILTIN, Modifiers.STATIC, "fromBits", new FunctionHeader(FLOAT, new FunctionParameter(UINT)));
140
-	public static final MethodMember DOUBLE_FROMBITS = new MethodMember(BUILTIN, Modifiers.STATIC, "fromBits", new FunctionHeader(DOUBLE, new FunctionParameter(ULONG)));
141
-	
142
-	private static OperatorMember not(ITypeID result) {
143
-		return new OperatorMember(BUILTIN, 0, OperatorType.NOT, new FunctionHeader(result));
38
+	public static final ClassDefinition T_BOOL = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
39
+	public static final ClassDefinition T_BYTE = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
40
+	public static final ClassDefinition T_SBYTE = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
41
+	public static final ClassDefinition T_SHORT = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
42
+	public static final ClassDefinition T_USHORT = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
43
+	public static final ClassDefinition T_INT = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
44
+	public static final ClassDefinition T_UINT = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
45
+	public static final ClassDefinition T_LONG = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
46
+	public static final ClassDefinition T_ULONG = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
47
+	public static final ClassDefinition T_FLOAT = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
48
+	public static final ClassDefinition T_DOUBLE = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
49
+	public static final ClassDefinition T_CHAR = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
50
+	public static final ClassDefinition T_STRING = new ClassDefinition(BUILTIN, null, "not", Modifiers.EXPORT);
51
+	
52
+	public static final OperatorMember BOOL_NOT = not(T_BOOL, BOOL);
53
+	
54
+	public static final OperatorMember BYTE_NOT = not(T_BYTE, BYTE);
55
+	public static final OperatorMember SBYTE_NOT = not(T_SBYTE, SBYTE);
56
+	public static final OperatorMember SHORT_NOT = not(T_SHORT, SHORT);
57
+	public static final OperatorMember USHORT_NOT = not(T_USHORT, USHORT);
58
+	public static final OperatorMember INT_NOT = not(T_INT, INT);
59
+	public static final OperatorMember UINT_NOT = not(T_UINT, UINT);
60
+	public static final OperatorMember LONG_NOT = not(T_LONG, LONG);
61
+	public static final OperatorMember ULONG_NOT = not(T_ULONG, ULONG);
62
+	
63
+	public static final OperatorMember SBYTE_NEG = neg(T_SBYTE, SBYTE);
64
+	public static final OperatorMember SHORT_NEG = neg(T_SHORT, SHORT);
65
+	public static final OperatorMember INT_NEG = neg(T_INT, INT);
66
+	public static final OperatorMember LONG_NEG = neg(T_LONG, LONG);
67
+	public static final OperatorMember FLOAT_NEG = neg(T_FLOAT, FLOAT);
68
+	public static final OperatorMember DOUBLE_NEG = neg(T_DOUBLE, DOUBLE);
69
+	
70
+	public static final OperatorMember BYTE_ADD_BYTE = add(T_BYTE, BYTE, BYTE);
71
+	public static final OperatorMember SBYTE_ADD_SBYTE = add(T_SBYTE, SBYTE, SBYTE);
72
+	public static final OperatorMember SHORT_ADD_SHORT = add(T_SHORT, SHORT, SHORT);
73
+	public static final OperatorMember USHORT_ADD_USHORT = add(T_USHORT, USHORT, USHORT);
74
+	public static final OperatorMember INT_ADD_INT = add(T_INT, INT, INT);
75
+	public static final OperatorMember UINT_ADD_UINT = add(T_UINT, UINT, UINT);
76
+	public static final OperatorMember LONG_ADD_LONG = add(T_LONG, LONG, LONG);
77
+	public static final OperatorMember ULONG_ADD_ULONG = add(T_ULONG, ULONG, ULONG);
78
+	public static final OperatorMember FLOAT_ADD_FLOAT = add(T_FLOAT, FLOAT, FLOAT);
79
+	public static final OperatorMember DOUBLE_ADD_DOUBLE = add(T_DOUBLE, DOUBLE, DOUBLE);
80
+	public static final OperatorMember STRING_ADD_STRING = add(T_STRING, STRING, STRING);
81
+	
82
+	public static final OperatorMember BYTE_SUB_BYTE = sub(T_BYTE, BYTE, BYTE);
83
+	public static final OperatorMember SBYTE_SUB_SBYTE = sub(T_SBYTE, SBYTE, SBYTE);
84
+	public static final OperatorMember SHORT_SUB_SHORT = sub(T_SHORT, SHORT, SHORT);
85
+	public static final OperatorMember USHORT_SUB_USHORT = sub(T_USHORT, USHORT, USHORT);
86
+	public static final OperatorMember INT_SUB_INT = sub(T_INT, INT, INT);
87
+	public static final OperatorMember UINT_SUB_UINT = sub(T_UINT, UINT, UINT);
88
+	public static final OperatorMember LONG_SUB_LONG = sub(T_LONG, LONG, LONG);
89
+	public static final OperatorMember ULONG_SUB_ULONG = sub(T_ULONG, ULONG, ULONG);
90
+	public static final OperatorMember FLOAT_SUB_FLOAT = sub(T_FLOAT, FLOAT, FLOAT);
91
+	public static final OperatorMember DOUBLE_SUB_DOUBLE = sub(T_DOUBLE, DOUBLE, DOUBLE);
92
+	
93
+	public static final OperatorMember BYTE_MUL_BYTE = mul(T_BYTE, BYTE, BYTE);
94
+	public static final OperatorMember SBYTE_MUL_SBYTE = mul(T_SBYTE, SBYTE, SBYTE);
95
+	public static final OperatorMember SHORT_MUL_SHORT = mul(T_SHORT, SHORT, SHORT);
96
+	public static final OperatorMember USHORT_MUL_USHORT = mul(T_USHORT, USHORT, USHORT);
97
+	public static final OperatorMember INT_MUL_INT = mul(T_INT, INT, INT);
98
+	public static final OperatorMember UINT_MUL_UINT = mul(T_UINT, UINT, UINT);
99
+	public static final OperatorMember LONG_MUL_LONG = mul(T_LONG, LONG, LONG);
100
+	public static final OperatorMember ULONG_MUL_ULONG = mul(T_ULONG, ULONG, ULONG);
101
+	public static final OperatorMember FLOAT_MUL_FLOAT = mul(T_FLOAT, FLOAT, FLOAT);
102
+	public static final OperatorMember DOUBLE_MUL_DOUBLE = mul(T_DOUBLE, DOUBLE, DOUBLE);
103
+	
104
+	public static final OperatorMember BYTE_DIV_BYTE = div(T_BYTE, BYTE, BYTE);
105
+	public static final OperatorMember SBYTE_DIV_SBYTE = div(T_SBYTE, SBYTE, SBYTE);
106
+	public static final OperatorMember SHORT_DIV_SHORT = div(T_SHORT, SHORT, SHORT);
107
+	public static final OperatorMember USHORT_DIV_USHORT = div(T_USHORT, USHORT, USHORT);
108
+	public static final OperatorMember INT_DIV_INT = div(T_INT, INT, INT);
109
+	public static final OperatorMember UINT_DIV_UINT = div(T_UINT, UINT, UINT);
110
+	public static final OperatorMember LONG_DIV_LONG = div(T_LONG, LONG, LONG);
111
+	public static final OperatorMember ULONG_DIV_ULONG = div(T_ULONG, ULONG, ULONG);
112
+	public static final OperatorMember FLOAT_DIV_FLOAT = div(T_FLOAT, FLOAT, FLOAT);
113
+	public static final OperatorMember DOUBLE_DIV_DOUBLE = div(T_DOUBLE, DOUBLE, DOUBLE);
114
+	
115
+	public static final OperatorMember BYTE_MOD_BYTE = mod(T_BYTE, BYTE, BYTE);
116
+	public static final OperatorMember SBYTE_MOD_SBYTE = mod(T_SBYTE, SBYTE, SBYTE);
117
+	public static final OperatorMember SHORT_MOD_SHORT = mod(T_SHORT, SHORT, SHORT);
118
+	public static final OperatorMember USHORT_MOD_USHORT = mod(T_USHORT, USHORT, USHORT);
119
+	public static final OperatorMember INT_MOD_INT = mod(T_INT, INT, INT);
120
+	public static final OperatorMember UINT_MOD_UINT = mod(T_UINT, UINT, UINT);
121
+	public static final OperatorMember LONG_MOD_LONG = mod(T_LONG, LONG, LONG);
122
+	public static final OperatorMember ULONG_MOD_ULONG = mod(T_ULONG, ULONG, ULONG);
123
+	
124
+	public static final CasterMember INT_TO_BYTE = castExplicit(T_BYTE, BYTE);
125
+	public static final CasterMember INT_TO_SBYTE = castExplicit(T_SBYTE, SBYTE);
126
+	public static final CasterMember INT_TO_SHORT = castExplicit(T_SHORT, SHORT);
127
+	public static final CasterMember INT_TO_USHORT = castExplicit(T_USHORT, USHORT);
128
+	public static final CasterMember INT_TO_UINT = castImplicit(T_UINT, UINT);
129
+	public static final CasterMember INT_TO_LONG = castImplicit(T_LONG, LONG);
130
+	public static final CasterMember INT_TO_ULONG = castImplicit(T_ULONG, ULONG);
131
+	public static final CasterMember INT_TO_FLOAT = castImplicit(T_FLOAT, FLOAT);
132
+	public static final CasterMember INT_TO_DOUBLE = castImplicit(T_DOUBLE, DOUBLE);
133
+	public static final CasterMember INT_TO_CHAR = castExplicit(T_CHAR, CHAR);
134
+	public static final CasterMember INT_TO_STRING = castImplicit(T_STRING, STRING);
135
+	
136
+	public static final CasterMember LONG_TO_BYTE = castExplicit(T_BYTE, BYTE);
137
+	public static final CasterMember LONG_TO_SBYTE = castExplicit(T_SBYTE, SBYTE);
138
+	public static final CasterMember LONG_TO_SHORT = castExplicit(T_SHORT, SHORT);
139
+	public static final CasterMember LONG_TO_USHORT = castExplicit(T_USHORT, USHORT);
140
+	public static final CasterMember LONG_TO_INT = castExplicit(T_INT, INT);
141
+	public static final CasterMember LONG_TO_UINT = castExplicit(T_UINT, UINT);
142
+	public static final CasterMember LONG_TO_ULONG = castImplicit(T_ULONG, ULONG);
143
+	public static final CasterMember LONG_TO_FLOAT = castImplicit(T_FLOAT, FLOAT);
144
+	public static final CasterMember LONG_TO_DOUBLE = castImplicit(T_DOUBLE, DOUBLE);
145
+	public static final CasterMember LONG_TO_CHAR = castExplicit(T_CHAR, CHAR);
146
+	public static final CasterMember LONG_TO_STRING = castImplicit(T_STRING, STRING);
147
+	
148
+	public static final GetterMember FLOAT_BITS = new GetterMember(BUILTIN, T_FLOAT, 0, "bits", UINT);
149
+	public static final GetterMember DOUBLE_BITS = new GetterMember(BUILTIN, T_DOUBLE, 0, "bits", ULONG);
150
+	public static final MethodMember FLOAT_FROMBITS = new MethodMember(BUILTIN, T_FLOAT, Modifiers.STATIC, "fromBits", new FunctionHeader(FLOAT, new FunctionParameter(UINT)));
151
+	public static final MethodMember DOUBLE_FROMBITS = new MethodMember(BUILTIN, T_FLOAT, Modifiers.STATIC, "fromBits", new FunctionHeader(DOUBLE, new FunctionParameter(ULONG)));
152
+	
153
+	private static OperatorMember not(ClassDefinition cls, ITypeID result) {
154
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.NOT, new FunctionHeader(result));
144 155
 	}
145 156
 	
146
-	private static OperatorMember neg(ITypeID result) {
147
-		return new OperatorMember(BUILTIN, 0, OperatorType.NEG, new FunctionHeader(result));
157
+	private static OperatorMember neg(ClassDefinition cls, ITypeID result) {
158
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.NEG, new FunctionHeader(result));
148 159
 	}
149 160
 	
150
-	private static OperatorMember add(ITypeID operand, ITypeID result) {
151
-		return new OperatorMember(BUILTIN, 0, OperatorType.ADD, new FunctionHeader(result, new FunctionParameter(operand)));
161
+	private static OperatorMember add(ClassDefinition cls, ITypeID operand, ITypeID result) {
162
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.ADD, new FunctionHeader(result, new FunctionParameter(operand)));
152 163
 	}
153 164
 	
154
-	private static OperatorMember sub(ITypeID operand, ITypeID result) {
155
-		return new OperatorMember(BUILTIN, 0, OperatorType.SUB, new FunctionHeader(result, new FunctionParameter(operand)));
165
+	private static OperatorMember sub(ClassDefinition cls, ITypeID operand, ITypeID result) {
166
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.SUB, new FunctionHeader(result, new FunctionParameter(operand)));
156 167
 	}
157 168
 	
158
-	private static OperatorMember mul(ITypeID operand, ITypeID result) {
159
-		return new OperatorMember(BUILTIN, 0, OperatorType.MUL, new FunctionHeader(result, new FunctionParameter(operand)));
169
+	private static OperatorMember mul(ClassDefinition cls, ITypeID operand, ITypeID result) {
170
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.MUL, new FunctionHeader(result, new FunctionParameter(operand)));
160 171
 	}
161 172
 	
162
-	private static OperatorMember div(ITypeID operand, ITypeID result) {
163
-		return new OperatorMember(BUILTIN, 0, OperatorType.DIV, new FunctionHeader(result, new FunctionParameter(operand)));
173
+	private static OperatorMember div(ClassDefinition cls, ITypeID operand, ITypeID result) {
174
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.DIV, new FunctionHeader(result, new FunctionParameter(operand)));
164 175
 	}
165 176
 	
166
-	private static OperatorMember mod(ITypeID operand, ITypeID result) {
167
-		return new OperatorMember(BUILTIN, 0, OperatorType.MOD, new FunctionHeader(result, new FunctionParameter(operand)));
177
+	private static OperatorMember mod(ClassDefinition cls, ITypeID operand, ITypeID result) {
178
+		return new OperatorMember(BUILTIN, cls, 0, OperatorType.MOD, new FunctionHeader(result, new FunctionParameter(operand)));
168 179
 	}
169 180
 	
170
-	private static CasterMember castExplicit(ITypeID result) {
171
-		return new CasterMember(CodePosition.BUILTIN, 0, result);
181
+	private static CasterMember castExplicit(ClassDefinition cls, ITypeID result) {
182
+		return new CasterMember(CodePosition.BUILTIN, cls, 0, result);
172 183
 	}
173 184
 	
174
-	private static CasterMember castImplicit(ITypeID result) {
175
-		return new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, result);
185
+	private static CasterMember castImplicit(ClassDefinition cls, ITypeID result) {
186
+		return new CasterMember(CodePosition.BUILTIN, cls, Modifiers.IMPLICIT, result);
176 187
 	}
177 188
 }

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

@@ -15,6 +15,7 @@ import org.openzen.zenscript.codemodel.Modifiers;
15 15
 import org.openzen.zenscript.codemodel.OperatorType;
16 16
 import org.openzen.zenscript.codemodel.definition.ClassDefinition;
17 17
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
18
+import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
18 19
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
19 20
 import org.openzen.zenscript.codemodel.expression.CallTranslator;
20 21
 import org.openzen.zenscript.codemodel.expression.ConstantCharExpression;
@@ -51,7 +52,6 @@ import org.openzen.zenscript.codemodel.type.IteratorTypeID;
51 52
 import org.openzen.zenscript.codemodel.type.OptionalTypeID;
52 53
 import org.openzen.zenscript.codemodel.type.RangeTypeID;
53 54
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
54
-import org.openzen.zenscript.shared.CodePosition;
55 55
 import static org.openzen.zenscript.shared.CodePosition.BUILTIN;
56 56
 
57 57
 /**
@@ -101,6 +101,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
101 101
 
102 102
 	@Override
103 103
 	public Void visitArray(ArrayTypeID array) {
104
+		HighLevelDefinition definition = new ClassDefinition(BUILTIN, null, "", Modifiers.EXPORT);
104 105
 		ITypeID baseType = array.elementType;
105 106
 		int dimension = array.dimension;
106 107
 
@@ -109,16 +110,16 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
109 110
 			indexGetParameters[i] = new FunctionParameter(INT, null);
110 111
 
111 112
 		FunctionHeader indexGetHeader = new FunctionHeader(baseType, indexGetParameters);
112
-		members.addOperator(new OperatorMember(CodePosition.BUILTIN, 0, OperatorType.INDEXGET, indexGetHeader), TypeMemberPriority.SPECIFIED);
113
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.INDEXGET, indexGetHeader), TypeMemberPriority.SPECIFIED);
113 114
 		
114
-		FunctionHeader sliceHeader = new FunctionHeader(array, new FunctionParameter(cache.getRegistry().getRange(BasicTypeID.INT, BasicTypeID.INT), "range"));
115
-		members.addOperator(new OperatorMember(CodePosition.BUILTIN, 0, OperatorType.INDEXGET, sliceHeader), TypeMemberPriority.SPECIFIED);
115
+		FunctionHeader sliceHeader = new FunctionHeader(array, new FunctionParameter(cache.getRegistry().getRange(INT, INT), "range"));
116
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.INDEXGET, sliceHeader), TypeMemberPriority.SPECIFIED);
116 117
 		
117 118
 		FunctionHeader containsHeader = new FunctionHeader(BOOL, new FunctionParameter(baseType, "value"));
118
-		members.addOperator(new OperatorMember(CodePosition.BUILTIN, 0, OperatorType.CONTAINS, containsHeader), TypeMemberPriority.SPECIFIED);
119
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.CONTAINS, containsHeader), TypeMemberPriority.SPECIFIED);
119 120
 		
120 121
 		FunctionHeader sizedConstructorHeader = new FunctionHeader(VOID, indexGetParameters);
121
-		members.addConstructor(new ConstructorMember(CodePosition.BUILTIN, 0, sizedConstructorHeader), TypeMemberPriority.SPECIFIED);
122
+		members.addConstructor(new ConstructorMember(BUILTIN, definition, 0, sizedConstructorHeader), TypeMemberPriority.SPECIFIED);
122 123
 
123 124
 		FunctionParameter[] lambdaConstructorParameters = new FunctionParameter[dimension + 1];
124 125
 		for (int i = 0; i < dimension; i++)
@@ -127,7 +128,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
127 128
 		FunctionHeader lambdaConstructorFunction = new FunctionHeader(baseType, indexGetParameters);
128 129
 		lambdaConstructorParameters[dimension] = new FunctionParameter(cache.getRegistry().getFunction(lambdaConstructorFunction), null);
129 130
 		FunctionHeader lambdaConstructorHeader = new FunctionHeader(VOID, lambdaConstructorParameters);
130
-		members.addConstructor(new ConstructorMember(CodePosition.BUILTIN, 0, lambdaConstructorHeader), TypeMemberPriority.SPECIFIED);
131
+		members.addConstructor(new ConstructorMember(BUILTIN, definition, 0, lambdaConstructorHeader), TypeMemberPriority.SPECIFIED);
131 132
 		
132 133
 		FunctionParameter[] indexSetParameters = new FunctionParameter[dimension + 1];
133 134
 		for (int i = 0; i < dimension; i++)
@@ -135,21 +136,21 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
135 136
 		indexSetParameters[dimension] = new FunctionParameter(baseType, null);
136 137
 
137 138
 		FunctionHeader indexSetHeader = new FunctionHeader(VOID, indexSetParameters);
138
-		members.addOperator(new OperatorMember(CodePosition.BUILTIN, 0, OperatorType.INDEXSET, indexSetHeader), TypeMemberPriority.SPECIFIED);
139
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.INDEXSET, indexSetHeader), TypeMemberPriority.SPECIFIED);
139 140
 
140 141
 		if (dimension == 1) {
141
-			members.addConstructor(new ConstructorMember(CodePosition.BUILTIN, 0, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
142
+			members.addConstructor(new ConstructorMember(BUILTIN, definition, 0, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
142 143
 			
143 144
 			FunctionHeader addHeader = new FunctionHeader(VOID, new FunctionParameter(baseType, "value"));
144
-			members.addMethod(new MethodMember(CodePosition.BUILTIN, 0, "add", addHeader), TypeMemberPriority.SPECIFIED);
145
+			members.addMethod(new MethodMember(BUILTIN, definition, 0, "add", addHeader), TypeMemberPriority.SPECIFIED);
145 146
 
146
-			members.addField(new FieldMember(CodePosition.BUILTIN, Modifiers.FINAL, "length", INT), TypeMemberPriority.SPECIFIED);
147
+			members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "length", INT), TypeMemberPriority.SPECIFIED);
147 148
 		}
148 149
 
149
-		members.addGetter(new GetterMember(CodePosition.BUILTIN, 0, "empty", BOOL), TypeMemberPriority.SPECIFIED);
150
+		members.addGetter(new GetterMember(BUILTIN, definition, 0, "empty", BOOL), TypeMemberPriority.SPECIFIED);
150 151
 		members.addIterator(new ArrayIteratorKeyValues(array), TypeMemberPriority.SPECIFIED);
151 152
 		members.addIterator(new ArrayIteratorValues(array), TypeMemberPriority.SPECIFIED);
152
-		members.addMethod(new MethodMember(CodePosition.BUILTIN, 0, "clear", new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
153
+		members.addMethod(new MethodMember(BUILTIN, definition, 0, "clear", new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
153 154
 		return null;
154 155
 	}
155 156
 
@@ -158,22 +159,24 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
158 159
 		ITypeID keyType = assoc.keyType;
159 160
 		ITypeID valueType = assoc.valueType;
160 161
 		
161
-		members.addConstructor(new ConstructorMember(BUILTIN, 0, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
162
+		ClassDefinition definition = new ClassDefinition(BUILTIN, null, "", Modifiers.EXPORT);
163
+		
164
+		members.addConstructor(new ConstructorMember(BUILTIN, definition, 0, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
162 165
 
163 166
 		FunctionHeader indexGetHeader = new FunctionHeader(valueType, new FunctionParameter(keyType, "key"));
164
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.INDEXGET, indexGetHeader), TypeMemberPriority.SPECIFIED);
167
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.INDEXGET, indexGetHeader), TypeMemberPriority.SPECIFIED);
165 168
 
166 169
 		FunctionHeader indexSetHeader = new FunctionHeader(VOID, new FunctionParameter(keyType, "key"), new FunctionParameter(valueType, "value"));
167
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.INDEXSET, indexSetHeader), TypeMemberPriority.SPECIFIED);
170
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.INDEXSET, indexSetHeader), TypeMemberPriority.SPECIFIED);
168 171
 		
169 172
 		FunctionHeader getOrDefaultHeader = new FunctionHeader(valueType, new FunctionParameter(keyType, "key"), new FunctionParameter(valueType, "defaultValue"));
170
-		members.addMethod(new MethodMember(BUILTIN, 0, "getOrDefault", getOrDefaultHeader), TypeMemberPriority.SPECIFIED);
173
+		members.addMethod(new MethodMember(BUILTIN, definition, 0, "getOrDefault", getOrDefaultHeader), TypeMemberPriority.SPECIFIED);
171 174
 		
172
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.CONTAINS, new FunctionHeader(BOOL, new FunctionParameter(keyType, "key"))), TypeMemberPriority.SPECIFIED);
175
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.CONTAINS, new FunctionHeader(BOOL, new FunctionParameter(keyType, "key"))), TypeMemberPriority.SPECIFIED);
173 176
 
174
-		members.addField(new FieldMember(BUILTIN, Modifiers.FINAL, "length", INT), TypeMemberPriority.SPECIFIED);
175
-		members.addGetter(new GetterMember(BUILTIN, 0, "empty", BOOL), TypeMemberPriority.SPECIFIED);
176
-		members.addGetter(new GetterMember(BUILTIN, 0, "keys", cache.getRegistry().getArray(keyType, 1)), TypeMemberPriority.SPECIFIED);
177
+		members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "length", INT), TypeMemberPriority.SPECIFIED);
178
+		members.addGetter(new GetterMember(BUILTIN, definition, 0, "empty", BOOL), TypeMemberPriority.SPECIFIED);
179
+		members.addGetter(new GetterMember(BUILTIN, definition, 0, "keys", cache.getRegistry().getArray(keyType, 1)), TypeMemberPriority.SPECIFIED);
177 180
 		return null;
178 181
 	}
179 182
 	
@@ -184,7 +187,8 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
184 187
 
185 188
 	@Override
186 189
 	public Void visitFunction(FunctionTypeID function) {
187
-		members.addCaller(new CallerMember(BUILTIN, 0, function.header), TypeMemberPriority.SPECIFIED);
190
+		FunctionDefinition definition = new FunctionDefinition(BUILTIN, null, "", Modifiers.EXPORT, function.header);
191
+		members.addCaller(new CallerMember(BUILTIN, definition, 0, function.header), TypeMemberPriority.SPECIFIED);
188 192
 		return null;
189 193
 	}
190 194
 
@@ -194,7 +198,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
194 198
 		if (type.typeParameters.length > 0 || !type.outerTypeParameters.isEmpty()) {
195 199
 			Map<TypeParameter, ITypeID> mapping = new HashMap<>();
196 200
 			for (int i = 0; i < type.typeParameters.length; i++)
197
-				mapping.put(definition.genericParameters.get(i), type.typeParameters[i]);
201
+				mapping.put(definition.genericParameters[i], type.typeParameters[i]);
198 202
 			for (Map.Entry<TypeParameter, ITypeID> entry : type.outerTypeParameters.entrySet())
199 203
 				mapping.put(entry.getKey(), entry.getValue());
200 204
 			
@@ -211,10 +215,10 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
211 215
 		if (constructors.getMethodMembers().isEmpty()) {
212 216
 			if (definition instanceof ClassDefinition) {
213 217
 				// add default constructor
214
-				constructors.addMethod(new ConstructorMember(BUILTIN, Modifiers.PUBLIC, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
218
+				constructors.addMethod(new ConstructorMember(BUILTIN, definition, Modifiers.PUBLIC, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
215 219
 			} else if (definition instanceof StructDefinition) {
216 220
 				// add default struct constructors
217
-				constructors.addMethod(new ConstructorMember(BUILTIN, Modifiers.PUBLIC, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
221
+				constructors.addMethod(new ConstructorMember(BUILTIN, definition, Modifiers.PUBLIC, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
218 222
 				
219 223
 				List<FieldMember> fields = ((StructDefinition)definition).getFields();
220 224
 				if (!fields.isEmpty()) {
@@ -223,17 +227,17 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
223 227
 						FieldMember field = fields.get(i);
224 228
 						parameters[i] = new FunctionParameter(field.type, field.name, field.initializer, false);
225 229
 					}
226
-					constructors.addMethod(new ConstructorMember(BUILTIN, 0, new FunctionHeader(VOID, parameters)), TypeMemberPriority.SPECIFIED);
230
+					constructors.addMethod(new ConstructorMember(BUILTIN, definition, 0, new FunctionHeader(VOID, parameters)), TypeMemberPriority.SPECIFIED);
227 231
 				}
228 232
 			} else if (definition instanceof EnumDefinition) {
229 233
 				// add default constructor
230
-				constructors.addMethod(new ConstructorMember(BUILTIN, Modifiers.PRIVATE, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
234
+				constructors.addMethod(new ConstructorMember(BUILTIN, definition, Modifiers.PRIVATE, new FunctionHeader(VOID)), TypeMemberPriority.SPECIFIED);
231 235
 			}
232 236
 		}
233 237
 		
234 238
 		if (definition instanceof EnumDefinition) {
235
-			members.addGetter(new GetterMember(BUILTIN, 0, "name", BasicTypeID.STRING), TypeMemberPriority.SPECIFIED);
236
-			members.addGetter(new GetterMember(BUILTIN, 0, "ordinal", BasicTypeID.INT), TypeMemberPriority.SPECIFIED);
239
+			members.addGetter(new GetterMember(BUILTIN, definition, 0, "name", BasicTypeID.STRING), TypeMemberPriority.SPECIFIED);
240
+			members.addGetter(new GetterMember(BUILTIN, definition, 0, "ordinal", BasicTypeID.INT), TypeMemberPriority.SPECIFIED);
237 241
 		}
238 242
 		
239 243
 		return null;
@@ -254,8 +258,9 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
254 258
 		ITypeID fromType = range.from;
255 259
 		ITypeID toType = range.to;
256 260
 
257
-		members.addField(new FieldMember(BUILTIN, Modifiers.FINAL, "from", fromType), TypeMemberPriority.SPECIFIED);
258
-		members.addField(new FieldMember(BUILTIN, Modifiers.FINAL, "to", toType), TypeMemberPriority.SPECIFIED);
261
+		ClassDefinition definition = new ClassDefinition(BUILTIN, null, "", Modifiers.EXPORT);
262
+		members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "from", fromType), TypeMemberPriority.SPECIFIED);
263
+		members.addField(new FieldMember(BUILTIN, definition, Modifiers.FINAL, "to", toType), TypeMemberPriority.SPECIFIED);
259 264
 		members.addIterator(new RangeIterator(range), TypeMemberPriority.SPECIFIED);
260 265
 		return null;
261 266
 	}
@@ -290,27 +295,27 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
290 295
 		members.addOperator(OperatorType.COMPARE, new ComparatorMember(members.type), TypeMemberPriority.SPECIFIED);
291 296
 		
292 297
 		members.addOperator(INT_ADD_INT);
293
-		members.addOperator(add(LONG, LONG, castedTargetCall(LONG_ADD_LONG, INT_TO_LONG)));
294
-		members.addOperator(add(FLOAT, FLOAT, castedTargetCall(FLOAT_ADD_FLOAT, INT_TO_FLOAT)));
295
-		members.addOperator(add(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_ADD_DOUBLE, INT_TO_DOUBLE)));
298
+		members.addOperator(add(T_INT, LONG, LONG, castedTargetCall(LONG_ADD_LONG, INT_TO_LONG)));
299
+		members.addOperator(add(T_INT, FLOAT, FLOAT, castedTargetCall(FLOAT_ADD_FLOAT, INT_TO_FLOAT)));
300
+		members.addOperator(add(T_INT, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_ADD_DOUBLE, INT_TO_DOUBLE)));
296 301
 		
297 302
 		members.addOperator(INT_SUB_INT);
298
-		members.addOperator(sub(LONG, LONG, castedTargetCall(LONG_SUB_LONG, INT_TO_LONG)));
299
-		members.addOperator(sub(FLOAT, FLOAT, castedTargetCall(FLOAT_SUB_FLOAT, INT_TO_FLOAT)));
300
-		members.addOperator(sub(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_SUB_DOUBLE, INT_TO_DOUBLE)));
303
+		members.addOperator(sub(T_INT, LONG, LONG, castedTargetCall(LONG_SUB_LONG, INT_TO_LONG)));
304
+		members.addOperator(sub(T_INT, FLOAT, FLOAT, castedTargetCall(FLOAT_SUB_FLOAT, INT_TO_FLOAT)));
305
+		members.addOperator(sub(T_INT, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_SUB_DOUBLE, INT_TO_DOUBLE)));
301 306
 		
302 307
 		members.addOperator(INT_MUL_INT);
303
-		members.addOperator(mul(LONG, LONG, castedTargetCall(LONG_MUL_LONG, INT_TO_LONG)));
304
-		members.addOperator(mul(FLOAT, FLOAT, castedTargetCall(FLOAT_MUL_FLOAT, INT_TO_FLOAT)));
305
-		members.addOperator(mul(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_MUL_DOUBLE, INT_TO_DOUBLE)));
308
+		members.addOperator(mul(T_INT, LONG, LONG, castedTargetCall(LONG_MUL_LONG, INT_TO_LONG)));
309
+		members.addOperator(mul(T_INT, FLOAT, FLOAT, castedTargetCall(FLOAT_MUL_FLOAT, INT_TO_FLOAT)));
310
+		members.addOperator(mul(T_INT, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_MUL_DOUBLE, INT_TO_DOUBLE)));
306 311
 		
307 312
 		members.addOperator(INT_DIV_INT);
308
-		members.addOperator(div(LONG, LONG, castedTargetCall(LONG_DIV_LONG, INT_TO_LONG)));
309
-		members.addOperator(div(FLOAT, FLOAT, castedTargetCall(FLOAT_DIV_FLOAT, INT_TO_FLOAT)));
310
-		members.addOperator(div(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_DIV_DOUBLE, INT_TO_DOUBLE)));
313
+		members.addOperator(div(T_INT, LONG, LONG, castedTargetCall(LONG_DIV_LONG, INT_TO_LONG)));
314
+		members.addOperator(div(T_INT, FLOAT, FLOAT, castedTargetCall(FLOAT_DIV_FLOAT, INT_TO_FLOAT)));
315
+		members.addOperator(div(T_INT, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_DIV_DOUBLE, INT_TO_DOUBLE)));
311 316
 		
312 317
 		members.addOperator(INT_MOD_INT);
313
-		members.addOperator(mod(LONG, LONG, castedTargetCall(LONG_MOD_LONG, INT_TO_LONG)));
318
+		members.addOperator(mod(T_INT, LONG, LONG, castedTargetCall(LONG_MOD_LONG, INT_TO_LONG)));
314 319
 		
315 320
 		members.addGetter(INT_GET_MIN_VALUE);
316 321
 		members.addGetter(INT_GET_MAX_VALUE);
@@ -329,11 +334,11 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
329 334
 	}
330 335
 
331 336
 	private void visitUInt() {
332
-		registerUnaryOperations();
333
-		registerArithmeticOperations(UINT, UINT);
334
-		registerArithmeticOperations(ULONG, ULONG);
335
-		registerArithmeticOperations(FLOAT, FLOAT);
336
-		registerArithmeticOperations(DOUBLE, DOUBLE);
337
+		registerUnaryOperations(T_UINT);
338
+		registerArithmeticOperations(T_UINT, UINT, UINT);
339
+		registerArithmeticOperations(T_UINT, ULONG, ULONG);
340
+		registerArithmeticOperations(T_UINT, FLOAT, FLOAT);
341
+		registerArithmeticOperations(T_UINT, DOUBLE, DOUBLE);
337 342
 		members.addGetter(new ConstantGetterMember("MIN_VALUE", position -> new ConstantUIntExpression(position, 0)), TypeMemberPriority.SPECIFIED);
338 343
 		members.addGetter(new ConstantGetterMember("MAX_VALUE", position -> new ConstantUIntExpression(position, 0xFFFFFFFF)), TypeMemberPriority.SPECIFIED);
339 344
 	}
@@ -350,20 +355,20 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
350 355
 		members.addOperator(OperatorType.COMPARE, new ComparatorMember(members.type), TypeMemberPriority.SPECIFIED);
351 356
 		
352 357
 		members.addOperator(LONG_ADD_LONG);
353
-		members.addOperator(add(FLOAT, FLOAT, castedTargetCall(FLOAT_ADD_FLOAT, LONG_TO_FLOAT)));
354
-		members.addOperator(add(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_ADD_DOUBLE, LONG_TO_DOUBLE)));
358
+		members.addOperator(add(T_LONG, FLOAT, FLOAT, castedTargetCall(FLOAT_ADD_FLOAT, LONG_TO_FLOAT)));
359
+		members.addOperator(add(T_LONG, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_ADD_DOUBLE, LONG_TO_DOUBLE)));
355 360
 		
356 361
 		members.addOperator(LONG_SUB_LONG);
357
-		members.addOperator(sub(FLOAT, FLOAT, castedTargetCall(FLOAT_SUB_FLOAT, LONG_TO_FLOAT)));
358
-		members.addOperator(sub(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_SUB_DOUBLE, LONG_TO_DOUBLE)));
362
+		members.addOperator(sub(T_LONG, FLOAT, FLOAT, castedTargetCall(FLOAT_SUB_FLOAT, LONG_TO_FLOAT)));
363
+		members.addOperator(sub(T_LONG, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_SUB_DOUBLE, LONG_TO_DOUBLE)));
359 364
 		
360 365
 		members.addOperator(LONG_MUL_LONG);
361
-		members.addOperator(mul(FLOAT, FLOAT, castedTargetCall(FLOAT_MUL_FLOAT, LONG_TO_FLOAT)));
362
-		members.addOperator(mul(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_MUL_DOUBLE, LONG_TO_DOUBLE)));
366
+		members.addOperator(mul(T_LONG, FLOAT, FLOAT, castedTargetCall(FLOAT_MUL_FLOAT, LONG_TO_FLOAT)));
367
+		members.addOperator(mul(T_LONG, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_MUL_DOUBLE, LONG_TO_DOUBLE)));
363 368
 		
364 369
 		members.addOperator(LONG_DIV_LONG);
365
-		members.addOperator(div(FLOAT, FLOAT, castedTargetCall(FLOAT_DIV_FLOAT, LONG_TO_FLOAT)));
366
-		members.addOperator(div(DOUBLE, DOUBLE, castedTargetCall(DOUBLE_DIV_DOUBLE, LONG_TO_DOUBLE)));
370
+		members.addOperator(div(T_FLOAT, FLOAT, FLOAT, castedTargetCall(FLOAT_DIV_FLOAT, LONG_TO_FLOAT)));
371
+		members.addOperator(div(T_FLOAT, DOUBLE, DOUBLE, castedTargetCall(DOUBLE_DIV_DOUBLE, LONG_TO_DOUBLE)));
367 372
 		
368 373
 		members.addOperator(LONG_MOD_LONG);
369 374
 		
@@ -384,38 +389,38 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
384 389
 	}
385 390
 
386 391
 	private void visitChar() {
387
-		registerUnaryOperations();
388
-		registerArithmeticOperations(CHAR, CHAR);
389
-		registerArithmeticOperations(INT, INT);
390
-		registerArithmeticOperations(LONG, LONG);
391
-		registerArithmeticOperations(FLOAT, FLOAT);
392
-		registerArithmeticOperations(DOUBLE, DOUBLE);
392
+		registerUnaryOperations(T_CHAR);
393
+		registerArithmeticOperations(T_CHAR, CHAR, CHAR);
394
+		registerArithmeticOperations(T_CHAR, INT, INT);
395
+		registerArithmeticOperations(T_CHAR, LONG, LONG);
396
+		registerArithmeticOperations(T_CHAR, FLOAT, FLOAT);
397
+		registerArithmeticOperations(T_CHAR, DOUBLE, DOUBLE);
393 398
 		members.addGetter(new ConstantGetterMember("MIN_VALUE", position -> new ConstantCharExpression(position, (char)0)), TypeMemberPriority.SPECIFIED);
394 399
 		members.addGetter(new ConstantGetterMember("MAX_VALUE", position -> new ConstantCharExpression(position, (char)0xFFFF)), TypeMemberPriority.SPECIFIED);
395 400
 		
396
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, 0, BasicTypeID.BYTE), TypeMemberPriority.SPECIFIED);
397
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, 0, BasicTypeID.SBYTE), TypeMemberPriority.SPECIFIED);
398
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.SHORT), TypeMemberPriority.SPECIFIED);
399
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.USHORT), TypeMemberPriority.SPECIFIED);
400
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.INT), TypeMemberPriority.SPECIFIED);
401
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.UINT), TypeMemberPriority.SPECIFIED);
402
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.LONG), TypeMemberPriority.SPECIFIED);
403
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.ULONG), TypeMemberPriority.SPECIFIED);
404
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.FLOAT), TypeMemberPriority.SPECIFIED);
405
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.DOUBLE), TypeMemberPriority.SPECIFIED);
406
-		members.addCaster(new CasterMember(CodePosition.BUILTIN, Modifiers.IMPLICIT, BasicTypeID.STRING), TypeMemberPriority.SPECIFIED);
401
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, 0, BasicTypeID.BYTE), TypeMemberPriority.SPECIFIED);
402
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, 0, BasicTypeID.SBYTE), TypeMemberPriority.SPECIFIED);
403
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.SHORT), TypeMemberPriority.SPECIFIED);
404
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.USHORT), TypeMemberPriority.SPECIFIED);
405
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.INT), TypeMemberPriority.SPECIFIED);
406
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.UINT), TypeMemberPriority.SPECIFIED);
407
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.LONG), TypeMemberPriority.SPECIFIED);
408
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.ULONG), TypeMemberPriority.SPECIFIED);
409
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.FLOAT), TypeMemberPriority.SPECIFIED);
410
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.DOUBLE), TypeMemberPriority.SPECIFIED);
411
+		members.addCaster(new CasterMember(BUILTIN, T_CHAR, Modifiers.IMPLICIT, BasicTypeID.STRING), TypeMemberPriority.SPECIFIED);
407 412
 	}
408 413
 
409 414
 	private void visitString() {
410 415
 		FunctionHeader getIndexHeader = new FunctionHeader(CHAR, new FunctionParameter(INT));
411
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.INDEXGET, getIndexHeader), TypeMemberPriority.SPECIFIED);
416
+		members.addOperator(new OperatorMember(BUILTIN, T_STRING, 0, OperatorType.INDEXGET, getIndexHeader), TypeMemberPriority.SPECIFIED);
412 417
 
413
-		members.addGetter(new GetterMember(BUILTIN, 0, "length", INT), TypeMemberPriority.SPECIFIED);
418
+		members.addGetter(new GetterMember(BUILTIN, T_STRING, 0, "length", INT), TypeMemberPriority.SPECIFIED);
414 419
 
415 420
 		//FunctionHeader substringHeader = new FunctionHeader(STRING, new FunctionParameter(cache.getRegistry().getRange(INT, INT)));
416 421
 		//members.addOperator(OperatorType.INDEXGET, new SubstringMember(substringHeader), TypeMemberPriority.SPECIFIED);
417 422
 		
418
-		members.addConstructor(new ConstructorMember(BUILTIN, 0, new FunctionHeader(VOID, new FunctionParameter(cache.getRegistry().getArray(CHAR, 1), "characters"))), TypeMemberPriority.SPECIFIED);
423
+		members.addConstructor(new ConstructorMember(BUILTIN, T_STRING, 0, new FunctionHeader(VOID, new FunctionParameter(cache.getRegistry().getArray(CHAR, 1), "characters"))), TypeMemberPriority.SPECIFIED);
419 424
 		
420 425
 		members.addOperator(STRING_ADD_STRING);
421 426
 
@@ -439,44 +444,44 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
439 444
 		members.addOperator(STRING_ADD_STRING);
440 445
 	}
441 446
 
442
-	private void registerUnaryOperations() {
447
+	private void registerUnaryOperations(ClassDefinition definition) {
443 448
 		FunctionHeader unaryHeader = new FunctionHeader(members.type);
444
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.NEG, unaryHeader), TypeMemberPriority.SPECIFIED);
445
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.PRE_INCREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
446
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.PRE_DECREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
447
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.POST_INCREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
448
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.POST_DECREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
449
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.NEG, unaryHeader), TypeMemberPriority.SPECIFIED);
450
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.PRE_INCREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
451
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.PRE_DECREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
452
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.POST_INCREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
453
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.POST_DECREMENT, unaryHeader), TypeMemberPriority.SPECIFIED);
449 454
 
450 455
 		members.addOperator(OperatorType.COMPARE, new ComparatorMember(members.type), TypeMemberPriority.SPECIFIED);
451 456
 	}
452 457
 
453
-	private void registerArithmeticOperations(ITypeID otherType, ITypeID resultType) {
458
+	private void registerArithmeticOperations(ClassDefinition definition, ITypeID otherType, ITypeID resultType) {
454 459
 		FunctionHeader binaryHeader = new FunctionHeader(resultType, new FunctionParameter(otherType));
455
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.ADD, binaryHeader), TypeMemberPriority.SPECIFIED);
456
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.SUB, binaryHeader), TypeMemberPriority.SPECIFIED);
457
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.MUL, binaryHeader), TypeMemberPriority.SPECIFIED);
458
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.DIV, binaryHeader), TypeMemberPriority.SPECIFIED);
459
-		members.addOperator(new OperatorMember(BUILTIN, 0, OperatorType.MOD, binaryHeader), TypeMemberPriority.SPECIFIED);
460
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.ADD, binaryHeader), TypeMemberPriority.SPECIFIED);
461
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.SUB, binaryHeader), TypeMemberPriority.SPECIFIED);
462
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.MUL, binaryHeader), TypeMemberPriority.SPECIFIED);
463
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.DIV, binaryHeader), TypeMemberPriority.SPECIFIED);
464
+		members.addOperator(new OperatorMember(BUILTIN, definition, 0, OperatorType.MOD, binaryHeader), TypeMemberPriority.SPECIFIED);
460 465
 	}
461 466
 	
462
-	private static OperatorMember add(ITypeID operand, ITypeID result, CallTranslator translator) {
463
-		return new TranslatedOperatorMember(BUILTIN, 0, OperatorType.ADD, new FunctionHeader(result, new FunctionParameter(operand)), translator);
467
+	private static OperatorMember add(ClassDefinition definition, ITypeID operand, ITypeID result, CallTranslator translator) {
468
+		return new TranslatedOperatorMember(BUILTIN, definition, 0, OperatorType.ADD, new FunctionHeader(result, new FunctionParameter(operand)), translator);
464 469
 	}
465 470
 	
466
-	private static OperatorMember sub(ITypeID operand, ITypeID result, CallTranslator translator) {
467
-		return new TranslatedOperatorMember(BUILTIN, 0, OperatorType.SUB, new FunctionHeader(result, new FunctionParameter(operand)), translator);
471
+	private static OperatorMember sub(ClassDefinition definition, ITypeID operand, ITypeID result, CallTranslator translator) {
472
+		return new TranslatedOperatorMember(BUILTIN, definition, 0, OperatorType.SUB, new FunctionHeader(result, new FunctionParameter(operand)), translator);
468 473
 	}
469 474
 	
470
-	private static OperatorMember mul(ITypeID operand, ITypeID result, CallTranslator translator) {
471
-		return new TranslatedOperatorMember(BUILTIN, 0, OperatorType.MUL, new FunctionHeader(result, new FunctionParameter(operand)), translator);
475
+	private static OperatorMember mul(ClassDefinition definition, ITypeID operand, ITypeID result, CallTranslator translator) {
476
+		return new TranslatedOperatorMember(BUILTIN, definition, 0, OperatorType.MUL, new FunctionHeader(result, new FunctionParameter(operand)), translator);
472 477
 	}
473 478
 	
474
-	private static OperatorMember div(ITypeID operand, ITypeID result, CallTranslator translator) {
475
-		return new TranslatedOperatorMember(BUILTIN, 0, OperatorType.DIV, new FunctionHeader(result, new FunctionParameter(operand)), translator);
479
+	private static OperatorMember div(ClassDefinition definition, ITypeID operand, ITypeID result, CallTranslator translator) {
480
+		return new TranslatedOperatorMember(BUILTIN, definition, 0, OperatorType.DIV, new FunctionHeader(result, new FunctionParameter(operand)), translator);
476 481
 	}
477 482
 	
478
-	private static OperatorMember mod(ITypeID operand, ITypeID result, CallTranslator translator) {
479
-		return new TranslatedOperatorMember(BUILTIN, 0, OperatorType.MOD, new FunctionHeader(result, new FunctionParameter(operand)), translator);
483
+	private static OperatorMember mod(ClassDefinition definition, ITypeID operand, ITypeID result, CallTranslator translator) {
484
+		return new TranslatedOperatorMember(BUILTIN, definition, 0, OperatorType.MOD, new FunctionHeader(result, new FunctionParameter(operand)), translator);
480 485
 	}
481 486
 	
482 487
 	private static CallTranslator castedTargetCall(FunctionalMember member, CasterMember caster) {

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

@@ -12,11 +12,11 @@ import java.util.Map;
12 12
 import org.openzen.zenscript.codemodel.CompareType;
13 13
 import org.openzen.zenscript.codemodel.OperatorType;
14 14
 import org.openzen.zenscript.codemodel.expression.CallArguments;
15
+import org.openzen.zenscript.codemodel.expression.CallExpression;
15 16
 import org.openzen.zenscript.codemodel.expression.CheckNullExpression;
16 17
 import org.openzen.zenscript.codemodel.expression.Expression;
17 18
 import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
18 19
 import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
19
-import org.openzen.zenscript.codemodel.expression.NotExpression;
20 20
 import org.openzen.zenscript.codemodel.expression.NullExpression;
21 21
 import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
22 22
 import org.openzen.zenscript.codemodel.member.CallerMember;
@@ -241,8 +241,10 @@ public final class TypeMembers {
241 241
 		} else if (operator == CompareType.NE) {
242 242
 			DefinitionMemberGroup equal = getOrCreateGroup(OperatorType.EQUALS);
243 243
 			for (TypeMember<ICallableMember> member : equal.getMethodMembers()) {
244
-				if (member.member.getHeader().accepts(scope, right))
245
-					return new NotExpression(position, equal.call(position, scope, left, new CallArguments(right), false));
244
+				if (member.member.getHeader().accepts(scope, right)) {
245
+					Expression equalExpression = equal.call(position, scope, left, new CallArguments(right), false);
246
+					return new CallExpression(position, equalExpression, BuiltinTypeMembers.BOOL_NOT, BuiltinTypeMembers.BOOL_NOT.header, CallArguments.EMPTY);
247
+				}
246 248
 			}
247 249
 		}
248 250
 		

+ 1
- 4
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java View File

@@ -48,14 +48,10 @@ public class JavaCompiler {
48 48
 		implement(LONG_NOT, JavaWriter::lNot);
49 49
 		implement(ULONG_NOT, JavaWriter::lNot);
50 50
 		
51
-		implement(BYTE_NEG, JavaWriter::iNeg);
52 51
 		implement(SBYTE_NEG, JavaWriter::iNeg);
53 52
 		implement(SHORT_NEG, JavaWriter::iNeg);
54
-		implement(USHORT_NEG, JavaWriter::iNeg);
55 53
 		implement(INT_NEG, JavaWriter::iNeg);
56
-		implement(UINT_NEG, JavaWriter::iNeg);
57 54
 		implement(LONG_NEG, JavaWriter::lNeg);
58
-		implement(ULONG_NEG, JavaWriter::lNeg);
59 55
 		implement(FLOAT_NEG, JavaWriter::fNeg);
60 56
 		implement(DOUBLE_NEG, JavaWriter::dNeg);
61 57
 		
@@ -160,6 +156,7 @@ public class JavaCompiler {
160 156
 			methodName = "generatedBlock" + (generatedScriptBlockCounter++);
161 157
 		} else {
162 158
 			// TODO: remove special characters
159
+			System.out.println("Writing script: " + sourceFile.filename);
163 160
 			methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
164 161
 		}
165 162
 

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

@@ -2,7 +2,6 @@ package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.objectweb.asm.Label;
4 4
 import org.objectweb.asm.Type;
5
-import org.openzen.zenscript.codemodel.CompareType;
6 5
 import org.openzen.zenscript.codemodel.expression.*;
7 6
 import org.openzen.zenscript.codemodel.member.DefinitionMember;
8 7
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
@@ -295,16 +294,6 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
295 294
         return null;
296 295
     }
297 296
 
298
-    @Override
299
-    public Void visitEquals(EqualsExpression expression) {
300
-        expression.left.accept(this);
301
-        expression.right.accept(this);
302
-        javaWriter.constant(CompareType.EQ.name());
303
-        javaWriter.invokeStatic(ZenUtils.class, "compare", boolean.class, getForEquals(expression.left.type), getForEquals(expression.right.type), String.class);
304
-
305
-        return null;
306
-    }
307
-
308 297
     @Override
309 298
     public Void visitFunction(FunctionExpression expression) {
310 299
         return null;
@@ -352,6 +341,16 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
352 341
         return null;
353 342
     }
354 343
 
344
+    @Override
345
+    public Void visitGlobal(GlobalExpression expression) {
346
+        return expression.resolution.accept(this);
347
+    }
348
+
349
+    @Override
350
+    public Void visitGlobalCall(GlobalCallExpression expression) {
351
+        return expression.resolution.accept(this);
352
+    }
353
+
355 354
     @Override
356 355
     public Void visitInterfaceCast(InterfaceCastExpression expression) {
357 356
         expression.value.accept(this);
@@ -408,13 +407,6 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
408 407
         return null;
409 408
     }
410 409
 
411
-    @Override
412
-    public Void visitNot(NotExpression expression) {
413
-        expression.value.accept(this);
414
-        javaWriter.iNeg();
415
-        return null;
416
-    }
417
-
418 410
     @Override
419 411
     public Void visitNull(NullExpression expression) {
420 412
         javaWriter.aConstNull();

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

@@ -0,0 +1,111 @@
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.javabytecode.compiler;
7
+
8
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
9
+import org.openzen.zenscript.codemodel.type.AssocTypeID;
10
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
11
+import org.openzen.zenscript.codemodel.type.ConstTypeID;
12
+import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
13
+import org.openzen.zenscript.codemodel.type.FunctionTypeID;
14
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
15
+import org.openzen.zenscript.codemodel.type.ITypeVisitor;
16
+import org.openzen.zenscript.codemodel.type.IteratorTypeID;
17
+import org.openzen.zenscript.codemodel.type.OptionalTypeID;
18
+import org.openzen.zenscript.codemodel.type.RangeTypeID;
19
+
20
+/**
21
+ *
22
+ * @author Hoofdgebruiker
23
+ */
24
+public class JavaOptionalTypeClassVisitor implements ITypeVisitor<Class> {
25
+	private final JavaTypeClassVisitor base;
26
+	
27
+	public JavaOptionalTypeClassVisitor(JavaTypeClassVisitor base) {
28
+		this.base = base;
29
+	}
30
+
31
+	@Override
32
+	public Class visitBasic(BasicTypeID basic) {
33
+		switch (basic) {
34
+			case VOID:
35
+				return void.class;
36
+			case NULL:
37
+				return Object.class;
38
+			case ANY:
39
+				return Object.class; // TODO
40
+			case BOOL:
41
+				return Boolean.class;
42
+			case BYTE:
43
+			case SBYTE:
44
+				return Byte.class;
45
+			case SHORT:
46
+			case USHORT:
47
+				return Short.class;
48
+			case INT:
49
+			case UINT:
50
+				return Integer.class;
51
+			case LONG:
52
+			case ULONG:
53
+				return Long.class;
54
+			case FLOAT:
55
+				return Float.class;
56
+			case DOUBLE:
57
+				return Double.class;
58
+			case CHAR:
59
+				return Character.class;
60
+			case STRING:
61
+				return String.class;
62
+			default:
63
+				throw new IllegalArgumentException("Invalid type: " + basic);
64
+		}
65
+	}
66
+
67
+	@Override
68
+	public Class visitArray(ArrayTypeID array) {
69
+		return base.visitArray(array);
70
+	}
71
+
72
+	@Override
73
+	public Class visitAssoc(AssocTypeID assoc) {
74
+		return base.visitAssoc(assoc);
75
+	}
76
+
77
+	@Override
78
+	public Class visitIterator(IteratorTypeID iterator) {
79
+		return base.visitIterator(iterator);
80
+	}
81
+
82
+	@Override
83
+	public Class visitFunction(FunctionTypeID function) {
84
+		return base.visitFunction(function);
85
+	}
86
+
87
+	@Override
88
+	public Class visitDefinition(DefinitionTypeID definition) {
89
+		return base.visitDefinition(definition);
90
+	}
91
+
92
+	@Override
93
+	public Class visitGeneric(GenericTypeID generic) {
94
+		return base.visitGeneric(generic);
95
+	}
96
+
97
+	@Override
98
+	public Class visitRange(RangeTypeID range) {
99
+		return base.visitRange(range);
100
+	}
101
+
102
+	@Override
103
+	public Class visitConst(ConstTypeID type) {
104
+		return base.visitConst(type);
105
+	}
106
+
107
+	@Override
108
+	public Class visitOptional(OptionalTypeID optional) {
109
+		return base.visitOptional(optional);
110
+	}
111
+}

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

@@ -9,6 +9,7 @@ import java.util.Map;
9 9
 public class JavaTypeClassVisitor implements ITypeVisitor<Class> {
10 10
 
11 11
     public static final JavaTypeClassVisitor INSTANCE = new JavaTypeClassVisitor();
12
+	private final JavaOptionalTypeClassVisitor optional = new JavaOptionalTypeClassVisitor(this);
12 13
 
13 14
     @Override
14 15
     public Class visitBasic(BasicTypeID basic) {
@@ -87,6 +88,6 @@ public class JavaTypeClassVisitor implements ITypeVisitor<Class> {
87 88
 
88 89
     @Override
89 90
     public Class visitOptional(OptionalTypeID optional) {
90
-        return optional.baseType.accept(this);
91
+        return optional.baseType.accept(this.optional);
91 92
     }
92 93
 }

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

@@ -16,7 +16,7 @@ import static org.objectweb.asm.Opcodes.*;
16 16
 public class JavaWriter {
17 17
     private final LocalVariablesSorter visitor;
18 18
     private final List<JavaLocalVariableInfo> localVariableInfos = new ArrayList<>();
19
-    private boolean debug = true;
19
+    private boolean debug = false;
20 20
     private boolean nameVariables = true;
21 21
     private int labelIndex = 1;
22 22
     private Map<Label, String> labelNames = new HashMap<>();

+ 6
- 3
Linker/src/main/java/org/openzen/zenscript/linker/FileScope.java View File

@@ -17,6 +17,7 @@ import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
17 17
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
18 18
 import org.openzen.zenscript.codemodel.expression.Expression;
19 19
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
20
+import org.openzen.zenscript.codemodel.partial.PartialGlobalExpression;
20 21
 import org.openzen.zenscript.codemodel.partial.PartialTypeExpression;
21 22
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
22 23
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
@@ -74,8 +75,10 @@ public class FileScope extends BaseScope {
74 75
 		if (localDefinition != null)
75 76
 			return new PartialTypeExpression(position, globalRegistry.getForDefinition(localDefinition, name.arguments));
76 77
 		
77
-		if (globalSymbols.containsKey(name.name))
78
-			return globalSymbols.get(name.name).getExpression(position, globalRegistry, name.arguments);
78
+		if (globalSymbols.containsKey(name.name)) {
79
+			IPartialExpression resolution = globalSymbols.get(name.name).getExpression(position, globalRegistry, name.arguments);
80
+			return new PartialGlobalExpression(position, name.name, resolution);
81
+		}
79 82
 		
80 83
 		return rootPackage.getMember(position, globalRegistry, name);
81 84
 	}
@@ -100,7 +103,7 @@ public class FileScope extends BaseScope {
100 103
 			}
101 104
 			
102 105
 			// TODO: take care of non-static inner classes in generic classes!
103
-			if (type != null && name.get(name.size() - 1).arguments.size() != type.definition.genericParameters.size())
106
+			if (type != null && name.get(name.size() - 1).arguments.size() != type.definition.genericParameters.length)
104 107
 				throw new CompileException(position, CompileExceptionCode.TYPE_ARGUMENTS_INVALID_NUMBER, "Invalid number of type arguments");
105 108
 			
106 109
 			if (type != null)

+ 2
- 0
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java View File

@@ -44,6 +44,8 @@ public class ZSTokenStream extends TokenStream<ZSToken, ZSTokenType> {
44 44
 		KEYWORDS.put("static", K_STATIC);
45 45
 		KEYWORDS.put("protected", K_PROTECTED);
46 46
 		KEYWORDS.put("implicit", K_IMPLICIT);
47
+		KEYWORDS.put("virtual", K_VIRTUAL);
48
+		KEYWORDS.put("extern", K_EXTERN);
47 49
 		
48 50
 		KEYWORDS.put("val", K_VAL);
49 51
 		KEYWORDS.put("var", K_VAR);

+ 2
- 0
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java View File

@@ -90,6 +90,8 @@ public enum ZSTokenType implements TokenType {
90 90
 	K_STATIC,
91 91
 	K_PROTECTED,
92 92
 	K_IMPLICIT,
93
+	K_VIRTUAL,
94
+	K_EXTERN,
93 95
 	
94 96
 	K_VAL,
95 97
 	K_VAR,

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

@@ -62,24 +62,36 @@ public class ParsedFile {
62 62
 		while (true) {
63 63
 			CodePosition position = tokens.peek().position;
64 64
 			int modifiers = 0;
65
-			while (true) {
66
-				if (tokens.optional(K_PUBLIC) != null) {
67
-					modifiers |= Modifiers.PUBLIC;
68
-				} else if (tokens.optional(K_PRIVATE) != null) {
69
-					modifiers |= Modifiers.PRIVATE;
70
-				} else if (tokens.optional(K_EXPORT) != null) {
71
-					modifiers |= Modifiers.EXPORT;
72
-				} else if (tokens.optional(K_ABSTRACT) != null) {
73
-					modifiers |= Modifiers.ABSTRACT;
74
-				} else if (tokens.optional(K_FINAL) != null) {
75
-					modifiers |= Modifiers.FINAL;
76
-				} else if (tokens.optional(K_PROTECTED) != null) {
77
-					modifiers |= Modifiers.PROTECTED;
78
-				} else if (tokens.optional(K_IMPLICIT) != null) {
79
-					modifiers |= Modifiers.IMPLICIT;
80
-				} else {
81
-					break;
65
+			outer: while (true) {
66
+				switch (tokens.peek().type) {
67
+					case K_PUBLIC:
68
+						modifiers |= Modifiers.PUBLIC;
69
+						break;
70
+					case K_PRIVATE:
71
+						modifiers |= Modifiers.PRIVATE;
72
+						break;
73
+					case K_EXPORT:
74
+						modifiers |= Modifiers.EXPORT;
75
+						break;
76
+					case K_ABSTRACT:
77
+						modifiers |= Modifiers.ABSTRACT;
78
+						break;
79
+					case K_FINAL:
80
+						modifiers |= Modifiers.FINAL;
81
+						break;
82
+					case K_PROTECTED:
83
+						modifiers |= Modifiers.PROTECTED;
84
+						break;
85
+					case K_IMPLICIT:
86
+						modifiers |= Modifiers.IMPLICIT;
87
+						break;
88
+					case K_VIRTUAL:
89
+						modifiers |= Modifiers.VIRTUAL;
90
+						break;
91
+					default:
92
+						break outer;
82 93
 				}
94
+				tokens.next();
83 95
 			}
84 96
 
85 97
 			if (tokens.optional(K_IMPORT) != null) {

+ 1
- 1
Parser/src/main/java/org/openzen/zenscript/parser/definitions/BaseParsedDefinition.java View File

@@ -31,7 +31,7 @@ public abstract class BaseParsedDefinition extends ParsedDefinition {
31 31
 	@Override
32 32
 	public void linkInnerTypes() {
33 33
 		for (ParsedDefinitionMember member : members)
34
-			member.linkInnerTypes(getCompiled());
34
+			member.linkInnerTypes();
35 35
 	}
36 36
 
37 37
 	@Override

+ 8
- 4
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedAlias.java View File

@@ -53,13 +53,17 @@ public class ParsedAlias extends ParsedDefinition {
53 53
 
54 54
 	@Override
55 55
 	public void compileMembers(BaseScope scope) {
56
-		for (ParsedGenericParameter parameter : this.parameters) {
57
-			compiled.addGenericParameter(parameter.compiled);
56
+		if (parameters.size() > 0) {
57
+			TypeParameter[] typeParameters = new TypeParameter[parameters.size()];
58
+			for (int i = 0; i < parameters.size(); i++) {
59
+				typeParameters[i] = parameters.get(i).compiled;
60
+			}
61
+			compiled.setTypeParameters(typeParameters);
58 62
 		}
59 63
 		
60 64
 		DefinitionScope innerScope = new DefinitionScope(scope, compiled);
61
-		for (int i = 0; i < compiled.genericParameters.size(); i++) {
62
-			TypeParameter output = compiled.genericParameters.get(i);
65
+		for (int i = 0; i < compiled.genericParameters.length; i++) {
66
+			TypeParameter output = compiled.genericParameters[i];
63 67
 			ParsedGenericParameter input = this.parameters.get(i);
64 68
 			for (ParsedGenericBound bound : input.bounds) {
65 69
 				output.addBound(bound.compile(innerScope));

+ 3
- 5
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedClass.java View File

@@ -9,7 +9,6 @@ import java.util.List;
9 9
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 10
 import org.openzen.zenscript.codemodel.definition.ClassDefinition;
11 11
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
12
-import org.openzen.zenscript.codemodel.generic.TypeParameter;
13 12
 import org.openzen.zenscript.lexer.ZSTokenStream;
14 13
 import org.openzen.zenscript.lexer.ZSTokenType;
15 14
 import org.openzen.zenscript.linker.BaseScope;
@@ -53,8 +52,7 @@ public class ParsedClass extends BaseParsedDefinition {
53 52
 		this.superclass = superclass;
54 53
 		
55 54
 		compiled = new ClassDefinition(position, pkg, name, modifiers, outerDefinition);
56
-		for (ParsedGenericParameter parameter : genericParameters)
57
-			compiled.addGenericParameter(parameter.compiled);
55
+		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(genericParameters));
58 56
 	}
59 57
 
60 58
 	@Override
@@ -64,9 +62,9 @@ public class ParsedClass extends BaseParsedDefinition {
64 62
 
65 63
 	@Override
66 64
 	public void compileMembers(BaseScope scope) {
67
-		TypeParameter[] parameters = ParsedGenericParameter.compile(scope, genericParameters);
65
+		ParsedGenericParameter.compile(scope, compiled.genericParameters, genericParameters);
68 66
 		if (superclass != null)
69
-			compiled.setSuperclass(superclass.compile(new GenericFunctionScope(scope, parameters)));
67
+			compiled.setSuperclass(superclass.compile(new GenericFunctionScope(scope, compiled.genericParameters)));
70 68
 		
71 69
 		super.compileMembers(scope);
72 70
 	}

+ 9
- 7
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedEnum.java View File

@@ -28,14 +28,14 @@ public class ParsedEnum extends BaseParsedDefinition {
28 28
 		String name = tokens.required(ZSTokenType.T_IDENTIFIER, "identifier expected").content;
29 29
 		tokens.required(ZSTokenType.T_AOPEN, "{ expected");
30 30
 		
31
-		List<ParsedEnumConstant> enumValues = new ArrayList<>();
31
+		ParsedEnum result = new ParsedEnum(pkg, position, modifiers, name, outerDefinition);
32
+		
32 33
 		while (!tokens.isNext(ZSTokenType.T_ACLOSE) && !tokens.isNext(ZSTokenType.T_SEMICOLON)) {
33
-			enumValues.add(ParsedEnumConstant.parse(tokens, enumValues.size()));
34
+			result.addEnumValue(ParsedEnumConstant.parse(tokens, result.compiled, result.enumValues.size()));
34 35
 			if (tokens.optional(ZSTokenType.T_COMMA) == null)
35 36
 				break;
36 37
 		}
37 38
 		
38
-		ParsedEnum result = new ParsedEnum(pkg, position, modifiers, name, enumValues, outerDefinition);
39 39
 		if (tokens.optional(ZSTokenType.T_SEMICOLON) != null) {
40 40
 			while (tokens.optional(ZSTokenType.T_ACLOSE) == null) {
41 41
 				result.addMember(ParsedDefinitionMember.parse(tokens, result.compiled));
@@ -46,17 +46,19 @@ public class ParsedEnum extends BaseParsedDefinition {
46 46
 		return result;
47 47
 	}
48 48
 	
49
-	private final List<ParsedEnumConstant> enumValues;
49
+	private final List<ParsedEnumConstant> enumValues = new ArrayList<>();
50 50
 	
51 51
 	private final EnumDefinition compiled;
52 52
 	
53
-	public ParsedEnum(ZSPackage pkg, CodePosition position, int modifiers, String name, List<ParsedEnumConstant> enumValues, HighLevelDefinition outerDefinition) {
53
+	public ParsedEnum(ZSPackage pkg, CodePosition position, int modifiers, String name, HighLevelDefinition outerDefinition) {
54 54
 		super(position, modifiers);
55 55
 		
56
-		this.enumValues = enumValues;
57
-		
58 56
 		compiled = new EnumDefinition(position, pkg, name, modifiers, outerDefinition);
59 57
 	}
58
+	
59
+	public void addEnumValue(ParsedEnumConstant value) {
60
+		enumValues.add(value);
61
+	}
60 62
 
61 63
 	@Override
62 64
 	public HighLevelDefinition getCompiled() {

+ 6
- 4
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedEnumConstant.java View File

@@ -7,6 +7,8 @@ package org.openzen.zenscript.parser.definitions;
7 7
 
8 8
 import java.util.ArrayList;
9 9
 import java.util.List;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
10 12
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
11 13
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
12 14
 import org.openzen.zenscript.lexer.ZSToken;
@@ -23,7 +25,7 @@ import org.openzen.zenscript.shared.CodePosition;
23 25
  * @author Hoofdgebruiker
24 26
  */
25 27
 public class ParsedEnumConstant {
26
-	public static ParsedEnumConstant parse(ZSTokenStream tokens, int value) {
28
+	public static ParsedEnumConstant parse(ZSTokenStream tokens, EnumDefinition definition, int value) {
27 29
 		ZSToken name = tokens.required(ZSTokenType.T_IDENTIFIER, "identifier expected");
28 30
 		List<ParsedExpression> arguments = new ArrayList<>();
29 31
 		if (tokens.optional(ZSTokenType.T_BROPEN) != null) {
@@ -33,7 +35,7 @@ public class ParsedEnumConstant {
33 35
 			tokens.required(ZSTokenType.T_BRCLOSE, ") expected");
34 36
 		}
35 37
 		
36
-		return new ParsedEnumConstant(name.position, name.content, value, arguments);
38
+		return new ParsedEnumConstant(name.position, definition, name.content, value, arguments);
37 39
 	}
38 40
 	
39 41
 	public final CodePosition position;
@@ -42,12 +44,12 @@ public class ParsedEnumConstant {
42 44
 	
43 45
 	private final EnumConstantMember compiled;
44 46
 	
45
-	public ParsedEnumConstant(CodePosition position, String name, int value, List<ParsedExpression> arguments) {
47
+	public ParsedEnumConstant(CodePosition position, HighLevelDefinition definition, String name, int value, List<ParsedExpression> arguments) {
46 48
 		this.position = position;
47 49
 		this.name = name;
48 50
 		this.arguments = arguments;
49 51
 		
50
-		compiled = new EnumConstantMember(position, name, value);
52
+		compiled = new EnumConstantMember(position, definition, name, value);
51 53
 	}
52 54
 	
53 55
 	public EnumConstantMember getCompiled() {

+ 6
- 8
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedExpansion.java View File

@@ -9,7 +9,6 @@ import java.util.List;
9 9
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10 10
 import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
11 11
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
12
-import org.openzen.zenscript.codemodel.generic.TypeParameter;
13 12
 import org.openzen.zenscript.lexer.ZSTokenStream;
14 13
 import org.openzen.zenscript.lexer.ZSTokenType;
15 14
 import org.openzen.zenscript.linker.BaseScope;
@@ -39,15 +38,14 @@ public class ParsedExpansion extends BaseParsedDefinition {
39 38
 	private final IParsedType target;
40 39
 	private final ExpansionDefinition compiled;
41 40
 	
42
-	public ParsedExpansion(ZSPackage pkg, CodePosition position, int modifiers, List<ParsedGenericParameter> parameters, IParsedType target, HighLevelDefinition outerDefinition) {
41
+	public ParsedExpansion(ZSPackage pkg, CodePosition position, int modifiers, List<ParsedGenericParameter> genericParameters, IParsedType target, HighLevelDefinition outerDefinition) {
43 42
 		super(position, modifiers);
44 43
 		
45
-		this.parameters = parameters;
44
+		this.parameters = genericParameters;
46 45
 		this.target = target;
47 46
 		
48
-		this.compiled = new ExpansionDefinition(position, pkg, modifiers, outerDefinition);
49
-		for (ParsedGenericParameter parameter : parameters)
50
-			compiled.addGenericParameter(parameter.compiled);
47
+		compiled = new ExpansionDefinition(position, pkg, modifiers, outerDefinition);
48
+		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(genericParameters));
51 49
 	}
52 50
 	
53 51
 	@Override
@@ -57,8 +55,8 @@ public class ParsedExpansion extends BaseParsedDefinition {
57 55
 
58 56
 	@Override
59 57
 	public void compileMembers(BaseScope scope) {
60
-		TypeParameter[] parameters = ParsedGenericParameter.compile(scope, this.parameters);
61
-		compiled.target = target.compile(new GenericFunctionScope(scope, parameters));
58
+		ParsedGenericParameter.compile(scope, compiled.genericParameters, this.parameters);
59
+		compiled.target = target.compile(new GenericFunctionScope(scope, compiled.genericParameters));
62 60
 		
63 61
 		super.compileMembers(scope);
64 62
 	}

+ 3
- 1
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunctionHeader.java View File

@@ -87,8 +87,10 @@ public class ParsedFunctionHeader {
87 87
 	}
88 88
 	
89 89
 	public FunctionHeader compile(BaseScope scope) {
90
-		TypeParameter[] genericParameters = ParsedGenericParameter.compile(scope, this.genericParameters);
90
+		TypeParameter[] genericParameters = ParsedGenericParameter.getCompiled(this.genericParameters);
91
+		ParsedGenericParameter.compile(scope, genericParameters, this.genericParameters);
91 92
 		GenericFunctionScope innerScope = new GenericFunctionScope(scope, genericParameters);
93
+		
92 94
 		ITypeID returnType = this.returnType.compile(innerScope);
93 95
 		FunctionParameter[] parameters = new FunctionParameter[this.parameters.size()];
94 96
 		for (int i = 0; i < parameters.length; i++)

+ 15
- 7
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedGenericParameter.java View File

@@ -45,17 +45,25 @@ public class ParsedGenericParameter {
45 45
 		return genericParameters;
46 46
 	}
47 47
 	
48
-	public static TypeParameter[] compile(BaseScope scope, List<ParsedGenericParameter> parameters) {
49
-		TypeParameter[] result = new TypeParameter[parameters.size()];
50
-		for (int i = 0; i < result.length; i++)
51
-			result[i] = parameters.get(i).compiled;
48
+	public static void compile(BaseScope scope, TypeParameter[] compiled, List<ParsedGenericParameter> parameters) {
49
+		if (compiled.length == 0)
50
+			return;
52 51
 		
53
-		GenericFunctionScope innerScope = new GenericFunctionScope(scope, result);
54
-		for (int i = 0; i < result.length; i++) {
52
+		GenericFunctionScope innerScope = new GenericFunctionScope(scope, compiled);
53
+		for (int i = 0; i < compiled.length; i++) {
55 54
 			for (ParsedGenericBound bound : parameters.get(i).bounds)
56
-				result[i].addBound(bound.compile(innerScope));
55
+				compiled[i].addBound(bound.compile(innerScope));
57 56
 		}
57
+	}
58
+	
59
+	private static TypeParameter[] NO_TYPE_PARAMETERS = new TypeParameter[0];
60
+	public static TypeParameter[] getCompiled(List<ParsedGenericParameter> parameters) {
61
+		if (parameters.isEmpty())
62
+			return NO_TYPE_PARAMETERS;
58 63
 		
64
+		TypeParameter[] result = new TypeParameter[parameters.size()];
65
+		for (int i = 0; i < result.length; i++)
66
+			result[i] = parameters.get(i).compiled;
59 67
 		return result;
60 68
 	}
61 69
 	

+ 4
- 6
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedStruct.java View File

@@ -37,14 +37,13 @@ public class ParsedStruct extends BaseParsedDefinition {
37 37
 	
38 38
 	private final StructDefinition compiled;
39 39
 	
40
-	public ParsedStruct(ZSPackage pkg, CodePosition position, int modifiers, String name, List<ParsedGenericParameter> parameters, HighLevelDefinition outerDefinition) {
40
+	public ParsedStruct(ZSPackage pkg, CodePosition position, int modifiers, String name, List<ParsedGenericParameter> genericParameters, HighLevelDefinition outerDefinition) {
41 41
 		super(position, modifiers);
42 42
 		
43
-		this.parameters = parameters;
43
+		this.parameters = genericParameters;
44 44
 		
45 45
 		compiled = new StructDefinition(position, pkg, name, modifiers, outerDefinition);
46
-		for (ParsedGenericParameter parameter : parameters)
47
-			compiled.addGenericParameter(parameter.compiled);
46
+		compiled.setTypeParameters(ParsedGenericParameter.getCompiled(genericParameters));
48 47
 	}
49 48
 
50 49
 	@Override
@@ -54,8 +53,7 @@ public class ParsedStruct extends BaseParsedDefinition {
54 53
 
55 54
 	@Override
56 55
 	public void compileMembers(BaseScope scope) {
57
-		ParsedGenericParameter.compile(scope, parameters);
58
-		
56
+		ParsedGenericParameter.compile(scope, compiled.genericParameters, parameters);
59 57
 		super.compileMembers(scope);
60 58
 	}
61 59
 }

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

@@ -457,7 +457,7 @@ public abstract class ParsedExpression {
457 457
 	}
458 458
 	
459 459
 	public final CodePosition position;
460
-
460
+	
461 461
 	public ParsedExpression(CodePosition position) {
462 462
 		this.position = position;
463 463
 	}

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.member.CallerMember;
9 10
 import org.openzen.zenscript.linker.BaseScope;
10 11
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
@@ -18,14 +19,14 @@ import org.openzen.zenscript.shared.CodePosition;
18 19
 public class ParsedCaller extends ParsedFunctionalMember {
19 20
 	private final ParsedFunctionHeader header;
20 21
 	
21
-	public ParsedCaller(CodePosition position, int modifiers, ParsedFunctionHeader header, ParsedFunctionBody body) {
22
-		super(position, modifiers, body);
22
+	public ParsedCaller(CodePosition position, HighLevelDefinition definition, int modifiers, ParsedFunctionHeader header, ParsedFunctionBody body) {
23
+		super(position, definition, modifiers, body);
23 24
 		
24 25
 		this.header = header;
25 26
 	}
26 27
 
27 28
 	@Override
28 29
 	public void linkTypes(BaseScope scope) {
29
-		compiled = new CallerMember(position, modifiers, header.compile(scope));
30
+		compiled = new CallerMember(position, definition, modifiers, header.compile(scope));
30 31
 	}
31 32
 }

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.member.CasterMember;
9 10
 import org.openzen.zenscript.linker.BaseScope;
10 11
 import org.openzen.zenscript.parser.statements.ParsedFunctionBody;
@@ -18,14 +19,14 @@ import org.openzen.zenscript.shared.CodePosition;
18 19
 public class ParsedCaster extends ParsedFunctionalMember {
19 20
 	private final IParsedType type;
20 21
 	
21
-	public ParsedCaster(CodePosition position, int modifiers, IParsedType type, ParsedFunctionBody body) {
22
-		super(position, modifiers, body);
22
+	public ParsedCaster(CodePosition position, HighLevelDefinition definition, int modifiers, IParsedType type, ParsedFunctionBody body) {
23
+		super(position, definition, modifiers, body);
23 24
 		
24 25
 		this.type = type;
25 26
 	}
26 27
 
27 28
 	@Override
28 29
 	public void linkTypes(BaseScope scope) {
29
-		compiled = new CasterMember(position, modifiers, type.compile(scope));
30
+		compiled = new CasterMember(position, definition, modifiers, type.compile(scope));
30 31
 	}
31 32
 }

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
9 10
 import org.openzen.zenscript.linker.BaseScope;
10 11
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
@@ -18,14 +19,14 @@ import org.openzen.zenscript.shared.CodePosition;
18 19
 public class ParsedConstructor extends ParsedFunctionalMember {
19 20
 	private final ParsedFunctionHeader header;
20 21
 	
21
-	public ParsedConstructor(CodePosition position, int modifiers, ParsedFunctionHeader header, ParsedFunctionBody body) {
22
-		super(position, modifiers, body);
22
+	public ParsedConstructor(CodePosition position, HighLevelDefinition definition, int modifiers, ParsedFunctionHeader header, ParsedFunctionBody body) {
23
+		super(position, definition, modifiers, body);
23 24
 		
24 25
 		this.header = header;
25 26
 	}
26 27
 
27 28
 	@Override
28 29
 	public void linkTypes(BaseScope scope) {
29
-		compiled = new ConstructorMember(position, modifiers, header.compile(scope));
30
+		compiled = new ConstructorMember(position, definition, modifiers, header.compile(scope));
30 31
 	}
31 32
 }

+ 21
- 16
Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedDefinitionMember.java View File

@@ -15,7 +15,6 @@ import org.openzen.zenscript.parser.statements.ParsedFunctionBody;
15 15
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
16 16
 import org.openzen.zenscript.codemodel.Modifiers;
17 17
 import org.openzen.zenscript.codemodel.OperatorType;
18
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
19 18
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
20 19
 import org.openzen.zenscript.lexer.ZSToken;
21 20
 import org.openzen.zenscript.lexer.ZSTokenStream;
@@ -77,7 +76,7 @@ public abstract class ParsedDefinitionMember {
77 76
 					initializer = ParsedExpression.parse(tokens);
78 77
 				}
79 78
 				tokens.required(ZSTokenType.T_SEMICOLON, "; expected");
80
-				return new ParsedField(start, modifiers, name, type, initializer, t.type == ZSTokenType.K_VAL);
79
+				return new ParsedField(start, forDefinition, modifiers, name, type, initializer, t.type == ZSTokenType.K_VAL);
81 80
 			}
82 81
 			case K_THIS: {
83 82
 				tokens.next();
@@ -86,13 +85,13 @@ public abstract class ParsedDefinitionMember {
86 85
 				if (body == null)
87 86
 					throw new CompileException(start, CompileExceptionCode.METHOD_BODY_REQUIRED, "Function body is required for constructors");
88 87
 				
89
-				return new ParsedConstructor(start, modifiers, header, body);
88
+				return new ParsedConstructor(start, forDefinition, modifiers, header, body);
90 89
 			}
91 90
 			case T_IDENTIFIER: {
92 91
 				String name = tokens.next().content;
93 92
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
94 93
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
95
-				return new ParsedMethod(start, modifiers, name, header, body);
94
+				return new ParsedMethod(start, forDefinition, modifiers, name, header, body);
96 95
 			}
97 96
 			case K_SET: {
98 97
 				tokens.next();
@@ -102,7 +101,7 @@ public abstract class ParsedDefinitionMember {
102 101
 					type = IParsedType.parse(tokens);
103 102
 				}
104 103
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
105
-				return new ParsedSetter(start, modifiers, name, type, body);
104
+				return new ParsedSetter(start, forDefinition, modifiers, name, type, body);
106 105
 			}
107 106
 			case K_GET: {
108 107
 				tokens.next();
@@ -112,7 +111,7 @@ public abstract class ParsedDefinitionMember {
112 111
 					type = IParsedType.parse(tokens);
113 112
 				}
114 113
 				ParsedFunctionBody statements = ParsedStatement.parseFunctionBody(tokens);
115
-				return new ParsedGetter(start, modifiers, name, type, statements);
114
+				return new ParsedGetter(start, forDefinition, modifiers, name, type, statements);
116 115
 			}
117 116
 			case K_IMPLEMENTS: {
118 117
 				tokens.next();
@@ -124,12 +123,12 @@ public abstract class ParsedDefinitionMember {
124 123
 						members.add(ParsedDefinitionMember.parse(tokens, forDefinition));
125 124
 					}
126 125
 				}
127
-				return new ParsedImplementation(start, modifiers, type, members);
126
+				return new ParsedImplementation(start, forDefinition, modifiers, type, members);
128 127
 			}
129 128
 			case T_BROPEN: {
130 129
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
131 130
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
132
-				return new ParsedCaller(start, modifiers, header, body);
131
+				return new ParsedCaller(start, forDefinition, modifiers, header, body);
133 132
 			}
134 133
 			case T_SQOPEN: {
135 134
 				tokens.required(ZSTokenType.T_SQCLOSE, "] expected");
@@ -139,7 +138,7 @@ public abstract class ParsedDefinitionMember {
139 138
 				}
140 139
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
141 140
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
142
-				return new ParsedOperator(start, modifiers, operator, header, body);
141
+				return new ParsedOperator(start, forDefinition, modifiers, operator, header, body);
143 142
 			}
144 143
 			case T_ADD:
145 144
 			case T_SUB:
@@ -165,37 +164,37 @@ public abstract class ParsedDefinitionMember {
165 164
 				ZSToken token = tokens.next();
166 165
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
167 166
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
168
-				return new ParsedOperator(start, modifiers, getOperator(token.type), header, body);
167
+				return new ParsedOperator(start, forDefinition, modifiers, getOperator(token.type), header, body);
169 168
 			}
170 169
 			case T_EQUAL2: {
171 170
 				tokens.next();
172 171
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
173 172
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
174
-				return new ParsedOperator(start, modifiers, OperatorType.EQUALS, header, body);
173
+				return new ParsedOperator(start, forDefinition, modifiers, OperatorType.EQUALS, header, body);
175 174
 			}
176 175
 			case K_AS: {
177 176
 				tokens.next();
178 177
 				IParsedType type = IParsedType.parse(tokens);
179 178
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
180
-				return new ParsedCaster(start, modifiers, type, body);
179
+				return new ParsedCaster(start, forDefinition, modifiers, type, body);
181 180
 			}
182 181
 			case K_IN: {
183 182
 				tokens.next();
184 183
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
185 184
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
186
-				return new ParsedOperator(start, modifiers, OperatorType.CONTAINS, header, body);
185
+				return new ParsedOperator(start, forDefinition, modifiers, OperatorType.CONTAINS, header, body);
187 186
 			}
188 187
 			case K_CLASS:
189 188
 			case K_INTERFACE:
190 189
 			case K_ALIAS:
191 190
 			case K_STRUCT:
192 191
 			case K_ENUM:
193
-				return new ParsedInnerDefinition(ParsedDefinition.parse(forDefinition.pkg, start, modifiers, tokens, forDefinition));
192
+				return new ParsedInnerDefinition(forDefinition, ParsedDefinition.parse(forDefinition.pkg, start, modifiers, tokens, forDefinition));
194 193
 			case K_FOR: {
195 194
 				tokens.next();
196 195
 				ParsedFunctionHeader header = ParsedFunctionHeader.parse(tokens);
197 196
 				ParsedFunctionBody body = ParsedStatement.parseFunctionBody(tokens);
198
-				return new ParsedIterator(start, modifiers, header, body);
197
+				return new ParsedIterator(start, forDefinition, modifiers, header, body);
199 198
 			}
200 199
 			default:
201 200
 				throw new CompileException(tokens.peek().position, CompileExceptionCode.UNEXPECTED_TOKEN, "Unexpected token: " + tokens.peek().content);
@@ -230,7 +229,13 @@ public abstract class ParsedDefinitionMember {
230 229
 		}
231 230
 	}
232 231
 	
233
-	public abstract void linkInnerTypes(HighLevelDefinition definition);
232
+	public final HighLevelDefinition definition;
233
+	
234
+	public ParsedDefinitionMember(HighLevelDefinition definition) {
235
+		this.definition = definition;
236
+	}
237
+	
238
+	public abstract void linkInnerTypes();
234 239
 	
235 240
 	public abstract void linkTypes(BaseScope scope);
236 241
 	

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

@@ -29,7 +29,17 @@ public class ParsedField extends ParsedDefinitionMember {
29 29
 	
30 30
 	private FieldMember compiled;
31 31
 	
32
-	public ParsedField(CodePosition position, int modifiers, String name, IParsedType type, ParsedExpression expression, boolean isFinal) {
32
+	public ParsedField(
33
+			CodePosition position,
34
+			HighLevelDefinition definition,
35
+			int modifiers,
36
+			String name,
37
+			IParsedType type,
38
+			ParsedExpression expression,
39
+			boolean isFinal)
40
+	{
41
+		super(definition);
42
+		
33 43
 		this.position = position;
34 44
 		this.modifiers = modifiers;
35 45
 		this.name = name;
@@ -39,13 +49,18 @@ public class ParsedField extends ParsedDefinitionMember {
39 49
 	}
40 50
 	
41 51
 	@Override
42
-	public void linkInnerTypes(HighLevelDefinition definition) {
52
+	public void linkInnerTypes() {
43 53
 		
44 54
 	}
45 55
 
46 56
 	@Override
47 57
 	public void linkTypes(BaseScope scope) {
48
-		compiled = new FieldMember(position, modifiers | (isFinal ? Modifiers.FINAL : 0), name, type.compile(scope));
58
+		compiled = new FieldMember(
59
+				position,
60
+				definition,
61
+				modifiers | (isFinal ? Modifiers.FINAL : 0),
62
+				name,
63
+				type.compile(scope));
49 64
 	}
50 65
 
51 66
 	@Override

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

@@ -23,14 +23,16 @@ public abstract class ParsedFunctionalMember extends ParsedDefinitionMember {
23 23
 	
24 24
 	protected FunctionalMember compiled;
25 25
 	
26
-	public ParsedFunctionalMember(CodePosition position, int modifiers, ParsedFunctionBody body) {
26
+	public ParsedFunctionalMember(CodePosition position, HighLevelDefinition definition, int modifiers, ParsedFunctionBody body) {
27
+		super(definition);
28
+		
27 29
 		this.position = position;
28 30
 		this.modifiers = modifiers;
29 31
 		this.body = body;
30 32
 	}
31 33
 	
32 34
 	@Override
33
-	public void linkInnerTypes(HighLevelDefinition definition) {
35
+	public void linkInnerTypes() {
34 36
 		
35 37
 	}
36 38
 

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.member.GetterMember;
9 10
 import org.openzen.zenscript.linker.BaseScope;
10 11
 import org.openzen.zenscript.parser.statements.ParsedFunctionBody;
@@ -19,14 +20,15 @@ public class ParsedGetter extends ParsedFunctionalMember {
19 20
 	private final String name;
20 21
 	private final IParsedType type;
21 22
 	
22
-	public ParsedGetter(CodePosition position, int modifiers, String name, IParsedType type, ParsedFunctionBody body) {
23
-		super(position, modifiers, body);
23
+	public ParsedGetter(CodePosition position, HighLevelDefinition definition, int modifiers, String name, IParsedType type, ParsedFunctionBody body) {
24
+		super(position, definition, modifiers, body);
25
+		
24 26
 		this.name = name;
25 27
 		this.type = type;
26 28
 	}
27 29
 
28 30
 	@Override
29 31
 	public void linkTypes(BaseScope scope) {
30
-		compiled = new GetterMember(position, modifiers, name, type.compile(scope));
32
+		compiled = new GetterMember(position, definition, modifiers, name, type.compile(scope));
31 33
 	}
32 34
 }

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

@@ -25,7 +25,15 @@ public class ParsedImplementation extends ParsedDefinitionMember {
25 25
 	
26 26
 	private ImplementationMember compiled;
27 27
 	
28
-	public ParsedImplementation(CodePosition position, int modifiers, IParsedType type, List<ParsedDefinitionMember> members) {
28
+	public ParsedImplementation(
29
+			CodePosition position,
30
+			HighLevelDefinition definition,
31
+			int modifiers,
32
+			IParsedType type,
33
+			List<ParsedDefinitionMember> members)
34
+	{
35
+		super(definition);
36
+		
29 37
 		this.position = position;
30 38
 		this.modifiers = modifiers;
31 39
 		this.type = type;
@@ -33,13 +41,13 @@ public class ParsedImplementation extends ParsedDefinitionMember {
33 41
 	}
34 42
 	
35 43
 	@Override
36
-	public void linkInnerTypes(HighLevelDefinition definition) {
44
+	public void linkInnerTypes() {
37 45
 		
38 46
 	}
39 47
 
40 48
 	@Override
41 49
 	public void linkTypes(BaseScope scope) {
42
-		compiled = new ImplementationMember(position, modifiers, type.compile(scope));
50
+		compiled = new ImplementationMember(position, definition, modifiers, type.compile(scope));
43 51
 		
44 52
 		for (ParsedDefinitionMember member : members) {
45 53
 			member.linkTypes(scope);

+ 11
- 10
Parser/src/main/java/org/openzen/zenscript/parser/member/ParsedInnerDefinition.java View File

@@ -15,26 +15,27 @@ import org.openzen.zenscript.parser.ParsedDefinition;
15 15
  * @author Hoofdgebruiker
16 16
  */
17 17
 public class ParsedInnerDefinition extends ParsedDefinitionMember {
18
-	private final ParsedDefinition definition;
18
+	private final ParsedDefinition innerDefinition;
19
+	private final InnerDefinitionMember member;
19 20
 	
20
-	private InnerDefinitionMember member;
21
-	
22
-	public ParsedInnerDefinition(ParsedDefinition definition) {
23
-		this.definition = definition;
21
+	public ParsedInnerDefinition(HighLevelDefinition outer, ParsedDefinition definition) {
22
+		super(outer);
23
+		
24
+		this.innerDefinition = definition;
24 25
 		
25
-		member = new InnerDefinitionMember(definition.getPosition(), definition.getModifiers(), definition.getCompiled());
26
+		member = new InnerDefinitionMember(definition.getPosition(), outer, definition.getModifiers(), definition.getCompiled());
26 27
 	}
27 28
 	
28 29
 	@Override
29
-	public void linkInnerTypes(HighLevelDefinition definition) {
30
+	public void linkInnerTypes() {
30 31
 		definition.addMember(member);
31 32
 		
32
-		this.definition.linkInnerTypes();
33
+		this.innerDefinition.linkInnerTypes();
33 34
 	}
34 35
 
35 36
 	@Override
36 37
 	public void linkTypes(BaseScope scope) {
37
-		definition.compileMembers(scope);
38
+		this.innerDefinition.compileMembers(scope);
38 39
 	}
39 40
 
40 41
 	@Override
@@ -44,6 +45,6 @@ public class ParsedInnerDefinition extends ParsedDefinitionMember {
44 45
 
45 46
 	@Override
46 47
 	public void compile(BaseScope scope) {
47
-		definition.compileCode(scope);
48
+		innerDefinition.compileCode(scope);
48 49
 	}
49 50
 }

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

@@ -28,7 +28,15 @@ public class ParsedIterator extends ParsedDefinitionMember {
28 28
 	
29 29
 	private CustomIteratorMember compiled;
30 30
 	
31
-	public ParsedIterator(CodePosition position, int modifiers, ParsedFunctionHeader header, ParsedFunctionBody body) {
31
+	public ParsedIterator(
32
+			CodePosition position,
33
+			HighLevelDefinition definition,
34
+			int modifiers,
35
+			ParsedFunctionHeader header,
36
+			ParsedFunctionBody body)
37
+	{
38
+		super(definition);
39
+		
32 40
 		this.position = position;
33 41
 		this.modifiers = modifiers;
34 42
 		this.header = header;
@@ -36,7 +44,7 @@ public class ParsedIterator extends ParsedDefinitionMember {
36 44
 	}
37 45
 
38 46
 	@Override
39
-	public void linkInnerTypes(HighLevelDefinition definition) {
47
+	public void linkInnerTypes() {
40 48
 		// nothing to do
41 49
 	}
42 50
 
@@ -46,7 +54,7 @@ public class ParsedIterator extends ParsedDefinitionMember {
46 54
 		for (int i = 0; i < loopVariableTypes.length; i++)
47 55
 			loopVariableTypes[i] = header.parameters.get(i).type.compile(scope);
48 56
 		
49
-		compiled = new CustomIteratorMember(position, modifiers, loopVariableTypes);
57
+		compiled = new CustomIteratorMember(position, definition, modifiers, loopVariableTypes);
50 58
 	}
51 59
 
52 60
 	@Override

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.member.MethodMember;
9 10
 import org.openzen.zenscript.linker.BaseScope;
10 11
 import org.openzen.zenscript.parser.definitions.ParsedFunctionHeader;
@@ -19,8 +20,8 @@ public class ParsedMethod extends ParsedFunctionalMember {
19 20
 	private final String name;
20 21
 	private final ParsedFunctionHeader header;
21 22
 	
22
-	public ParsedMethod(CodePosition position, int modifiers, String name, ParsedFunctionHeader header, ParsedFunctionBody body) {
23
-		super(position, modifiers, body);
23
+	public ParsedMethod(CodePosition position, HighLevelDefinition definition, int modifiers, String name, ParsedFunctionHeader header, ParsedFunctionBody body) {
24
+		super(position, definition, modifiers, body);
24 25
 		
25 26
 		this.name = name;
26 27
 		this.header = header;
@@ -28,6 +29,6 @@ public class ParsedMethod extends ParsedFunctionalMember {
28 29
 
29 30
 	@Override
30 31
 	public void linkTypes(BaseScope scope) {
31
-		compiled = new MethodMember(position, modifiers, name, header.compile(scope));
32
+		compiled = new MethodMember(position, definition, modifiers, name, header.compile(scope));
32 33
 	}
33 34
 }

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.OperatorType;
9 10
 import org.openzen.zenscript.codemodel.member.OperatorMember;
10 11
 import org.openzen.zenscript.linker.BaseScope;
@@ -20,8 +21,8 @@ public class ParsedOperator extends ParsedFunctionalMember {
20 21
 	private final OperatorType operator;
21 22
 	private final ParsedFunctionHeader header;
22 23
 	
23
-	public ParsedOperator(CodePosition position, int modifiers, OperatorType operator, ParsedFunctionHeader header, ParsedFunctionBody body) {
24
-		super(position, modifiers, body);
24
+	public ParsedOperator(CodePosition position, HighLevelDefinition definition, int modifiers, OperatorType operator, ParsedFunctionHeader header, ParsedFunctionBody body) {
25
+		super(position, definition, modifiers, body);
25 26
 		
26 27
 		this.operator = operator;
27 28
 		this.header = header;
@@ -29,6 +30,6 @@ public class ParsedOperator extends ParsedFunctionalMember {
29 30
 
30 31
 	@Override
31 32
 	public void linkTypes(BaseScope scope) {
32
-		compiled = new OperatorMember(position, modifiers, operator, header.compile(scope));
33
+		compiled = new OperatorMember(position, definition, modifiers, operator, header.compile(scope));
33 34
 	}
34 35
 }

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

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.member;
7 7
 
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 9
 import org.openzen.zenscript.codemodel.member.SetterMember;
9 10
 import org.openzen.zenscript.linker.BaseScope;
10 11
 import org.openzen.zenscript.parser.statements.ParsedFunctionBody;
@@ -19,8 +20,8 @@ public class ParsedSetter extends ParsedFunctionalMember {
19 20
 	private final String name;
20 21
 	private final IParsedType type;
21 22
 	
22
-	public ParsedSetter(CodePosition position, int modifiers, String name, IParsedType type, ParsedFunctionBody body) {
23
-		super(position, modifiers, body);
23
+	public ParsedSetter(CodePosition position, HighLevelDefinition definition, int modifiers, String name, IParsedType type, ParsedFunctionBody body) {
24
+		super(position, definition, modifiers, body);
24 25
 		
25 26
 		this.name = name;
26 27
 		this.type = type;
@@ -28,6 +29,6 @@ public class ParsedSetter extends ParsedFunctionalMember {
28 29
 
29 30
 	@Override
30 31
 	public void linkTypes(BaseScope scope) {
31
-		compiled = new SetterMember(position, modifiers, name, type.compile(scope));
32
+		compiled = new SetterMember(position, definition, modifiers, name, type.compile(scope));
32 33
 	}
33 34
 }

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

@@ -11,6 +11,7 @@ import org.openzen.zenscript.codemodel.expression.Expression;
11 11
 import org.openzen.zenscript.codemodel.statement.CatchClause;
12 12
 import org.openzen.zenscript.codemodel.statement.Statement;
13 13
 import org.openzen.zenscript.codemodel.statement.TryCatchStatement;
14
+import org.openzen.zenscript.codemodel.statement.VarStatement;
14 15
 import org.openzen.zenscript.linker.ExpressionScope;
15 16
 import org.openzen.zenscript.linker.StatementScope;
16 17
 import org.openzen.zenscript.parser.expression.ParsedExpression;
@@ -52,6 +53,10 @@ public class ParsedStatementTryCatch extends ParsedStatement {
52 53
 			catches.add(catchClause.compile(scope));
53 54
 		
54 55
 		Statement finallyClause = this.finallyClause == null ? null : this.finallyClause.compile(scope);
55
-		return new TryCatchStatement(position, resourceName, resourceInitializer, statement, catches, finallyClause);
56
+		VarStatement resource = null;
57
+		if (resourceName != null) {
58
+			resource = new VarStatement(position, resourceName, resourceInitializer.type, resourceInitializer, true);
59
+		}
60
+		return new TryCatchStatement(position, resource, statement, catches, finallyClause);
56 61
 	}
57 62
 }

+ 1
- 0
ScriptingExample/build.gradle View File

@@ -17,4 +17,5 @@ dependencies {
17 17
 	compile project(':Parser')
18 18
 	compile project(':JavaBytecodeCompiler')
19 19
 	compile project(':CodeFormatter')
20
+	compile project(':Validator')
20 21
 }

+ 0
- 15
ScriptingExample/scripts/enums.zs View File

@@ -1,15 +0,0 @@
1
-enum TestEnum {
2
-	HELLO,
3
-	WORLD
4
-}
5
-
6
-enum TestEnum2 {
7
-	HELLO("Hello"),
8
-	WORLD("World");
9
-	
10
-	val value as string;
11
-	
12
-	this(value as string) {
13
-		this.value = value;
14
-	}
15
-}

+ 3
- 1
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/GlobalRegistry.java View File

@@ -67,7 +67,7 @@ public class GlobalRegistry {
67 67
 			ClassDefinition myClassDefinition = new ClassDefinition(CodePosition.NATIVE, packageMyPackage, "MyClass", Modifiers.PUBLIC, null);
68 68
 			JavaClassInfo myClassInfo = new JavaClassInfo("my/test/MyClass");
69 69
 			
70
-			MethodMember member = new MethodMember(CodePosition.NATIVE, Modifiers.PUBLIC, "test", new FunctionHeader(BasicTypeID.STRING));
70
+			MethodMember member = new MethodMember(CodePosition.NATIVE, myClassDefinition, Modifiers.PUBLIC, "test", new FunctionHeader(BasicTypeID.STRING));
71 71
 			member.setTag(JavaMethodInfo.class, new JavaMethodInfo(myClassInfo, "test", "()Ljava/lang/String;"));
72 72
 			myClassDefinition.addMember(member);
73 73
 			
@@ -96,12 +96,14 @@ public class GlobalRegistry {
96 96
 	private final ClassDefinition SYSTEM = new ClassDefinition(CodePosition.NATIVE, javaLang, "System", Modifiers.EXPORT);
97 97
 	private final MethodMember PRINTSTREAM_PRINTLN = new MethodMember(
98 98
 			CodePosition.NATIVE,
99
+			PRINTSTREAM,
99 100
 			Modifiers.EXPORT,
100 101
 			"println",
101 102
 			new FunctionHeader(BasicTypeID.VOID, new FunctionParameter(BasicTypeID.STRING)));
102 103
 	
103 104
 	private final FieldMember SYSTEM_OUT = new FieldMember(
104 105
 			CodePosition.NATIVE,
106
+			SYSTEM,
105 107
 			Modifiers.EXPORT | Modifiers.FINAL,
106 108
 			"out",
107 109
 			DefinitionTypeID.forType(SYSTEM));

+ 24
- 5
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/Main.java View File

@@ -21,6 +21,8 @@ import org.openzen.zenscript.javabytecode.JavaModule;
21 21
 import org.openzen.zenscript.linker.symbol.ISymbol;
22 22
 import org.openzen.zenscript.parser.ParsedFile;
23 23
 import org.openzen.zenscript.shared.SourceFile;
24
+import org.openzen.zenscript.validator.ValidationLogEntry;
25
+import org.openzen.zenscript.validator.Validator;
24 26
 
25 27
 public class Main {
26 28
     /**
@@ -38,15 +40,19 @@ public class Main {
38 40
 		GlobalRegistry registry = new GlobalRegistry(global);
39 41
 		SemanticModule module = compileSyntaxToSemantic(parsedFiles, registry);
40 42
 		
41
-		/*FormattingSettings settings = new FormattingSettings.Builder().build();
43
+		FormattingSettings settings = new FormattingSettings.Builder().build();
42 44
 		for (ScriptBlock block : module.scripts) {
43 45
 			FileFormatter formatter = new FileFormatter(settings);
44 46
 			System.out.println("== " + block.getTag(SourceFile.class).filename + " ==");
45 47
 			System.out.println(formatter.format(pkg, block, Collections.emptyList()));
46
-		}*/
48
+		}
47 49
 		
48
-		JavaModule javaModule = compileSemanticToJava(module);
49
-		javaModule.execute();
50
+		if (module.isValid) {
51
+			JavaModule javaModule = compileSemanticToJava(module);
52
+			javaModule.execute();
53
+		} else {
54
+			System.out.println("There were compilation errors");
55
+		}
50 56
     }
51 57
 	
52 58
 	private static ParsedFile[] parse(ZSPackage pkg, File[] files) throws IOException {
@@ -90,7 +96,20 @@ public class Main {
90 96
 			file.compileCode(rootPackage, definitions, globalRegistry, expansions, scripts, globals);
91 97
 		}
92 98
 		
93
-		return new SemanticModule(definitions, scripts);
99
+		Validator validator = new Validator();
100
+		boolean isValid = true;
101
+		for (ScriptBlock script : scripts) {
102
+			isValid &= validator.validate(script);
103
+		}
104
+		for (HighLevelDefinition definition : definitions.getAll()) {
105
+			isValid &= validator.validate(definition);
106
+		}
107
+		
108
+		for (ValidationLogEntry entry : validator.getLog()) {
109
+			System.out.println(entry.kind + " " + entry.position.toString() + ": " + entry.message);
110
+		}
111
+		
112
+		return new SemanticModule(isValid, definitions, scripts);
94 113
 	}
95 114
 	
96 115
 	private static JavaModule compileSemanticToJava(SemanticModule module) {

+ 3
- 1
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/SemanticModule.java View File

@@ -14,10 +14,12 @@ import org.openzen.zenscript.codemodel.ScriptBlock;
14 14
  * @author Hoofdgebruiker
15 15
  */
16 16
 public class SemanticModule {
17
+	public final boolean isValid;
17 18
 	public final PackageDefinitions definitions;
18 19
 	public final List<ScriptBlock> scripts;
19 20
 
20
-	public SemanticModule(PackageDefinitions definitions, List<ScriptBlock> scripts) {
21
+	public SemanticModule(boolean isValid, PackageDefinitions definitions, List<ScriptBlock> scripts) {
22
+		this.isValid = isValid;
21 23
 		this.definitions = definitions;
22 24
 		this.scripts = scripts;
23 25
 	}

+ 18
- 0
Validator/build.gradle View File

@@ -0,0 +1,18 @@
1
+// Note: "common.gradle" in the root project contains additional initialization
2
+//   for this project. This initialization is applied in the "build.gradle"
3
+//   of the root project.
4
+
5
+// NetBeans will automatically add "run" and "debug" tasks relying on the
6
+// "mainClass" property. You may however define the property prior executing
7
+// tasks by passing a "-PmainClass=<QUALIFIED_CLASS_NAME>" argument.
8
+//
9
+// Note however, that you may define your own "run" and "debug" task if you
10
+// prefer. In this case NetBeans will not add these tasks but you may rely on
11
+// your own implementation.
12
+if (!hasProperty('mainClass')) {
13
+    ext.mainClass = ''
14
+}
15
+
16
+dependencies {
17
+	compile project(':CodeModel')
18
+}

+ 64
- 0
Validator/src/main/java/org/openzen/zenscript/validator/ValidationLogEntry.java View File

@@ -0,0 +1,64 @@
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.validator;
7
+
8
+import org.openzen.zenscript.shared.CodePosition;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class ValidationLogEntry {
15
+	public final Kind kind;
16
+	public final Code code;
17
+	public final CodePosition position;
18
+	public final String message;
19
+	
20
+	public ValidationLogEntry(Kind kind, Code code, CodePosition position, String message) {
21
+		this.kind = kind;
22
+		this.code = code;
23
+		this.position = position;
24
+		this.message = message;
25
+	}
26
+	
27
+	public static enum Kind {
28
+		ERROR,
29
+		WARNING
30
+	}
31
+	
32
+	public static enum Code {
33
+		SUPERCLASS_NOT_A_CLASS,
34
+		SUPERCLASS_NOT_VIRTUAL,
35
+		INVALID_MODIFIER,
36
+		INVALID_IDENTIFIER,
37
+		DUPLICATE_FIELD_NAME,
38
+		DUPLICATE_MEMBER_NAME,
39
+		INVALID_TYPE,
40
+		DUPLICATE_PARAMETER_NAME,
41
+		INVALID_OPERAND_TYPE,
42
+		INVALID_TYPE_ARGUMENT,
43
+		INVALID_CALL_ARGUMENT,
44
+		VARIADIC_PARAMETER_MUST_BE_LAST,
45
+		CONSTRUCTOR_FORWARD_OUTSIDE_CONSTRUCTOR,
46
+		CONSTRUCTOR_FORWARD_NOT_FIRST_STATEMENT,
47
+		DUPLICATE_CONSTRUCTOR,
48
+		DUPLICATE_METHOD,
49
+		BODY_REQUIRED,
50
+		INVALID_CONDITION_TYPE,
51
+		DUPLICATE_VARIABLE_NAME,
52
+		SCRIPT_CANNOT_RETURN,
53
+		INVALID_RETURN_TYPE,
54
+		TRY_CATCH_RESOURCE_REQUIRES_INITIALIZER,
55
+		TYPE_ALREADY_IMPLEMENTED,
56
+		THIS_IN_STATIC_SCOPE,
57
+		ENUM_CONSTANT_NOT_YET_INITIALIZED,
58
+		FIELD_NOT_YET_INITIALIZED,
59
+		LOCAL_VARIABLE_NOT_YET_INITIALIZED,
60
+		INVALID_SOURCE_TYPE,
61
+		SETTING_FINAL_FIELD,
62
+		SETTING_FINAL_VARIABLE
63
+	}
64
+}

+ 14
- 0
Validator/src/main/java/org/openzen/zenscript/validator/ValidationSettings.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.validator;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public class ValidationSettings {
13
+	
14
+}

+ 87
- 0
Validator/src/main/java/org/openzen/zenscript/validator/Validator.java View File

@@ -0,0 +1,87 @@
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.validator;
7
+
8
+import java.util.ArrayList;
9
+import java.util.Collections;
10
+import java.util.List;
11
+import org.openzen.zenscript.codemodel.FunctionHeader;
12
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
13
+import org.openzen.zenscript.codemodel.ScriptBlock;
14
+import org.openzen.zenscript.codemodel.statement.Statement;
15
+import org.openzen.zenscript.shared.CodePosition;
16
+import org.openzen.zenscript.validator.analysis.StatementScope;
17
+import org.openzen.zenscript.validator.visitors.DefinitionValidator;
18
+import org.openzen.zenscript.validator.visitors.StatementValidator;
19
+
20
+/**
21
+ *
22
+ * @author Hoofdgebruiker
23
+ */
24
+public class Validator {
25
+	private final List<ValidationLogEntry> log = new ArrayList<>();
26
+	private boolean hasErrors = false;
27
+	
28
+	private final DefinitionValidator definitionValidator = new DefinitionValidator(this);
29
+	
30
+	public List<ValidationLogEntry> getLog() {
31
+		return Collections.unmodifiableList(log);
32
+	}
33
+	
34
+	public boolean validate(ScriptBlock script) {
35
+		StatementValidator statementValidator = new StatementValidator(this, new ScriptScope());
36
+		boolean isValid = true;
37
+		for (Statement statement : script.statements) {
38
+			isValid &= statement.accept(statementValidator);
39
+		}
40
+		return isValid;
41
+	}
42
+	
43
+	public boolean validate(HighLevelDefinition definition) {
44
+		return definition.accept(definitionValidator);
45
+	}
46
+	
47
+	public boolean hasErrors() {
48
+		return hasErrors;
49
+	}
50
+	
51
+	public void logError(ValidationLogEntry.Code code, CodePosition position, String message) {
52
+		log.add(new ValidationLogEntry(ValidationLogEntry.Kind.ERROR, code, position, message));
53
+		hasErrors = true;
54
+	}
55
+	
56
+	public void logWarning(ValidationLogEntry.Code code, CodePosition position, String message) {
57
+		log.add(new ValidationLogEntry(ValidationLogEntry.Kind.WARNING, code, position, message));
58
+	}
59
+	
60
+	private class ScriptScope implements StatementScope {
61
+
62
+		@Override
63
+		public boolean isConstructor() {
64
+			return false;
65
+		}
66
+
67
+		@Override
68
+		public boolean isStatic() {
69
+			return true;
70
+		}
71
+
72
+		@Override
73
+		public FunctionHeader getFunctionHeader() {
74
+			return null;
75
+		}
76
+
77
+		@Override
78
+		public boolean isStaticInitializer() {
79
+			return false;
80
+		}
81
+
82
+		@Override
83
+		public HighLevelDefinition getDefinition() {
84
+			return null;
85
+		}
86
+	}
87
+}

+ 35
- 0
Validator/src/main/java/org/openzen/zenscript/validator/analysis/ExpressionScope.java View File

@@ -0,0 +1,35 @@
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.validator.analysis;
7
+
8
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
9
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
10
+import org.openzen.zenscript.codemodel.member.FieldMember;
11
+import org.openzen.zenscript.codemodel.statement.VarStatement;
12
+
13
+/**
14
+ *
15
+ * @author Hoofdgebruiker
16
+ */
17
+public interface ExpressionScope {
18
+	public boolean isConstructor();
19
+	
20
+	public boolean isFirstStatement();
21
+	
22
+	public boolean hasThis();
23
+	
24
+	public boolean isFieldInitialized(FieldMember field);
25
+	
26
+	public boolean isEnumConstantInitialized(EnumConstantMember member);
27
+	
28
+	public boolean isLocalVariableInitialized(VarStatement variable);
29
+	
30
+	public void markConstructorForwarded();
31
+	
32
+	public boolean isStaticInitializer();
33
+	
34
+	public HighLevelDefinition getDefinition();
35
+}

+ 25
- 0
Validator/src/main/java/org/openzen/zenscript/validator/analysis/StatementScope.java View File

@@ -0,0 +1,25 @@
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.validator.analysis;
7
+
8
+import org.openzen.zenscript.codemodel.FunctionHeader;
9
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public interface StatementScope {
16
+	public boolean isConstructor();
17
+	
18
+	public boolean isStatic();
19
+	
20
+	public FunctionHeader getFunctionHeader();
21
+	
22
+	public boolean isStaticInitializer();
23
+	
24
+	public HighLevelDefinition getDefinition();
25
+}

+ 390
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionMemberValidator.java View File

@@ -0,0 +1,390 @@
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.validator.visitors;
7
+
8
+import java.util.ArrayList;
9
+import java.util.HashSet;
10
+import java.util.List;
11
+import java.util.Set;
12
+import org.openzen.zenscript.codemodel.FunctionHeader;
13
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
14
+import org.openzen.zenscript.codemodel.member.CallerMember;
15
+import org.openzen.zenscript.codemodel.member.CasterMember;
16
+import org.openzen.zenscript.codemodel.member.ConstructorMember;
17
+import org.openzen.zenscript.codemodel.member.CustomIteratorMember;
18
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
19
+import org.openzen.zenscript.codemodel.member.FieldMember;
20
+import org.openzen.zenscript.codemodel.member.GetterMember;
21
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
22
+import org.openzen.zenscript.codemodel.member.ImplementationMember;
23
+import org.openzen.zenscript.codemodel.member.InnerDefinitionMember;
24
+import org.openzen.zenscript.codemodel.member.MemberVisitor;
25
+import org.openzen.zenscript.codemodel.member.MethodMember;
26
+import org.openzen.zenscript.codemodel.member.OperatorMember;
27
+import org.openzen.zenscript.codemodel.member.SetterMember;
28
+import org.openzen.zenscript.codemodel.statement.Statement;
29
+import org.openzen.zenscript.codemodel.statement.VarStatement;
30
+import org.openzen.zenscript.codemodel.type.ITypeID;
31
+import org.openzen.zenscript.validator.ValidationLogEntry;
32
+import org.openzen.zenscript.validator.Validator;
33
+import org.openzen.zenscript.validator.analysis.ExpressionScope;
34
+import org.openzen.zenscript.validator.analysis.StatementScope;
35
+
36
+/**
37
+ *
38
+ * @author Hoofdgebruiker
39
+ */
40
+public class DefinitionMemberValidator implements MemberVisitor<Boolean> {
41
+	private final Validator validator;
42
+	private final Set<String> fieldNames = new HashSet<>();
43
+	private final Set<String> members = new HashSet<>();
44
+	private final Set<FieldMember> initializedFields = new HashSet<>();
45
+	private final List<FunctionHeader> constructors = new ArrayList<>();
46
+	private final HighLevelDefinition definition;
47
+	private final Set<EnumConstantMember> initializedEnumConstants = new HashSet<>();
48
+	private final Set<ITypeID> implementedTypes = new HashSet<>();
49
+	
50
+	public DefinitionMemberValidator(Validator validator, HighLevelDefinition definition) {
51
+		this.validator = validator;
52
+		this.definition = definition;
53
+	}
54
+	
55
+	@Override
56
+	public Boolean visitField(FieldMember member) {
57
+		boolean isValid = true;
58
+		if (fieldNames.contains(member.name)) {
59
+			validator.logError(
60
+					ValidationLogEntry.Code.DUPLICATE_FIELD_NAME,
61
+					member.position,
62
+					"Duplicate field name: " + member.name);
63
+			isValid = false;
64
+		}
65
+		fieldNames.add(member.name);
66
+		
67
+		isValid &= member.type.accept(new TypeValidator(validator, member.position));
68
+		
69
+		if (member.initializer != null) {
70
+			isValid &= member.initializer.accept(new ExpressionValidator(validator, new FieldInitializerScope(member)));
71
+		}
72
+		
73
+		return isValid;
74
+	}
75
+
76
+	@Override
77
+	public Boolean visitConstructor(ConstructorMember member) {
78
+		boolean isValid = true;
79
+		for (FunctionHeader existing : constructors) {
80
+			if (existing.isSimilarTo(member.header)) {
81
+				validator.logError(ValidationLogEntry.Code.DUPLICATE_CONSTRUCTOR, member.position, "Duplicate constructor, conflicts with this" + existing.toString());
82
+				isValid = false;
83
+			}
84
+		}
85
+		constructors.add(member.header);
86
+		isValid &= ValidationUtils.validateHeader(validator, member.position, member.header);
87
+		
88
+		if (member.body == null && !member.isExtern()) {
89
+			validator.logError(ValidationLogEntry.Code.BODY_REQUIRED, member.position, "Constructors must have a body");
90
+		} else {
91
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
92
+			for (Statement statement : member.body) {
93
+				isValid &= statement.accept(statementValidator);
94
+			}
95
+			
96
+			if (!statementValidator.constructorForwarded) {
97
+				// TODO: does this type have a supertype with no-argument constructor?
98
+			}
99
+		}
100
+		
101
+		return isValid;
102
+	}
103
+
104
+	@Override
105
+	public Boolean visitMethod(MethodMember member) {
106
+		boolean isValid = true;
107
+		isValid &= ValidationUtils.validateIdentifier(validator, member.position, member.name);
108
+		isValid &= ValidationUtils.validateHeader(validator, member.position, member.header);
109
+		
110
+		if (member.body != null) {
111
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
112
+			for (Statement statement : member.body) {
113
+				isValid &= statement.accept(statementValidator);
114
+			}
115
+		}
116
+		
117
+		return isValid;
118
+	}
119
+
120
+	@Override
121
+	public Boolean visitGetter(GetterMember member) {
122
+		boolean isValid = true;
123
+		isValid &= ValidationUtils.validateIdentifier(validator, member.position, member.name);
124
+		isValid &= member.type.accept(new TypeValidator(validator, member.position));
125
+		
126
+		if (member.body != null) {
127
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
128
+			for (Statement statement : member.body) {
129
+				isValid &= statement.accept(statementValidator);
130
+			}
131
+		}
132
+		
133
+		return isValid;
134
+	}
135
+
136
+	@Override
137
+	public Boolean visitSetter(SetterMember member) {
138
+		boolean isValid = true;
139
+		isValid &= ValidationUtils.validateIdentifier(validator, member.position, member.name);
140
+		isValid &= member.type.accept(new TypeValidator(validator, member.position));
141
+		
142
+		if (member.body != null) {
143
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
144
+			for (Statement statement : member.body) {
145
+				isValid &= statement.accept(statementValidator);
146
+			}
147
+		}
148
+		
149
+		return isValid;
150
+	}
151
+
152
+	@Override
153
+	public Boolean visitEnumConstant(EnumConstantMember member) {
154
+		boolean isValid = true;
155
+		isValid &= ValidationUtils.validateIdentifier(validator, member.position, member.name);
156
+		if (member.constructor != null) {
157
+			isValid &= member.constructor.accept(new ExpressionValidator(validator, new EnumConstantInitializerScope()));
158
+		}
159
+		if (members.contains(member.name)) {
160
+			validator.logError(ValidationLogEntry.Code.INVALID_TYPE, member.position, "Duplicate enum value: " + member.name);
161
+			isValid = false;
162
+		}
163
+		
164
+		initializedEnumConstants.add(member);
165
+		return isValid;
166
+	}
167
+
168
+	@Override
169
+	public Boolean visitOperator(OperatorMember member) {
170
+		boolean isValid = true;
171
+		isValid &= ValidationUtils.validateHeader(validator, member.position, member.header);
172
+		
173
+		if (member.body != null) {
174
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
175
+			for (Statement statement : member.body) {
176
+				isValid &= statement.accept(statementValidator);
177
+			}
178
+		}
179
+		
180
+		return isValid;
181
+	}
182
+
183
+	@Override
184
+	public Boolean visitCaster(CasterMember member) {
185
+		boolean isValid = true;
186
+		isValid &= member.toType.accept(new TypeValidator(validator, member.position));
187
+		
188
+		if (member.body != null) {
189
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
190
+			for (Statement statement : member.body) {
191
+				isValid &= statement.accept(statementValidator);
192
+			}
193
+		}
194
+		
195
+		return isValid;
196
+	}
197
+
198
+	@Override
199
+	public Boolean visitCustomIterator(CustomIteratorMember member) {
200
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
201
+	}
202
+
203
+	@Override
204
+	public Boolean visitCaller(CallerMember member) {
205
+		boolean isValid = true;
206
+		isValid &= ValidationUtils.validateHeader(validator, member.position, member.header);
207
+		
208
+		if (member.body != null) {
209
+			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
210
+			for (Statement statement : member.body) {
211
+				isValid &= statement.accept(statementValidator);
212
+			}
213
+		}
214
+		
215
+		return isValid;
216
+	}
217
+
218
+	@Override
219
+	public Boolean visitImplementation(ImplementationMember implementation) {
220
+		boolean isValid = true;
221
+		if (implementedTypes.contains(implementation.type)) {
222
+			validator.logError(
223
+					ValidationLogEntry.Code.TYPE_ALREADY_IMPLEMENTED,
224
+					implementation.position,
225
+					"Type is already implemented: " + implementation.type);
226
+			isValid = false;
227
+		}
228
+		implementedTypes.add(implementation.type);
229
+		
230
+		DefinitionMemberValidator memberValidator = new DefinitionMemberValidator(validator, definition);
231
+		for (IDefinitionMember member : implementation.members) {
232
+			isValid &= member.accept(memberValidator);
233
+		}
234
+		
235
+		return isValid;
236
+	}
237
+
238
+	@Override
239
+	public Boolean visitInnerDefinition(InnerDefinitionMember innerDefinition) {
240
+		boolean isValid = true;
241
+		if (members.contains(innerDefinition.innerDefinition.name)) {
242
+			validator.logError(
243
+					ValidationLogEntry.Code.DUPLICATE_MEMBER_NAME,
244
+					innerDefinition.position,
245
+					"Duplicate member name: " + innerDefinition.innerDefinition.name);
246
+			isValid = false;
247
+		}
248
+		
249
+		isValid &= innerDefinition.innerDefinition.accept(new DefinitionValidator(validator));
250
+		return isValid;
251
+	}
252
+	
253
+	private class FieldInitializerScope implements ExpressionScope {
254
+		private final FieldMember field;
255
+		
256
+		public FieldInitializerScope(FieldMember field) {
257
+			this.field = field;
258
+		}
259
+		
260
+		@Override
261
+		public boolean isConstructor() {
262
+			return false;
263
+		}
264
+
265
+		@Override
266
+		public boolean isFirstStatement() {
267
+			return true;
268
+		}
269
+
270
+		@Override
271
+		public boolean hasThis() {
272
+			return !field.isStatic();
273
+		}
274
+
275
+		@Override
276
+		public boolean isFieldInitialized(FieldMember field) {
277
+			return initializedFields.contains(field);
278
+		}
279
+
280
+		@Override
281
+		public void markConstructorForwarded() {
282
+			
283
+		}
284
+
285
+		@Override
286
+		public boolean isEnumConstantInitialized(EnumConstantMember member) {
287
+			return true;
288
+		}
289
+
290
+		@Override
291
+		public boolean isLocalVariableInitialized(VarStatement variable) {
292
+			return true; // TODO
293
+		}
294
+
295
+		@Override
296
+		public boolean isStaticInitializer() {
297
+			return false;
298
+		}
299
+
300
+		@Override
301
+		public HighLevelDefinition getDefinition() {
302
+			return definition;
303
+		}
304
+	}
305
+	
306
+	private class ConstructorStatementScope implements StatementScope {
307
+		private final FunctionHeader header;
308
+		
309
+		public ConstructorStatementScope(FunctionHeader header) {
310
+			this.header = header;
311
+		}
312
+
313
+		@Override
314
+		public boolean isConstructor() {
315
+			return true;
316
+		}
317
+
318
+		@Override
319
+		public boolean isStatic() {
320
+			return false;
321
+		}
322
+
323
+		@Override
324
+		public FunctionHeader getFunctionHeader() {
325
+			return header;
326
+		}
327
+
328
+		@Override
329
+		public boolean isStaticInitializer() {
330
+			return false;
331
+		}
332
+
333
+		@Override
334
+		public HighLevelDefinition getDefinition() {
335
+			return definition;
336
+		}
337
+	}
338
+	
339
+	private class EnumConstantInitializerScope implements ExpressionScope {
340
+
341
+		@Override
342
+		public boolean isConstructor() {
343
+			return false;
344
+		}
345
+
346
+		@Override
347
+		public boolean isFirstStatement() {
348
+			return false;
349
+		}
350
+
351
+		@Override
352
+		public boolean hasThis() {
353
+			return false;
354
+		}
355
+
356
+		@Override
357
+		public boolean isFieldInitialized(FieldMember field) {
358
+			return false;
359
+		}
360
+
361
+		@Override
362
+		public void markConstructorForwarded() {
363
+			
364
+		}
365
+
366
+		@Override
367
+		public boolean isEnumConstantInitialized(EnumConstantMember member) {
368
+			if (member.definition == definition) {
369
+				return initializedEnumConstants.contains(member);
370
+			} else {
371
+				return true;
372
+			}
373
+		}
374
+
375
+		@Override
376
+		public boolean isLocalVariableInitialized(VarStatement variable) {
377
+			return false;
378
+		}
379
+
380
+		@Override
381
+		public boolean isStaticInitializer() {
382
+			return false;
383
+		}
384
+
385
+		@Override
386
+		public HighLevelDefinition getDefinition() {
387
+			return definition;
388
+		}
389
+	}
390
+}

+ 208
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionValidator.java View File

@@ -0,0 +1,208 @@
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.validator.visitors;
7
+
8
+import org.openzen.zenscript.codemodel.FunctionHeader;
9
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
10
+import static org.openzen.zenscript.codemodel.Modifiers.*;
11
+import org.openzen.zenscript.codemodel.definition.AliasDefinition;
12
+import org.openzen.zenscript.codemodel.definition.ClassDefinition;
13
+import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
14
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
15
+import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
16
+import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
17
+import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
18
+import org.openzen.zenscript.codemodel.definition.StructDefinition;
19
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
20
+import org.openzen.zenscript.codemodel.statement.Statement;
21
+import org.openzen.zenscript.validator.Validator;
22
+import org.openzen.zenscript.validator.analysis.StatementScope;
23
+
24
+/**
25
+ *
26
+ * @author Hoofdgebruiker
27
+ */
28
+public class DefinitionValidator implements DefinitionVisitor<Boolean> {
29
+	private final Validator validator;
30
+	
31
+	public DefinitionValidator(Validator validator) {
32
+		this.validator = validator;
33
+	}
34
+
35
+	@Override
36
+	public Boolean visitClass(ClassDefinition definition) {
37
+		boolean isValid = true;
38
+		isValid &= ValidationUtils.validateModifiers(
39
+				validator,
40
+				definition.modifiers,
41
+				PUBLIC | EXPORT | PRIVATE | ABSTRACT | STATIC | PROTECTED | VIRTUAL,
42
+				definition.position,
43
+				"Invalid class modifier");
44
+		isValid &= ValidationUtils.validateIdentifier(
45
+				validator,
46
+				definition.position,
47
+				definition.name);
48
+		
49
+		if (definition.superType != null)
50
+			isValid &= definition.superType.accept(new SupertypeValidator(validator, definition.position));
51
+		
52
+		isValid &= validateMembers(definition);
53
+		return isValid;
54
+	}
55
+
56
+	@Override
57
+	public Boolean visitInterface(InterfaceDefinition definition) {
58
+		boolean isValid = true;
59
+		isValid &= ValidationUtils.validateModifiers(
60
+				validator,
61
+				definition.modifiers,
62
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
63
+				definition.position,
64
+				"Invalid interface modifier");
65
+		isValid &= ValidationUtils.validateIdentifier(
66
+				validator,
67
+				definition.position,
68
+				definition.name);
69
+		
70
+		isValid &= validateMembers(definition);
71
+		return isValid;
72
+	}
73
+
74
+	@Override
75
+	public Boolean visitEnum(EnumDefinition definition) {
76
+		boolean isValid = true;
77
+		isValid &= ValidationUtils.validateModifiers(
78
+				validator,
79
+				definition.modifiers,
80
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
81
+				definition.position,
82
+				"Invalid enum modifier");
83
+		isValid &= ValidationUtils.validateIdentifier(
84
+				validator,
85
+				definition.position,
86
+				definition.name);
87
+		
88
+		isValid &= validateMembers(definition);
89
+		return isValid;
90
+	}
91
+
92
+	@Override
93
+	public Boolean visitStruct(StructDefinition definition) {
94
+		boolean isValid = true;
95
+		isValid &= ValidationUtils.validateModifiers(
96
+				validator,
97
+				definition.modifiers,
98
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
99
+				definition.position,
100
+				"Invalid struct modifier");
101
+		isValid &= ValidationUtils.validateIdentifier(
102
+				validator,
103
+				definition.position,
104
+				definition.name);
105
+		
106
+		isValid &= validateMembers(definition);
107
+		return isValid;
108
+	}
109
+
110
+	@Override
111
+	public Boolean visitFunction(FunctionDefinition definition) {
112
+		boolean isValid = true;
113
+		isValid &= ValidationUtils.validateModifiers(
114
+				validator,
115
+				definition.modifiers,
116
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
117
+				definition.position,
118
+				"Invalid function modifier");
119
+		isValid &= ValidationUtils.validateIdentifier(
120
+				validator,
121
+				definition.position,
122
+				definition.name);
123
+				
124
+		StatementValidator statementValidator = new StatementValidator(validator, new FunctionStatementScope(definition.header));
125
+		for (Statement statement : definition.statements) {
126
+			isValid &= statement.accept(statementValidator);
127
+		}
128
+		return isValid;
129
+	}
130
+
131
+	@Override
132
+	public Boolean visitExpansion(ExpansionDefinition definition) {
133
+		boolean isValid = true;
134
+		isValid &= ValidationUtils.validateModifiers(
135
+				validator,
136
+				definition.modifiers,
137
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
138
+				definition.position,
139
+				"Invalid expansion modifier");
140
+		isValid &= ValidationUtils.validateIdentifier(
141
+				validator,
142
+				definition.position,
143
+				definition.name);
144
+		
145
+		isValid &= definition.target.accept(new TypeValidator(validator, definition.position));
146
+		isValid &= validateMembers(definition);
147
+		return isValid;
148
+	}
149
+
150
+	@Override
151
+	public Boolean visitAlias(AliasDefinition definition) {
152
+		boolean isValid = true;
153
+		isValid &= ValidationUtils.validateModifiers(
154
+				validator,
155
+				definition.modifiers,
156
+				PUBLIC | EXPORT | PROTECTED | PRIVATE,
157
+				definition.position,
158
+				"Invalid alias modifier");
159
+		isValid &= ValidationUtils.validateIdentifier(
160
+				validator,
161
+				definition.position,
162
+				definition.name);
163
+		
164
+		return isValid;
165
+	}
166
+	
167
+	private boolean validateMembers(HighLevelDefinition definition) {
168
+		DefinitionMemberValidator memberValidator = new DefinitionMemberValidator(validator, definition);
169
+		boolean isValid = true;
170
+		for (IDefinitionMember member : definition.members) {
171
+			isValid &= member.accept(memberValidator);
172
+		}
173
+		return isValid;
174
+	}
175
+	
176
+	private class FunctionStatementScope implements StatementScope {
177
+		private final FunctionHeader header;
178
+		
179
+		public FunctionStatementScope(FunctionHeader header) {
180
+			this.header = header;
181
+		}
182
+
183
+		@Override
184
+		public boolean isConstructor() {
185
+			return false;
186
+		}
187
+
188
+		@Override
189
+		public boolean isStatic() {
190
+			return true;
191
+		}
192
+
193
+		@Override
194
+		public FunctionHeader getFunctionHeader() {
195
+			return header;
196
+		}
197
+
198
+		@Override
199
+		public boolean isStaticInitializer() {
200
+			return false;
201
+		}
202
+
203
+		@Override
204
+		public HighLevelDefinition getDefinition() {
205
+			return null;
206
+		}
207
+	}
208
+}

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

@@ -0,0 +1,663 @@
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.validator.visitors;
7
+
8
+import org.openzen.zenscript.codemodel.FunctionHeader;
9
+import org.openzen.zenscript.codemodel.FunctionParameter;
10
+import org.openzen.zenscript.codemodel.expression.AndAndExpression;
11
+import org.openzen.zenscript.codemodel.expression.ArrayExpression;
12
+import org.openzen.zenscript.codemodel.expression.BasicCompareExpression;
13
+import org.openzen.zenscript.codemodel.expression.CallArguments;
14
+import org.openzen.zenscript.codemodel.expression.CallExpression;
15
+import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
16
+import org.openzen.zenscript.codemodel.expression.CapturedClosureExpression;
17
+import org.openzen.zenscript.codemodel.expression.CapturedDirectExpression;
18
+import org.openzen.zenscript.codemodel.expression.CapturedLocalVariableExpression;
19
+import org.openzen.zenscript.codemodel.expression.CapturedParameterExpression;
20
+import org.openzen.zenscript.codemodel.expression.CapturedThisExpression;
21
+import org.openzen.zenscript.codemodel.expression.CastExpression;
22
+import org.openzen.zenscript.codemodel.expression.CheckNullExpression;
23
+import org.openzen.zenscript.codemodel.expression.CoalesceExpression;
24
+import org.openzen.zenscript.codemodel.expression.ConditionalExpression;
25
+import org.openzen.zenscript.codemodel.expression.ConstantBoolExpression;
26
+import org.openzen.zenscript.codemodel.expression.ConstantByteExpression;
27
+import org.openzen.zenscript.codemodel.expression.ConstantCharExpression;
28
+import org.openzen.zenscript.codemodel.expression.ConstantDoubleExpression;
29
+import org.openzen.zenscript.codemodel.expression.ConstantFloatExpression;
30
+import org.openzen.zenscript.codemodel.expression.ConstantIntExpression;
31
+import org.openzen.zenscript.codemodel.expression.ConstantLongExpression;
32
+import org.openzen.zenscript.codemodel.expression.ConstantSByteExpression;
33
+import org.openzen.zenscript.codemodel.expression.ConstantShortExpression;
34
+import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
35
+import org.openzen.zenscript.codemodel.expression.ConstantUIntExpression;
36
+import org.openzen.zenscript.codemodel.expression.ConstantULongExpression;
37
+import org.openzen.zenscript.codemodel.expression.ConstantUShortExpression;
38
+import org.openzen.zenscript.codemodel.expression.ConstructorSuperCallExpression;
39
+import org.openzen.zenscript.codemodel.expression.ConstructorThisCallExpression;
40
+import org.openzen.zenscript.codemodel.expression.EnumConstantExpression;
41
+import org.openzen.zenscript.codemodel.expression.Expression;
42
+import org.openzen.zenscript.codemodel.expression.ExpressionVisitor;
43
+import org.openzen.zenscript.codemodel.expression.FunctionExpression;
44
+import org.openzen.zenscript.codemodel.expression.GenericCompareExpression;
45
+import org.openzen.zenscript.codemodel.expression.GetFieldExpression;
46
+import org.openzen.zenscript.codemodel.expression.GetFunctionParameterExpression;
47
+import org.openzen.zenscript.codemodel.expression.GetLocalVariableExpression;
48
+import org.openzen.zenscript.codemodel.expression.GetStaticFieldExpression;
49
+import org.openzen.zenscript.codemodel.expression.GetterExpression;
50
+import org.openzen.zenscript.codemodel.expression.GlobalCallExpression;
51
+import org.openzen.zenscript.codemodel.expression.GlobalExpression;
52
+import org.openzen.zenscript.codemodel.expression.InterfaceCastExpression;
53
+import org.openzen.zenscript.codemodel.expression.IsExpression;
54
+import org.openzen.zenscript.codemodel.expression.MakeConstExpression;
55
+import org.openzen.zenscript.codemodel.expression.MapExpression;
56
+import org.openzen.zenscript.codemodel.expression.NewExpression;
57
+import org.openzen.zenscript.codemodel.expression.NullExpression;
58
+import org.openzen.zenscript.codemodel.expression.OrOrExpression;
59
+import org.openzen.zenscript.codemodel.expression.RangeExpression;
60
+import org.openzen.zenscript.codemodel.expression.SetFieldExpression;
61
+import org.openzen.zenscript.codemodel.expression.SetFunctionParameterExpression;
62
+import org.openzen.zenscript.codemodel.expression.SetLocalVariableExpression;
63
+import org.openzen.zenscript.codemodel.expression.SetStaticFieldExpression;
64
+import org.openzen.zenscript.codemodel.expression.SetterExpression;
65
+import org.openzen.zenscript.codemodel.expression.StaticGetterExpression;
66
+import org.openzen.zenscript.codemodel.expression.StaticSetterExpression;
67
+import org.openzen.zenscript.codemodel.expression.ThisExpression;
68
+import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
69
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
70
+import org.openzen.zenscript.codemodel.type.AssocTypeID;
71
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
72
+import org.openzen.zenscript.codemodel.type.ITypeID;
73
+import org.openzen.zenscript.codemodel.type.RangeTypeID;
74
+import org.openzen.zenscript.shared.CodePosition;
75
+import org.openzen.zenscript.validator.ValidationLogEntry;
76
+import org.openzen.zenscript.validator.Validator;
77
+import org.openzen.zenscript.validator.analysis.ExpressionScope;
78
+
79
+/**
80
+ *
81
+ * @author Hoofdgebruiker
82
+ */
83
+public class ExpressionValidator implements ExpressionVisitor<Boolean> {
84
+	private final Validator validator;
85
+	private final ExpressionScope scope;
86
+	
87
+	public ExpressionValidator(Validator validator, ExpressionScope scope) {
88
+		this.validator = validator;
89
+		this.scope = scope;
90
+	}
91
+
92
+	@Override
93
+	public Boolean visitAndAnd(AndAndExpression expression) {
94
+		boolean isValid =
95
+				expression.left.accept(this)
96
+				& expression.right.accept(this);
97
+		
98
+		if (expression.left.type != BasicTypeID.BOOL) {
99
+			validator.logError(
100
+					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
101
+					expression.position,
102
+					"left hand side operand of && must be a bool");
103
+			isValid = false;
104
+		}
105
+		if (expression.right.type != BasicTypeID.BOOL) {
106
+			validator.logError(
107
+					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
108
+					expression.position,
109
+					"right hand side operand of && must be a bool");
110
+			isValid = false;
111
+		}
112
+		return isValid;
113
+	}
114
+
115
+	@Override
116
+	public Boolean visitArray(ArrayExpression expression) {
117
+		boolean isValid = true;
118
+		for (Expression element : expression.expressions) {
119
+			if (element.type != expression.arrayType.elementType) {
120
+				validator.logError(
121
+					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
122
+					expression.position,
123
+					"array element expression type doesn't match array type");
124
+				isValid = false;
125
+			}
126
+			isValid &= element.accept(this);
127
+		}
128
+		return isValid;
129
+	}
130
+
131
+	@Override
132
+	public Boolean visitCompare(BasicCompareExpression expression) {
133
+		boolean isValid = true;
134
+		if (expression.left.type != expression.right.type) {
135
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "comparison must be between the same types");
136
+			isValid = false;
137
+		}
138
+		isValid &= expression.left.accept(this);
139
+		isValid &= expression.right.accept(this);
140
+		return isValid;
141
+	}
142
+
143
+	@Override
144
+	public Boolean visitCall(CallExpression expression) {
145
+		boolean isValid = true;
146
+		isValid &= expression.target.accept(this);
147
+		isValid &= checkCallArguments(expression.position, expression.member.header, expression.arguments);
148
+		return isValid;
149
+	}
150
+
151
+	@Override
152
+	public Boolean visitCallStatic(CallStaticExpression expression) {
153
+		return checkCallArguments(expression.position, expression.member.header, expression.arguments);
154
+	}
155
+
156
+	@Override
157
+	public Boolean visitCapturedClosure(CapturedClosureExpression expression) {
158
+		return true;
159
+	}
160
+
161
+	@Override
162
+	public Boolean visitCapturedDirect(CapturedDirectExpression expression) {
163
+		return true;
164
+	}
165
+
166
+	@Override
167
+	public Boolean visitCapturedLocalVariable(CapturedLocalVariableExpression expression) {
168
+		return true;
169
+	}
170
+
171
+	@Override
172
+	public Boolean visitCapturedParameter(CapturedParameterExpression expression) {
173
+		return true;
174
+	}
175
+
176
+	@Override
177
+	public Boolean visitCapturedThis(CapturedThisExpression expression) {
178
+		return true;
179
+	}
180
+
181
+	@Override
182
+	public Boolean visitCast(CastExpression expression) {
183
+		return expression.target.accept(this);
184
+	}
185
+
186
+	@Override
187
+	public Boolean visitCheckNull(CheckNullExpression expression) {
188
+		boolean isValid = true;
189
+		isValid &= expression.value.accept(this);
190
+		if (!expression.value.type.isOptional()) {
191
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "target of a null check is not optional");
192
+			isValid = false;
193
+		}
194
+		return isValid;
195
+	}
196
+
197
+	@Override
198
+	public Boolean visitCoalesce(CoalesceExpression expression) {
199
+		boolean isValid = true;
200
+		isValid &= expression.left.accept(this);
201
+		isValid &= expression.right.accept(this);
202
+		if (!expression.left.type.isOptional()) {
203
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "target of a null coalesce is not optional");
204
+			isValid = false;
205
+		}
206
+		return isValid;
207
+	}
208
+
209
+	@Override
210
+	public Boolean visitConditional(ConditionalExpression expression) {
211
+		boolean isValid = true;
212
+		isValid &= expression.condition.accept(this);
213
+		isValid &= expression.ifThen.accept(this);
214
+		isValid &= expression.ifElse.accept(this);
215
+		if (expression.condition.type != BasicTypeID.BOOL) {
216
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "conditional expression condition must be a bool");
217
+			isValid = false;
218
+		}
219
+		return isValid;
220
+	}
221
+
222
+	@Override
223
+	public Boolean visitConstantBool(ConstantBoolExpression expression) {
224
+		return true;
225
+	}
226
+
227
+	@Override
228
+	public Boolean visitConstantByte(ConstantByteExpression expression) {
229
+		return true;
230
+	}
231
+
232
+	@Override
233
+	public Boolean visitConstantChar(ConstantCharExpression expression) {
234
+		return true;
235
+	}
236
+
237
+	@Override
238
+	public Boolean visitConstantDouble(ConstantDoubleExpression expression) {
239
+		return true;
240
+	}
241
+
242
+	@Override
243
+	public Boolean visitConstantFloat(ConstantFloatExpression expression) {
244
+		return true;
245
+	}
246
+
247
+	@Override
248
+	public Boolean visitConstantInt(ConstantIntExpression expression) {
249
+		return true;
250
+	}
251
+
252
+	@Override
253
+	public Boolean visitConstantLong(ConstantLongExpression expression) {
254
+		return true;
255
+	}
256
+
257
+	@Override
258
+	public Boolean visitConstantSByte(ConstantSByteExpression expression) {
259
+		return true;
260
+	}
261
+
262
+	@Override
263
+	public Boolean visitConstantShort(ConstantShortExpression expression) {
264
+		return true;
265
+	}
266
+
267
+	@Override
268
+	public Boolean visitConstantString(ConstantStringExpression expression) {
269
+		return true;
270
+	}
271
+
272
+	@Override
273
+	public Boolean visitConstantUInt(ConstantUIntExpression expression) {
274
+		return true;
275
+	}
276
+
277
+	@Override
278
+	public Boolean visitConstantULong(ConstantULongExpression expression) {
279
+		return true;
280
+	}
281
+
282
+	@Override
283
+	public Boolean visitConstantUShort(ConstantUShortExpression expression) {
284
+		return true;
285
+	}
286
+
287
+	@Override
288
+	public Boolean visitConstructorThisCall(ConstructorThisCallExpression expression) {
289
+		boolean isValid = true;
290
+		if (!scope.isConstructor()) {
291
+			validator.logError(ValidationLogEntry.Code.CONSTRUCTOR_FORWARD_OUTSIDE_CONSTRUCTOR, expression.position, "Can only forward constructors inside constructors");
292
+			isValid = false;
293
+		}
294
+		if (!scope.isFirstStatement()) {
295
+			validator.logError(ValidationLogEntry.Code.CONSTRUCTOR_FORWARD_NOT_FIRST_STATEMENT, expression.position, "Constructor forwarder must be first expression");
296
+			isValid = false;
297
+		}
298
+		scope.markConstructorForwarded();
299
+		isValid &= checkCallArguments(expression.position, expression.constructor.header, expression.arguments);
300
+		return isValid;
301
+	}
302
+
303
+	@Override
304
+	public Boolean visitConstructorSuperCall(ConstructorSuperCallExpression expression) {
305
+		boolean isValid = true;
306
+		if (!scope.isConstructor()) {
307
+			validator.logError(ValidationLogEntry.Code.CONSTRUCTOR_FORWARD_OUTSIDE_CONSTRUCTOR, expression.position, "Can only forward constructors inside constructors");
308
+			isValid = false;
309
+		}
310
+		if (!scope.isFirstStatement()) {
311
+			validator.logError(ValidationLogEntry.Code.CONSTRUCTOR_FORWARD_NOT_FIRST_STATEMENT, expression.position, "Constructor forwarder must be first expression");
312
+			isValid = false;
313
+		}
314
+		scope.markConstructorForwarded();
315
+		isValid &= checkCallArguments(expression.position, expression.constructor.header, expression.arguments);
316
+		return isValid;
317
+	}
318
+
319
+	@Override
320
+	public Boolean visitEnumConstant(EnumConstantExpression expression) {
321
+		if (!scope.isEnumConstantInitialized(expression.value)) {
322
+			validator.logError(
323
+					ValidationLogEntry.Code.ENUM_CONSTANT_NOT_YET_INITIALIZED,
324
+					expression.position,
325
+					"Using an enum constant that is not yet initialized: " + expression.value.name);
326
+			return false;
327
+		}
328
+		return true;
329
+	}
330
+
331
+	@Override
332
+	public Boolean visitFunction(FunctionExpression expression) {
333
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
334
+	}
335
+
336
+	@Override
337
+	public Boolean visitGenericCompare(GenericCompareExpression expression) {
338
+		boolean isValid = expression.value.accept(this);
339
+		if (expression.value.type != BasicTypeID.INT) {
340
+			validator.logError(
341
+					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
342
+					expression.position,
343
+					"Generic compare expression must be an int");
344
+			isValid = false;
345
+		}
346
+		return isValid;
347
+	}
348
+
349
+	@Override
350
+	public Boolean visitGetField(GetFieldExpression expression) {
351
+		boolean isValid = true;
352
+		isValid &= expression.target.accept(this);
353
+		if (expression.target instanceof ThisExpression && !scope.isFieldInitialized(expression.field)) {
354
+			validator.logError(
355
+					ValidationLogEntry.Code.FIELD_NOT_YET_INITIALIZED,
356
+					expression.position,
357
+					"Using a field that was not yet initialized");
358
+			isValid = false;
359
+		}
360
+		return isValid;
361
+	}
362
+
363
+	@Override
364
+	public Boolean visitGetFunctionParameter(GetFunctionParameterExpression expression) {
365
+		return true;
366
+	}
367
+
368
+	@Override
369
+	public Boolean visitGetLocalVariable(GetLocalVariableExpression expression) {
370
+		boolean isValid = true;
371
+		if (!scope.isLocalVariableInitialized(expression.variable)) {
372
+			validator.logError(ValidationLogEntry.Code.LOCAL_VARIABLE_NOT_YET_INITIALIZED, expression.position, "Local variable not yet initialized");
373
+			isValid = false;
374
+		}
375
+		return isValid;
376
+	}
377
+
378
+	@Override
379
+	public Boolean visitGetStaticField(GetStaticFieldExpression expression) {
380
+		return true;
381
+	}
382
+
383
+	@Override
384
+	public Boolean visitGetter(GetterExpression expression) {
385
+		return expression.target.accept(this);
386
+	}
387
+	
388
+	@Override
389
+	public Boolean visitGlobal(GlobalExpression expression) {
390
+		return expression.resolution.accept(this);
391
+	}
392
+	
393
+	@Override
394
+	public Boolean visitGlobalCall(GlobalCallExpression expression) {
395
+		return expression.resolution.accept(this);
396
+	}
397
+
398
+	@Override
399
+	public Boolean visitInterfaceCast(InterfaceCastExpression expression) {
400
+		boolean isValid = true;
401
+		isValid &= expression.value.accept(this);
402
+		isValid &= expression.type.accept(new TypeValidator(validator, expression.position));
403
+		return isValid;
404
+	}
405
+
406
+	@Override
407
+	public Boolean visitIs(IsExpression expression) {
408
+		boolean isValid = true;
409
+		isValid &= expression.value.accept(this);
410
+		isValid &= expression.isType.accept(new TypeValidator(validator, expression.position));
411
+		return isValid;
412
+	}
413
+
414
+	@Override
415
+	public Boolean visitMakeConst(MakeConstExpression expression) {
416
+		return expression.value.accept(this);
417
+	}
418
+
419
+	@Override
420
+	public Boolean visitMap(MapExpression expression) {
421
+		boolean isValid = true;
422
+		AssocTypeID type = (AssocTypeID) expression.type;
423
+		for (int i = 0; i < expression.keys.length; i++) {
424
+			Expression key = expression.keys[i];
425
+			Expression value = expression.values[i];
426
+			
427
+			isValid &= key.accept(this);
428
+			isValid &= value.accept(this);
429
+			if (key.type != type.keyType) {
430
+				validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, key.position, "Key type must match the associative array key type");
431
+				isValid = false;
432
+			}
433
+			if (value.type != type.valueType) {
434
+				validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, key.position, "Value type must match the associative array value type");
435
+				isValid = false;
436
+			}
437
+		}
438
+		return isValid;
439
+	}
440
+
441
+	@Override
442
+	public Boolean visitNew(NewExpression expression) {
443
+		boolean isValid = checkCallArguments(
444
+				expression.position,
445
+				expression.constructor.header,
446
+				expression.arguments);
447
+		return isValid;
448
+	}
449
+
450
+	@Override
451
+	public Boolean visitNull(NullExpression expression) {
452
+		return true;
453
+	}
454
+
455
+	@Override
456
+	public Boolean visitOrOr(OrOrExpression expression) {
457
+		boolean isValid = true;
458
+		isValid &= expression.left.accept(this);
459
+		isValid &= expression.right.accept(this);
460
+		if (expression.left.type != BasicTypeID.BOOL) {
461
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "Left hand side of || expression is not a bool");
462
+			isValid = false;
463
+		}
464
+		if (expression.right.type != BasicTypeID.BOOL) {
465
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "Right hand side of || expression is not a bool");
466
+			isValid = false;
467
+		}
468
+		return isValid;
469
+	}
470
+
471
+	@Override
472
+	public Boolean visitRange(RangeExpression expression) {
473
+		boolean isValid = true;
474
+		isValid &= expression.from.accept(this);
475
+		isValid &= expression.to.accept(this);
476
+		
477
+		RangeTypeID rangeType = (RangeTypeID) expression.type;
478
+		if (expression.from.type != rangeType.from) {
479
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "From operand is not a " + rangeType.from.toString());
480
+			isValid = false;
481
+		}
482
+		if (expression.to.type != rangeType.to) {
483
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "To operand is not a " + rangeType.to.toString());
484
+			isValid = false;
485
+		}
486
+		return isValid;
487
+	}
488
+
489
+	@Override
490
+	public Boolean visitSetField(SetFieldExpression expression) {
491
+		boolean isValid = true;
492
+		isValid &= expression.target.accept(this);
493
+		isValid &= expression.value.accept(this);
494
+		if (expression.value.type != expression.field.type) {
495
+			validator.logError(
496
+					ValidationLogEntry.Code.INVALID_SOURCE_TYPE, 
497
+					expression.position,
498
+					"Trying to set a field of type " + expression.field.type + " to a value of type " + expression.value.type);
499
+			isValid = false;
500
+		}
501
+		if (expression.field.isFinal()) {
502
+			if (!(expression.target instanceof ThisExpression && scope.isConstructor())) {
503
+				validator.logError(ValidationLogEntry.Code.SETTING_FINAL_FIELD, expression.position, "Cannot set a final field");
504
+				isValid = false;
505
+			}
506
+		}
507
+		return isValid;
508
+	}
509
+
510
+	@Override
511
+	public Boolean visitSetFunctionParameter(SetFunctionParameterExpression expression) {
512
+		boolean isValid = true;
513
+		isValid &= expression.value.accept(this);
514
+		if (expression.value.type != expression.parameter.type) {
515
+			validator.logError(
516
+					ValidationLogEntry.Code.INVALID_SOURCE_TYPE, 
517
+					expression.position,
518
+					"Trying to set a parameter of type " + expression.parameter.type + " to a value of type " + expression.value.type);
519
+			isValid = false;
520
+		}
521
+		return isValid;
522
+	}
523
+
524
+	@Override
525
+	public Boolean visitSetLocalVariable(SetLocalVariableExpression expression) {
526
+		boolean isValid = true;
527
+		isValid &= expression.value.accept(this);
528
+		if (expression.value.type != expression.variable.type) {
529
+			validator.logError(
530
+					ValidationLogEntry.Code.INVALID_SOURCE_TYPE, 
531
+					expression.position,
532
+					"Trying to set a variable of type " + expression.variable.type + " to a value of type " + expression.value.type);
533
+			isValid = false;
534
+		}
535
+		if (expression.variable.isFinal) {
536
+			validator.logError(ValidationLogEntry.Code.SETTING_FINAL_VARIABLE, expression.position, "Trying to set final variable " + expression.variable.name);
537
+			isValid = false;
538
+		}
539
+		return isValid;
540
+	}
541
+
542
+	@Override
543
+	public Boolean visitSetStaticField(SetStaticFieldExpression expression) {
544
+		boolean isValid = true;
545
+		isValid &= expression.value.accept(this);
546
+		if (expression.value.type != expression.field.type) {
547
+			validator.logError(
548
+					ValidationLogEntry.Code.INVALID_SOURCE_TYPE,
549
+					expression.position,
550
+					"Trying to set a static field of type " + expression.field.type + " to a value of type " + expression.value.type);
551
+			isValid = false;
552
+		}
553
+		if (expression.field.isFinal()) {
554
+			if (!scope.isStaticInitializer() || expression.field.definition != scope.getDefinition()) {
555
+				validator.logError(
556
+						ValidationLogEntry.Code.SETTING_FINAL_FIELD,
557
+						expression.position,
558
+						"Trying to set final field " + expression.field.name);
559
+				isValid = false;
560
+			}
561
+		}
562
+		return isValid;
563
+	}
564
+
565
+	@Override
566
+	public Boolean visitSetter(SetterExpression expression) {
567
+		boolean isValid = true;
568
+		isValid &= expression.target.accept(this);
569
+		isValid &= expression.value.accept(this);
570
+		if (expression.value.type != expression.setter.type) {
571
+			validator.logError(
572
+					ValidationLogEntry.Code.INVALID_SOURCE_TYPE,
573
+					expression.position,
574
+					"Trying to set a property of type " + expression.setter.type + " to a value of type " + expression.value.type);
575
+			isValid = false;
576
+		}
577
+		return isValid;
578
+	}
579
+
580
+	@Override
581
+	public Boolean visitStaticGetter(StaticGetterExpression expression) {
582
+		return true;
583
+	}
584
+
585
+	@Override
586
+	public Boolean visitStaticSetter(StaticSetterExpression expression) {
587
+		boolean isValid = true;
588
+		isValid &= expression.value.accept(this);
589
+		if (expression.value.type != expression.setter.type) {
590
+			validator.logError(
591
+					ValidationLogEntry.Code.INVALID_SOURCE_TYPE,
592
+					expression.position,
593
+					"Trying to set a static property of type " + expression.setter.type + " to a value of type " + expression.value.type);
594
+			isValid = false;
595
+		}
596
+		return isValid;
597
+	}
598
+
599
+	@Override
600
+	public Boolean visitThis(ThisExpression expression) {
601
+		if (!scope.hasThis()) {
602
+			validator.logError(ValidationLogEntry.Code.THIS_IN_STATIC_SCOPE, expression.position, "Cannot use this in a static scope");
603
+			return false;
604
+		}
605
+		
606
+		return true;
607
+	}
608
+
609
+	@Override
610
+	public Boolean visitWrapOptional(WrapOptionalExpression expression) {
611
+		boolean isValid = expression.value.accept(this);
612
+		if (expression.type.isOptional()) {
613
+			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "expression value is already optional");
614
+			isValid = false;
615
+		}
616
+		return isValid;
617
+	}
618
+	
619
+	private boolean checkCallArguments(CodePosition position, FunctionHeader header, CallArguments arguments) {
620
+		boolean isValid = true;
621
+		isValid &= ValidationUtils.validateTypeArguments(validator, position, header.typeParameters, arguments.typeArguments);
622
+		
623
+		for (int i = 0; i < arguments.arguments.length; i++) {
624
+			Expression argument = arguments.arguments[i];
625
+			isValid &= argument.accept(this);
626
+			
627
+			if (i >= header.parameters.length) {
628
+				FunctionParameter variadic = header.getVariadicParameter();
629
+				if (variadic == null) {
630
+					validator.logError(ValidationLogEntry.Code.INVALID_CALL_ARGUMENT, position, "too many call arguments");
631
+					isValid = false;
632
+					break;
633
+				} else if (variadic.type instanceof ArrayTypeID) {
634
+					ITypeID elementType = ((ArrayTypeID)variadic.type).elementType;
635
+					if (elementType != argument.type) {
636
+						validator.logError(ValidationLogEntry.Code.INVALID_CALL_ARGUMENT, position, "invalid type for variadic call argument");
637
+						isValid = false;
638
+						break;
639
+					}
640
+				}
641
+			}
642
+			
643
+			FunctionParameter parameter = header.parameters[i];
644
+			if (parameter.type != argument.type) {
645
+				validator.logError(
646
+						ValidationLogEntry.Code.INVALID_CALL_ARGUMENT,
647
+						position,
648
+						"invalid value for parameter " + parameter.name + ": " + parameter.type.toString() + " expected but " + arguments.arguments[i].type + " given");
649
+				isValid = false;
650
+			}
651
+		}
652
+		
653
+		for (int i = arguments.arguments.length; i < header.parameters.length; i++) {
654
+			FunctionParameter parameter = header.parameters[i];
655
+			if (parameter.defaultValue == null && !parameter.variadic) {
656
+				validator.logError(ValidationLogEntry.Code.INVALID_CALL_ARGUMENT, position, "missing call argument for " + parameter.name);
657
+				isValid = false;
658
+			}
659
+		}
660
+		
661
+		return isValid;
662
+	}
663
+}

+ 304
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/StatementValidator.java View File

@@ -0,0 +1,304 @@
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.validator.visitors;
7
+
8
+import java.util.HashSet;
9
+import java.util.Set;
10
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
+import org.openzen.zenscript.codemodel.expression.Expression;
12
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
13
+import org.openzen.zenscript.codemodel.member.FieldMember;
14
+import org.openzen.zenscript.codemodel.statement.BlockStatement;
15
+import org.openzen.zenscript.codemodel.statement.BreakStatement;
16
+import org.openzen.zenscript.codemodel.statement.CatchClause;
17
+import org.openzen.zenscript.codemodel.statement.ContinueStatement;
18
+import org.openzen.zenscript.codemodel.statement.DoWhileStatement;
19
+import org.openzen.zenscript.codemodel.statement.EmptyStatement;
20
+import org.openzen.zenscript.codemodel.statement.ExpressionStatement;
21
+import org.openzen.zenscript.codemodel.statement.ForeachStatement;
22
+import org.openzen.zenscript.codemodel.statement.IfStatement;
23
+import org.openzen.zenscript.codemodel.statement.LockStatement;
24
+import org.openzen.zenscript.codemodel.statement.ReturnStatement;
25
+import org.openzen.zenscript.codemodel.statement.Statement;
26
+import org.openzen.zenscript.codemodel.statement.StatementVisitor;
27
+import org.openzen.zenscript.codemodel.statement.ThrowStatement;
28
+import org.openzen.zenscript.codemodel.statement.TryCatchStatement;
29
+import org.openzen.zenscript.codemodel.statement.VarStatement;
30
+import org.openzen.zenscript.codemodel.statement.WhileStatement;
31
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
32
+import org.openzen.zenscript.validator.ValidationLogEntry;
33
+import org.openzen.zenscript.validator.Validator;
34
+import org.openzen.zenscript.validator.analysis.ExpressionScope;
35
+import org.openzen.zenscript.validator.analysis.StatementScope;
36
+
37
+/**
38
+ *
39
+ * @author Hoofdgebruiker
40
+ */
41
+public class StatementValidator implements StatementVisitor<Boolean> {
42
+	private final Validator validator;
43
+	private final StatementScope scope;
44
+	private final Set<String> variables = new HashSet<>();
45
+	private boolean firstStatement = true;
46
+	
47
+	public boolean constructorForwarded = true;
48
+	
49
+	public StatementValidator(Validator validator, StatementScope scope) {
50
+		this.validator = validator;
51
+		this.scope = scope;
52
+	}
53
+	
54
+	@Override
55
+	public Boolean visitBlock(BlockStatement block) {
56
+		boolean isValid = true;
57
+		
58
+		StatementValidator blockValidator = new StatementValidator(validator, scope);
59
+		for (Statement statement : block.statements)
60
+			isValid &= statement.accept(blockValidator);
61
+		
62
+		firstStatement = false;
63
+		return isValid;
64
+	}
65
+
66
+	@Override
67
+	public Boolean visitBreak(BreakStatement statement) {
68
+		firstStatement = false;
69
+		return true;
70
+	}
71
+
72
+	@Override
73
+	public Boolean visitContinue(ContinueStatement statement) {
74
+		firstStatement = false;
75
+		return true;
76
+	}
77
+
78
+	@Override
79
+	public Boolean visitDoWhile(DoWhileStatement statement) {
80
+		boolean isValid = true;
81
+		
82
+		if (statement.condition.type != BasicTypeID.BOOL) {
83
+			validator.logError(
84
+					ValidationLogEntry.Code.INVALID_CONDITION_TYPE,
85
+					statement.position,
86
+					"condition must be a boolean expression");
87
+			isValid = false;
88
+		}
89
+		
90
+		isValid &= statement.condition.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
91
+		isValid &= statement.content.accept(this);
92
+		
93
+		firstStatement = false;
94
+		return isValid;
95
+	}
96
+
97
+	@Override
98
+	public Boolean visitEmpty(EmptyStatement statement) {
99
+		firstStatement = false;
100
+		return true;
101
+	}
102
+
103
+	@Override
104
+	public Boolean visitExpression(ExpressionStatement statement) {
105
+		boolean isValid = statement.expression.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
106
+		firstStatement = false;
107
+		return isValid;
108
+	}
109
+
110
+	@Override
111
+	public Boolean visitForeach(ForeachStatement statement) {
112
+		boolean isValid = true;
113
+		isValid &= statement.list.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
114
+		isValid &= statement.content.accept(this);
115
+		
116
+		for (VarStatement var : statement.loopVariables) {
117
+			if (variables.contains(var.name)) {
118
+				validator.logError(ValidationLogEntry.Code.DUPLICATE_VARIABLE_NAME, var.position, "Duplicate variable name: " + var.name);
119
+				isValid = false;
120
+			}
121
+		}
122
+		
123
+		firstStatement = false;
124
+		return isValid;
125
+	}
126
+
127
+	@Override
128
+	public Boolean visitIf(IfStatement statement) {
129
+		boolean isValid = true;
130
+		isValid &= validateCondition(statement.condition);
131
+		isValid &= statement.onThen.accept(this);
132
+		if (statement.onElse != null)
133
+			isValid &= statement.onElse.accept(this);
134
+		
135
+		firstStatement = false;
136
+		return isValid;
137
+	}
138
+
139
+	@Override
140
+	public Boolean visitLock(LockStatement statement) {
141
+		boolean isValid = true;
142
+		// TODO: is the object a valid lock target?
143
+		isValid &= statement.object.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
144
+		isValid &= statement.content.accept(this);
145
+		
146
+		firstStatement = false;
147
+		return isValid;
148
+	}
149
+
150
+	@Override
151
+	public Boolean visitReturn(ReturnStatement statement) {
152
+		if (scope.getFunctionHeader() == null) {
153
+			validator.logError(ValidationLogEntry.Code.SCRIPT_CANNOT_RETURN, statement.position, "Cannot return from a script");
154
+			return false;
155
+		}
156
+		
157
+		boolean isValid = true;
158
+		if (statement.value != null) {
159
+			isValid &= statement.value.accept(new ExpressionValidator(
160
+					validator,
161
+					new StatementExpressionScope()));
162
+			
163
+			if (statement.value.type != scope.getFunctionHeader().returnType) {
164
+				validator.logError(ValidationLogEntry.Code.INVALID_RETURN_TYPE, statement.position, "Invalid return type: " + statement.value.type.toString());
165
+				isValid = false;
166
+			}
167
+		} else if (scope.getFunctionHeader().returnType != BasicTypeID.ANY
168
+				&& scope.getFunctionHeader().returnType != BasicTypeID.VOID) {
169
+			validator.logError(ValidationLogEntry.Code.INVALID_RETURN_TYPE, statement.position, "Missing return value");
170
+			isValid = false;
171
+		}
172
+		
173
+		firstStatement = false;
174
+		return isValid;
175
+	}
176
+
177
+	@Override
178
+	public Boolean visitThrow(ThrowStatement statement) {
179
+		boolean isValid = statement.value.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
180
+		// TODO: does the value type extend Exception?
181
+		
182
+		firstStatement = false;
183
+		return isValid;
184
+	}
185
+
186
+	@Override
187
+	public Boolean visitTryCatch(TryCatchStatement statement) {
188
+		boolean isValid = true;
189
+		if (statement.resource != null) {
190
+			if (variables.contains(statement.resource.name)) {
191
+				validator.logError(
192
+						ValidationLogEntry.Code.DUPLICATE_VARIABLE_NAME,
193
+						statement.position,
194
+						"Duplicate variable name: " + statement.resource.name);
195
+				isValid = false;
196
+			}
197
+			if (statement.resource.initializer == null) {
198
+				validator.logError(
199
+						ValidationLogEntry.Code.TRY_CATCH_RESOURCE_REQUIRES_INITIALIZER,
200
+						statement.position,
201
+						"try with resource requires initializer");
202
+				isValid = false;
203
+			}
204
+		}
205
+		
206
+		isValid &= statement.content.accept(this);
207
+		for (CatchClause catchClause : statement.catchClauses) {
208
+			isValid &= catchClause.content.accept(this);
209
+		}
210
+		
211
+		firstStatement = false;
212
+		return isValid;
213
+	}
214
+
215
+	@Override
216
+	public Boolean visitVar(VarStatement statement) {
217
+		boolean isValid = true;
218
+		if (variables.contains(statement.name)) {
219
+			validator.logError(
220
+						ValidationLogEntry.Code.DUPLICATE_VARIABLE_NAME,
221
+						statement.position,
222
+						"Duplicate variable name: " + statement.name);
223
+			isValid = false;
224
+		}
225
+		variables.add(statement.name);
226
+		if (statement.initializer != null) {
227
+			isValid &= statement.initializer.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
228
+		}
229
+		
230
+		firstStatement = false;
231
+		return isValid;
232
+	}
233
+
234
+	@Override
235
+	public Boolean visitWhile(WhileStatement statement) {
236
+		boolean isValid = true;
237
+		isValid &= validateCondition(statement.condition);
238
+		isValid &= statement.content.accept(this);
239
+		
240
+		firstStatement = false;
241
+		return isValid;
242
+	}
243
+	
244
+	private boolean validateCondition(Expression condition) {
245
+		boolean isValid = condition.accept(new ExpressionValidator(validator, new StatementExpressionScope()));
246
+		
247
+		if (condition.type != BasicTypeID.BOOL) {
248
+			validator.logError(
249
+					ValidationLogEntry.Code.INVALID_CONDITION_TYPE,
250
+					condition.position,
251
+					"condition must be a boolean expression");
252
+			isValid = false;
253
+		}
254
+		
255
+		return isValid;
256
+	}
257
+	
258
+	private class StatementExpressionScope implements ExpressionScope {
259
+		@Override
260
+		public boolean isConstructor() {
261
+			return scope.isConstructor();
262
+		}
263
+
264
+		@Override
265
+		public boolean isFirstStatement() {
266
+			return firstStatement;
267
+		}
268
+
269
+		@Override
270
+		public boolean hasThis() {
271
+			return !scope.isStatic();
272
+		}
273
+
274
+		@Override
275
+		public boolean isFieldInitialized(FieldMember field) {
276
+			return true; // TODO: improve field initialization analysis
277
+		}
278
+
279
+		@Override
280
+		public void markConstructorForwarded() {
281
+			constructorForwarded = true;
282
+		}
283
+
284
+		@Override
285
+		public boolean isEnumConstantInitialized(EnumConstantMember member) {
286
+			return true;
287
+		}
288
+
289
+		@Override
290
+		public boolean isLocalVariableInitialized(VarStatement variable) {
291
+			return true; // TODO
292
+		}
293
+
294
+		@Override
295
+		public boolean isStaticInitializer() {
296
+			return scope.isStaticInitializer();
297
+		}
298
+
299
+		@Override
300
+		public HighLevelDefinition getDefinition() {
301
+			return scope.getDefinition();
302
+		}
303
+	}
304
+}

+ 93
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/SuperclassValidator.java View File

@@ -0,0 +1,93 @@
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.validator.visitors;
7
+
8
+import org.openzen.zenscript.codemodel.Modifiers;
9
+import org.openzen.zenscript.codemodel.definition.AliasDefinition;
10
+import org.openzen.zenscript.codemodel.definition.ClassDefinition;
11
+import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
12
+import org.openzen.zenscript.codemodel.definition.EnumDefinition;
13
+import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
14
+import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
15
+import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
16
+import org.openzen.zenscript.codemodel.definition.StructDefinition;
17
+import org.openzen.zenscript.validator.ValidationLogEntry;
18
+import org.openzen.zenscript.validator.Validator;
19
+
20
+/**
21
+ *
22
+ * @author Hoofdgebruiker
23
+ */
24
+public class SuperclassValidator implements DefinitionVisitor<Boolean> {
25
+	private final Validator validator;
26
+	
27
+	public SuperclassValidator(Validator validator) {
28
+		this.validator = validator;
29
+	}
30
+
31
+	@Override
32
+	public Boolean visitClass(ClassDefinition definition) {
33
+		if (!Modifiers.isVirtual(definition.modifiers)) {
34
+			validator.logError(
35
+					ValidationLogEntry.Code.SUPERCLASS_NOT_VIRTUAL,
36
+					definition.position,
37
+					"Superclass is not virtual");
38
+			return false;
39
+		}
40
+		
41
+		return true;
42
+	}
43
+
44
+	@Override
45
+	public Boolean visitInterface(InterfaceDefinition definition) {
46
+		validator.logError(
47
+				ValidationLogEntry.Code.SUPERCLASS_NOT_A_CLASS,
48
+				definition.position,
49
+				"Superclass cannot be an interface");
50
+		
51
+		return false;
52
+	}
53
+
54
+	@Override
55
+	public Boolean visitEnum(EnumDefinition definition) {
56
+		validator.logError(
57
+				ValidationLogEntry.Code.SUPERCLASS_NOT_A_CLASS,
58
+				definition.position,
59
+				"Superclass cannot be an enum");
60
+		
61
+		return false;
62
+	}
63
+
64
+	@Override
65
+	public Boolean visitStruct(StructDefinition definition) {
66
+		validator.logError(
67
+				ValidationLogEntry.Code.SUPERCLASS_NOT_A_CLASS,
68
+				definition.position,
69
+				"Superclass cannot be a struct");
70
+		
71
+		return false;
72
+	}
73
+
74
+	@Override
75
+	public Boolean visitFunction(FunctionDefinition definition) {
76
+		validator.logError(
77
+				ValidationLogEntry.Code.SUPERCLASS_NOT_A_CLASS,
78
+				definition.position,
79
+				"Superclass cannot be a function");
80
+		
81
+		return false;
82
+	}
83
+
84
+	@Override
85
+	public Boolean visitExpansion(ExpansionDefinition definition) {
86
+		throw new AssertionError();
87
+	}
88
+
89
+	@Override
90
+	public Boolean visitAlias(AliasDefinition definition) {
91
+		throw new AssertionError();
92
+	}
93
+}

+ 90
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/SupertypeValidator.java View File

@@ -0,0 +1,90 @@
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.validator.visitors;
7
+
8
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
9
+import org.openzen.zenscript.codemodel.type.AssocTypeID;
10
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
11
+import org.openzen.zenscript.codemodel.type.ConstTypeID;
12
+import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
13
+import org.openzen.zenscript.codemodel.type.FunctionTypeID;
14
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
15
+import org.openzen.zenscript.codemodel.type.ITypeVisitor;
16
+import org.openzen.zenscript.codemodel.type.IteratorTypeID;
17
+import org.openzen.zenscript.codemodel.type.OptionalTypeID;
18
+import org.openzen.zenscript.codemodel.type.RangeTypeID;
19
+import org.openzen.zenscript.shared.CodePosition;
20
+import org.openzen.zenscript.validator.ValidationLogEntry;
21
+import org.openzen.zenscript.validator.Validator;
22
+
23
+/**
24
+ *
25
+ * @author Hoofdgebruiker
26
+ */
27
+public class SupertypeValidator implements ITypeVisitor<Boolean> {
28
+	private final Validator validator;
29
+	private final CodePosition position;
30
+	
31
+	public SupertypeValidator(
32
+			Validator validator,
33
+			CodePosition position)
34
+	{
35
+		this.validator = validator;
36
+		this.position = position;
37
+	}
38
+
39
+	@Override
40
+	public Boolean visitBasic(BasicTypeID basic) {
41
+		validator.logError(ValidationLogEntry.Code.SUPERCLASS_NOT_A_CLASS, position, "Superclass cannot be a basic type");
42
+		return false;
43
+	}
44
+
45
+	@Override
46
+	public Boolean visitArray(ArrayTypeID array) {
47
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
48
+	}
49
+
50
+	@Override
51
+	public Boolean visitAssoc(AssocTypeID assoc) {
52
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
53
+	}
54
+
55
+	@Override
56
+	public Boolean visitIterator(IteratorTypeID iterator) {
57
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
58
+	}
59
+
60
+	@Override
61
+	public Boolean visitFunction(FunctionTypeID function) {
62
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
63
+	}
64
+
65
+	@Override
66
+	public Boolean visitDefinition(DefinitionTypeID definition) {
67
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
68
+	}
69
+
70
+	@Override
71
+	public Boolean visitGeneric(GenericTypeID generic) {
72
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
73
+	}
74
+
75
+	@Override
76
+	public Boolean visitRange(RangeTypeID range) {
77
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
78
+	}
79
+
80
+	@Override
81
+	public Boolean visitConst(ConstTypeID type) {
82
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
83
+	}
84
+
85
+	@Override
86
+	public Boolean visitOptional(OptionalTypeID optional) {
87
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
88
+	}
89
+	
90
+}

+ 114
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/TypeValidator.java View File

@@ -0,0 +1,114 @@
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.validator.visitors;
7
+
8
+import org.openzen.zenscript.codemodel.generic.GenericParameterBound;
9
+import org.openzen.zenscript.codemodel.generic.GenericParameterBoundVisitor;
10
+import org.openzen.zenscript.codemodel.generic.ParameterSuperBound;
11
+import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
12
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
14
+import org.openzen.zenscript.codemodel.type.AssocTypeID;
15
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
16
+import org.openzen.zenscript.codemodel.type.ConstTypeID;
17
+import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
18
+import org.openzen.zenscript.codemodel.type.FunctionTypeID;
19
+import org.openzen.zenscript.codemodel.type.GenericTypeID;
20
+import org.openzen.zenscript.codemodel.type.ITypeID;
21
+import org.openzen.zenscript.codemodel.type.ITypeVisitor;
22
+import org.openzen.zenscript.codemodel.type.IteratorTypeID;
23
+import org.openzen.zenscript.codemodel.type.OptionalTypeID;
24
+import org.openzen.zenscript.codemodel.type.RangeTypeID;
25
+import org.openzen.zenscript.shared.CodePosition;
26
+import org.openzen.zenscript.validator.ValidationLogEntry;
27
+import org.openzen.zenscript.validator.Validator;
28
+
29
+/**
30
+ *
31
+ * @author Hoofdgebruiker
32
+ */
33
+public class TypeValidator implements ITypeVisitor<Boolean> {
34
+	private final Validator validator;
35
+	private final CodePosition position;
36
+	
37
+	public TypeValidator(Validator validator, CodePosition position) {
38
+		this.validator = validator;
39
+		this.position = position;
40
+	}
41
+
42
+	@Override
43
+	public Boolean visitBasic(BasicTypeID basic) {
44
+		if (basic == BasicTypeID.UNDETERMINED) {
45
+			validator.logError(ValidationLogEntry.Code.INVALID_TYPE, position, "type could not be determined");
46
+			return false;
47
+		}
48
+		
49
+		return true;
50
+	}
51
+
52
+	@Override
53
+	public Boolean visitArray(ArrayTypeID array) {
54
+		boolean isValid = true;
55
+		if (array.dimension < 1) {
56
+			validator.logError(ValidationLogEntry.Code.INVALID_TYPE, position, "array dimension must be at least 1");
57
+			isValid = false;
58
+		} else if (array.dimension > 16) {
59
+			validator.logError(ValidationLogEntry.Code.INVALID_TYPE, position, "array dimension must be at most 16");
60
+			isValid = false;
61
+		}
62
+		
63
+		return isValid & array.elementType.accept(this);
64
+	}
65
+
66
+	@Override
67
+	public Boolean visitAssoc(AssocTypeID assoc) {
68
+		boolean isValid = true;
69
+		isValid &= assoc.keyType.accept(this);
70
+		isValid &= assoc.valueType.accept(this);
71
+		
72
+		// TODO: does the keytype have == and hashcode operators?
73
+		return isValid;
74
+	}
75
+
76
+	@Override
77
+	public Boolean visitIterator(IteratorTypeID iterator) {
78
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
79
+	}
80
+
81
+	@Override
82
+	public Boolean visitFunction(FunctionTypeID function) {
83
+		return ValidationUtils.validateHeader(validator, position, function.header);
84
+	}
85
+
86
+	@Override
87
+	public Boolean visitDefinition(DefinitionTypeID definition) {
88
+		boolean isValid = true;
89
+		isValid &= ValidationUtils.validateTypeArguments(validator, position, definition.definition.genericParameters, definition.typeParameters);
90
+		return isValid;
91
+	}
92
+
93
+	@Override
94
+	public Boolean visitGeneric(GenericTypeID generic) {
95
+		return true;
96
+	}
97
+
98
+	@Override
99
+	public Boolean visitRange(RangeTypeID range) {
100
+		return range.from.accept(this) & range.to.accept(this);
101
+	}
102
+
103
+	@Override
104
+	public Boolean visitConst(ConstTypeID type) {
105
+		// TODO: detect duplicate const
106
+		return type.baseType.accept(this);
107
+	}
108
+
109
+	@Override
110
+	public Boolean visitOptional(OptionalTypeID optional) {
111
+		// TODO: detect duplicate optional
112
+		return optional.baseType.accept(this);
113
+	}
114
+}

+ 246
- 0
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ValidationUtils.java View File

@@ -0,0 +1,246 @@
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.validator.visitors;
7
+
8
+import java.util.HashSet;
9
+import java.util.Set;
10
+import java.util.regex.Pattern;
11
+import org.openzen.zenscript.codemodel.FunctionHeader;
12
+import org.openzen.zenscript.codemodel.FunctionParameter;
13
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
14
+import org.openzen.zenscript.codemodel.Modifiers;
15
+import org.openzen.zenscript.codemodel.generic.GenericParameterBound;
16
+import org.openzen.zenscript.codemodel.generic.GenericParameterBoundVisitor;
17
+import org.openzen.zenscript.codemodel.generic.ParameterSuperBound;
18
+import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
19
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
20
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
21
+import org.openzen.zenscript.codemodel.member.FieldMember;
22
+import org.openzen.zenscript.codemodel.statement.VarStatement;
23
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
24
+import org.openzen.zenscript.codemodel.type.ITypeID;
25
+import org.openzen.zenscript.shared.CodePosition;
26
+import org.openzen.zenscript.validator.ValidationLogEntry;
27
+import static org.openzen.zenscript.validator.ValidationLogEntry.Code.*;
28
+import org.openzen.zenscript.validator.Validator;
29
+import org.openzen.zenscript.validator.analysis.ExpressionScope;
30
+
31
+/**
32
+ *
33
+ * @author Hoofdgebruiker
34
+ */
35
+public class ValidationUtils {
36
+	private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z_0-9]*$");
37
+	
38
+	private ValidationUtils() {}
39
+	
40
+	public static boolean validateIdentifier(Validator target, CodePosition position, String identifier) { 
41
+		if (!IDENTIFIER_PATTERN.matcher(identifier).matches()) {
42
+			target.logError(INVALID_IDENTIFIER, position, "Invalid identifier: " + identifier);
43
+			return false;
44
+		}
45
+		
46
+		return true;
47
+	}
48
+	
49
+	public static boolean validateHeader(Validator target, CodePosition position, FunctionHeader header) {
50
+		boolean isValid = true;
51
+		
52
+		TypeValidator typeValidator = new TypeValidator(target, position);
53
+		isValid &= header.returnType.accept(typeValidator);
54
+		
55
+		Set<String> parameterNames = new HashSet<>();
56
+		int i = 0;
57
+		for (FunctionParameter parameter : header.parameters) {
58
+			if (parameterNames.contains(parameter.name)) {
59
+				target.logError(DUPLICATE_PARAMETER_NAME, position, "Duplicate parameter name: " + parameter.name);
60
+				isValid = false;
61
+			}
62
+			
63
+			parameterNames.add(parameter.name);
64
+			parameter.type.accept(typeValidator);
65
+			
66
+			if (parameter.defaultValue != null) {
67
+				isValid &= parameter.defaultValue.accept(new ExpressionValidator(target, new DefaultParameterValueExpressionScope()));
68
+				if (parameter.defaultValue.type != parameter.type) {
69
+					target.logError(INVALID_TYPE, position, "default value does not match parameter type");
70
+					isValid = false;
71
+				}
72
+			}
73
+			
74
+			if (parameter.variadic) {
75
+				if (i != header.parameters.length - 1) {
76
+					target.logError(VARIADIC_PARAMETER_MUST_BE_LAST, position, "variadic parameter must be the last parameter");
77
+					isValid = false;
78
+				}
79
+				if (!(parameter.type instanceof ArrayTypeID)) {
80
+					target.logError(INVALID_TYPE, position, "variadic parameter must be an array");
81
+					isValid = false;
82
+				}
83
+			}
84
+			i++;
85
+		}
86
+		
87
+		return isValid;
88
+	}
89
+	
90
+	public static boolean validateModifiers(
91
+			Validator target,
92
+			int modifiers,
93
+			int allowedModifiers,
94
+			CodePosition position,
95
+			String error)
96
+	{
97
+		if (Modifiers.isPublic(modifiers) && Modifiers.isExport(modifiers))
98
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine public and export");
99
+		if (Modifiers.isPublic(modifiers) && Modifiers.isPrivate(modifiers))
100
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine public and private");
101
+		if (Modifiers.isPublic(modifiers) && Modifiers.isProtected(modifiers))
102
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine public and protected");
103
+		if (Modifiers.isExport(modifiers) && Modifiers.isPrivate(modifiers))
104
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine export and private");
105
+		if (Modifiers.isExport(modifiers) && Modifiers.isProtected(modifiers))
106
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine export and protected");
107
+		if (Modifiers.isPrivate(modifiers) && Modifiers.isProtected(modifiers))
108
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine private and protected");
109
+		
110
+		if (Modifiers.isConst(modifiers) && Modifiers.isConstOptional(modifiers))
111
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine const and const?");
112
+		if (Modifiers.isFinal(modifiers) && Modifiers.isAbstract(modifiers))
113
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine abstract and final");
114
+		if (Modifiers.isFinal(modifiers) && Modifiers.isVirtual(modifiers))
115
+			target.logError(INVALID_MODIFIER, position, error + ": cannot combine final and virtual");
116
+		
117
+		int invalid = modifiers & ~allowedModifiers;
118
+		if (invalid == 0)
119
+			return true;
120
+		
121
+		if (Modifiers.isPublic(invalid))
122
+			target.logError(INVALID_MODIFIER, position, error + ": public");
123
+		if (Modifiers.isExport(invalid))
124
+			target.logError(INVALID_MODIFIER, position, error + ": export");
125
+		if (Modifiers.isProtected(invalid))
126
+			target.logError(INVALID_MODIFIER, position, error + ": protected");
127
+		if (Modifiers.isPrivate(invalid))
128
+			target.logError(INVALID_MODIFIER, position, error + ": private");
129
+		if (Modifiers.isFinal(invalid))
130
+			target.logError(INVALID_MODIFIER, position, error + ": final");
131
+		if (Modifiers.isConst(invalid))
132
+			target.logError(INVALID_MODIFIER, position, error + ": const");
133
+		if (Modifiers.isConstOptional(invalid))
134
+			target.logError(INVALID_MODIFIER, position, error + ": const?");
135
+		if (Modifiers.isStatic(invalid))
136
+			target.logError(INVALID_MODIFIER, position, error + ": static");
137
+		if (Modifiers.isImplicit(invalid))
138
+			target.logError(INVALID_MODIFIER, position, error + ": implicit");
139
+		if (Modifiers.isVirtual(invalid))
140
+			target.logError(INVALID_MODIFIER, position, error + ": virtual");
141
+		
142
+		return false;
143
+	}
144
+	
145
+	public static boolean validateTypeArguments(
146
+			Validator target,
147
+			CodePosition position,
148
+			TypeParameter[] typeParameters,
149
+			ITypeID[] typeArguments)
150
+	{
151
+		if (typeParameters.length != typeArguments.length) {
152
+			target.logError(
153
+					ValidationLogEntry.Code.INVALID_TYPE_ARGUMENT,
154
+					position,
155
+					"Invalid number of type arguments: "
156
+							+ typeArguments.length
157
+							+ " arguments given but "
158
+							+ typeParameters.length
159
+							+ " expected");
160
+			return false;
161
+		}
162
+		
163
+		boolean isValid = true;
164
+		for (int i = 0; i < typeParameters.length; i++) {
165
+			TypeParameter typeParameter = typeParameters[i];
166
+			for (GenericParameterBound bound : typeParameter.bounds) {
167
+				if (!bound.matches(typeArguments[i])) {
168
+					target.logError(
169
+							ValidationLogEntry.Code.INVALID_TYPE_ARGUMENT,
170
+							position,
171
+							bound.accept(new TypeParameterBoundErrorVisitor(typeArguments[i], target)));
172
+					isValid = false;
173
+				}
174
+			}
175
+		}
176
+		return isValid;
177
+	}
178
+	
179
+	private static class TypeParameterBoundErrorVisitor implements GenericParameterBoundVisitor<String> {
180
+		private final ITypeID type;
181
+		private final Validator target;
182
+		
183
+		public TypeParameterBoundErrorVisitor(ITypeID type, Validator target) {
184
+			this.type = type;
185
+			this.target = target;
186
+		}
187
+
188
+		@Override
189
+		public String visitSuper(ParameterSuperBound bound) {
190
+			return type.toString() + " is not a superclass of " + bound.type.toString();
191
+		}
192
+
193
+		@Override
194
+		public String visitType(ParameterTypeBound bound) {
195
+			return type.toString() + " is does not extend or implement " + bound.type.toString();
196
+		}
197
+	}
198
+	
199
+	private static class DefaultParameterValueExpressionScope implements ExpressionScope {
200
+		
201
+		@Override
202
+		public boolean isConstructor() {
203
+			return false;
204
+		}
205
+
206
+		@Override
207
+		public boolean isFirstStatement() {
208
+			return true;
209
+		}
210
+
211
+		@Override
212
+		public boolean hasThis() {
213
+			return false;
214
+		}
215
+
216
+		@Override
217
+		public boolean isFieldInitialized(FieldMember field) {
218
+			return false;
219
+		}
220
+
221
+		@Override
222
+		public void markConstructorForwarded() {
223
+			
224
+		}
225
+
226
+		@Override
227
+		public boolean isEnumConstantInitialized(EnumConstantMember member) {
228
+			return true;
229
+		}
230
+
231
+		@Override
232
+		public boolean isLocalVariableInitialized(VarStatement variable) {
233
+			return false;
234
+		}
235
+
236
+		@Override
237
+		public boolean isStaticInitializer() {
238
+			return false;
239
+		}
240
+
241
+		@Override
242
+		public HighLevelDefinition getDefinition() {
243
+			return null;
244
+		}
245
+	}
246
+}

Loading…
Cancel
Save