Browse Source

Fixed a large number of java source compilation bugs. (ZenCode.shared module now compiles, and so does StdLib.stdlib)

Stan Hebben 6 years ago
parent
commit
8594fc56e0
51 changed files with 1264 additions and 822 deletions
  1. 20
    1
      CodeFormatterShared/src/main/java/org/openzen/zenscript/formattershared/StatementFormatter.java
  2. 2
    0
      CodeFormatterShared/src/main/java/org/openzen/zenscript/formattershared/StatementFormattingTarget.java
  3. 56
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  4. 5
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/annotations/PreconditionForMethod.java
  5. 4
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/iterator/ForeachIteratorVisitor.java
  6. 3
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/CustomIteratorMember.java
  7. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/StaticInitializerMember.java
  8. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/builtin/AssocIterator.java
  9. 1
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ref/FunctionalMemberRef.java
  10. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ArrayTypeID.java
  11. 7
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/AssocTypeID.java
  12. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/BasicTypeID.java
  13. 11
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ConstTypeID.java
  14. 7
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java
  15. 8
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/FunctionTypeID.java
  16. 7
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericMapTypeID.java
  17. 7
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java
  18. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java
  19. 7
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/IteratorTypeID.java
  20. 6
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/OptionalTypeID.java
  21. 7
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/RangeTypeID.java
  22. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinID.java
  23. 5
    29
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java
  24. 3
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  25. 10
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachVisitor.java
  26. 166
    0
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/BaseMemberCompiler.java
  27. 92
    22
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaDefinitionVisitor.java
  28. 50
    247
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaExpansionMemberCompiler.java
  29. 59
    171
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaMemberCompiler.java
  30. 24
    12
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceCompiler.java
  31. 108
    50
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceExpressionFormatter.java
  32. 38
    30
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceFile.java
  33. 21
    39
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceImporter.java
  34. 44
    36
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceStatementFormatter.java
  35. 3
    3
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceSyntheticHelperGenerator.java
  36. 20
    9
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceSyntheticTypeGenerator.java
  37. 33
    7
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceTypeVisitor.java
  38. 50
    8
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceUtils.java
  39. 23
    0
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSynthesizedClass.java
  40. 40
    0
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaNativeClass.java
  41. 28
    73
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareClassMethodVisitor.java
  42. 191
    50
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareDefinitionVisitor.java
  43. 24
    6
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareExpansionMethodVisitor.java
  44. 8
    3
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/scope/JavaSourceFileScope.java
  45. 4
    4
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/scope/JavaSourceStatementScope.java
  46. 11
    3
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/tags/JavaSourceClass.java
  47. 5
    1
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/tags/JavaSourceMethod.java
  48. 2
    2
      Shared/src/main/java/org/openzen/zenscript/shared/ConcatMap.java
  49. 4
    1
      Validator/src/main/java/org/openzen/zenscript/validator/ValidationLogEntry.java
  50. 20
    1
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/DefinitionMemberValidator.java
  51. 1
    1
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java

+ 20
- 1
CodeFormatterShared/src/main/java/org/openzen/zenscript/formattershared/StatementFormatter.java View File

205
 		if (!lineAfter.isEmpty())
205
 		if (!lineAfter.isEmpty())
206
 			output.append('\n').append(indent).append(lineAfter);
206
 			output.append('\n').append(indent).append(lineAfter);
207
 	}
207
 	}
208
+	
209
+	@Override
210
+	public void writeInner(String lineBefore, String[] inlineContents, Statement contents, LoopStatement loop, String lineAfter) {
211
+		output.append('\n').append(indent).append(lineBefore);
212
+		StatementFormatter innerFormatter = new StatementFormatter(output, settings, formatter.forLoop(loop), indent + settings.indent, loop == null ? innerLoop : loop);
213
+		for (String inline : inlineContents)
214
+			output.append('\n').append(indent).append(settings.indent).append(inline);
215
+		if (contents instanceof BlockStatement) {
216
+			for (Statement statement : ((BlockStatement) contents).statements)
217
+				statement.accept(innerFormatter);
218
+		} else {
219
+			contents.accept(innerFormatter);
220
+		}
221
+		
222
+		if (!lineAfter.isEmpty())
223
+			output.append('\n').append(indent).append(lineAfter);
224
+	}
208
 
225
 
209
 	@Override
226
 	@Override
210
 	public void writeInnerMulti(String lineBefore, List<StatementFormattingSubBlock> contents, LoopStatement loop, String lineAfter) {
227
 	public void writeInnerMulti(String lineBefore, List<StatementFormattingSubBlock> contents, LoopStatement loop, String lineAfter) {
211
 		output.append('\n').append(indent).append(lineBefore);
228
 		output.append('\n').append(indent).append(lineBefore);
212
 		
229
 		
213
 		String newIndent = indent + settings.indent + settings.indent;
230
 		String newIndent = indent + settings.indent + settings.indent;
214
-		StatementFormatter inner = new StatementFormatter(output, settings, formatter, newIndent, innerLoop);
231
+		StatementFormatter inner = new StatementFormatter(output, settings, formatter.forLoop(loop), newIndent, innerLoop);
215
 		
232
 		
216
 		for (StatementFormattingSubBlock subBlock : contents) {
233
 		for (StatementFormattingSubBlock subBlock : contents) {
217
 			output.append('\n').append(indent).append(settings.indent).append(subBlock.header);
234
 			output.append('\n').append(indent).append(settings.indent).append(subBlock.header);
278
 	}
295
 	}
279
 	
296
 	
280
 	public interface Formatter {
297
 	public interface Formatter {
298
+		public Formatter forLoop(LoopStatement statement);
299
+		
281
 		public void formatBlock(StatementFormattingTarget target, BlockStatement statement);
300
 		public void formatBlock(StatementFormattingTarget target, BlockStatement statement);
282
 	
301
 	
283
 		public void formatBreak(StatementFormattingTarget target, BreakStatement statement);
302
 		public void formatBreak(StatementFormattingTarget target, BreakStatement statement);

+ 2
- 0
CodeFormatterShared/src/main/java/org/openzen/zenscript/formattershared/StatementFormattingTarget.java View File

23
 	
23
 	
24
 	void writeInner(String lineBefore, Statement contents, LoopStatement loop, String lineAfter);
24
 	void writeInner(String lineBefore, Statement contents, LoopStatement loop, String lineAfter);
25
 	
25
 	
26
+	void writeInner(String lineBefore, String[] inlineContents, Statement contents, LoopStatement loop, String lineAfter);
27
+	
26
 	void writeInnerMulti(String lineBefore, List<StatementFormattingSubBlock> contents, LoopStatement loop, String lineAfter);
28
 	void writeInnerMulti(String lineBefore, List<StatementFormattingSubBlock> contents, LoopStatement loop, String lineAfter);
27
 	
29
 	
28
 	void writeBlock(String lineBefore, BlockStatement contents, String lineAfter);
30
 	void writeBlock(String lineBefore, BlockStatement contents, String lineAfter);

+ 56
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

29
 	public final FunctionParameter[] parameters;
29
 	public final FunctionParameter[] parameters;
30
 	public final ITypeID thrownType;
30
 	public final ITypeID thrownType;
31
 	
31
 	
32
+	public final int minParameters;
33
+	public final int maxParameters;
34
+	
32
 	public FunctionHeader(ITypeID returnType) {
35
 	public FunctionHeader(ITypeID returnType) {
33
 		if (returnType == null)
36
 		if (returnType == null)
34
 			throw new NullPointerException();
37
 			throw new NullPointerException();
37
 		this.returnType = returnType;
40
 		this.returnType = returnType;
38
 		this.parameters = NO_PARAMETERS;
41
 		this.parameters = NO_PARAMETERS;
39
 		this.thrownType = null;
42
 		this.thrownType = null;
43
+		
44
+		minParameters = 0;
45
+		maxParameters = 0;
40
 	}
46
 	}
41
 	
47
 	
42
 	public FunctionHeader(ITypeID returnType, ITypeID... parameterTypes) {
48
 	public FunctionHeader(ITypeID returnType, ITypeID... parameterTypes) {
50
 		
56
 		
51
 		for (int i = 0; i < parameterTypes.length; i++)
57
 		for (int i = 0; i < parameterTypes.length; i++)
52
 			parameters[i] = new FunctionParameter(parameterTypes[i], null);
58
 			parameters[i] = new FunctionParameter(parameterTypes[i], null);
59
+		
60
+		minParameters = parameterTypes.length;
61
+		maxParameters = parameterTypes.length;
53
 	}
62
 	}
54
 	
63
 	
55
 	public FunctionHeader(ITypeID returnType, FunctionParameter... parameters) {
64
 	public FunctionHeader(ITypeID returnType, FunctionParameter... parameters) {
60
 		this.returnType = returnType;
69
 		this.returnType = returnType;
61
 		this.parameters = parameters;
70
 		this.parameters = parameters;
62
 		this.thrownType = null;
71
 		this.thrownType = null;
72
+		
73
+		minParameters = getMinParameters(parameters);
74
+		maxParameters = getMaxParameters(parameters);
63
 	}
75
 	}
64
 	
76
 	
65
 	public FunctionHeader(TypeParameter[] genericParameters, ITypeID returnType, ITypeID thrownType, FunctionParameter... parameters) {
77
 	public FunctionHeader(TypeParameter[] genericParameters, ITypeID returnType, ITypeID thrownType, FunctionParameter... parameters) {
70
 		this.returnType = returnType;
82
 		this.returnType = returnType;
71
 		this.parameters = parameters;
83
 		this.parameters = parameters;
72
 		this.thrownType = thrownType;
84
 		this.thrownType = thrownType;
85
+		
86
+		minParameters = getMinParameters(parameters);
87
+		maxParameters = getMaxParameters(parameters);
73
 	}
88
 	}
74
 	
89
 	
75
 	public int getNumberOfTypeParameters() {
90
 	public int getNumberOfTypeParameters() {
76
 		return typeParameters == null ? 0 : typeParameters.length;
91
 		return typeParameters == null ? 0 : typeParameters.length;
77
 	}
92
 	}
78
 	
93
 	
94
+	public boolean matchesExactly(CallArguments arguments, TypeScope scope) {
95
+		if (arguments.arguments.length < minParameters || arguments.arguments.length > maxParameters)
96
+			return false;
97
+		
98
+		FunctionHeader header = fillGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
99
+		for (int i = 0; i < header.parameters.length; i++) {
100
+			if (arguments.arguments[i].type != header.parameters[i].type)
101
+				return false;
102
+		}
103
+		
104
+		return true;
105
+	}
106
+	
107
+	public boolean matchesImplicitly(CallArguments arguments, TypeScope scope) {
108
+		if (arguments.arguments.length < minParameters || arguments.arguments.length > maxParameters)
109
+			return false;
110
+		
111
+		FunctionHeader header = fillGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
112
+		for (int i = 0; i < header.parameters.length; i++) {
113
+			if (!scope.getTypeMembers(arguments.arguments[i].type).canCastImplicit(header.parameters[i].type))
114
+				return false;
115
+		}
116
+		
117
+		return true;
118
+	}
119
+	
79
 	public String getCanonical() {
120
 	public String getCanonical() {
80
 		StringBuilder result = new StringBuilder();
121
 		StringBuilder result = new StringBuilder();
81
 		if (getNumberOfTypeParameters() > 0) {
122
 		if (getNumberOfTypeParameters() > 0) {
304
 		result.append(")");
345
 		result.append(")");
305
 		return result.toString();
346
 		return result.toString();
306
 	}
347
 	}
348
+
349
+	private static int getMinParameters(FunctionParameter[] parameters) {
350
+		for (int i = 0; i < parameters.length; i++)
351
+			if (parameters[i].defaultValue != null || parameters[i].variadic)
352
+				return i;
353
+		
354
+		return parameters.length;
355
+	}
356
+	
357
+	private static int getMaxParameters(FunctionParameter[] parameters) {
358
+		if (parameters.length == 0)
359
+			return 0;
360
+		
361
+		return parameters[parameters.length - 1].variadic ? Integer.MAX_VALUE : parameters.length;
362
+	}
307
 }
363
 }

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

7
 
7
 
8
 import java.util.ArrayList;
8
 import java.util.ArrayList;
9
 import java.util.List;
9
 import java.util.List;
10
+import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
10
 import org.openzen.zenscript.codemodel.expression.Expression;
11
 import org.openzen.zenscript.codemodel.expression.Expression;
11
 import org.openzen.zenscript.codemodel.expression.ExpressionBuilder;
12
 import org.openzen.zenscript.codemodel.expression.ExpressionBuilder;
13
+import org.openzen.zenscript.codemodel.expression.PanicExpression;
12
 import org.openzen.zenscript.codemodel.member.FunctionalMember;
14
 import org.openzen.zenscript.codemodel.member.FunctionalMember;
13
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
15
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
14
 import org.openzen.zenscript.codemodel.scope.BaseScope;
16
 import org.openzen.zenscript.codemodel.scope.BaseScope;
15
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
17
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
16
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
18
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
19
+import org.openzen.zenscript.codemodel.statement.ExpressionStatement;
17
 import org.openzen.zenscript.codemodel.statement.IfStatement;
20
 import org.openzen.zenscript.codemodel.statement.IfStatement;
18
 import org.openzen.zenscript.codemodel.statement.Statement;
21
 import org.openzen.zenscript.codemodel.statement.Statement;
19
-import org.openzen.zenscript.codemodel.statement.ThrowStatement;
20
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
22
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
21
 import org.openzen.zenscript.shared.CodePosition;
23
 import org.openzen.zenscript.shared.CodePosition;
22
 
24
 
55
 		List<Statement> statements = new ArrayList<>();
57
 		List<Statement> statements = new ArrayList<>();
56
 		ExpressionBuilder expressionBuilder = new ExpressionBuilder(position, expressionScope);
58
 		ExpressionBuilder expressionBuilder = new ExpressionBuilder(position, expressionScope);
57
 		Expression inverseCondition = expressionBuilder.not(condition);
59
 		Expression inverseCondition = expressionBuilder.not(condition);
58
-		Statement throwStatement = new ThrowStatement(CodePosition.BUILTIN, expressionBuilder.constructNew("stdlib.IllegalArgumentException", message));
59
-		statements.add(new IfStatement(CodePosition.BUILTIN, inverseCondition, throwStatement, null));
60
+		Statement throwStatement = new ExpressionStatement(position, new PanicExpression(position, BasicTypeID.VOID, message));
61
+		statements.add(new IfStatement(position, inverseCondition, throwStatement, null));
60
 		if (member.body instanceof BlockStatement) {
62
 		if (member.body instanceof BlockStatement) {
61
 			statements.addAll(((BlockStatement)member.body).statements);
63
 			statements.addAll(((BlockStatement)member.body).statements);
62
 		} else {
64
 		} else {

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

16
 	
16
 	
17
 	T visitArrayKeyValueIterator();
17
 	T visitArrayKeyValueIterator();
18
 	
18
 	
19
+	T visitAssocKeyIterator();
20
+	
21
+	T visitAssocKeyValueIterator();
22
+	
19
 	T visitStringCharacterIterator();
23
 	T visitStringCharacterIterator();
20
 	
24
 	
21
 	T visitCustomIterator();
25
 	T visitCustomIterator();

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

22
  */
22
  */
23
 public class CustomIteratorMember extends DefinitionMember implements IIteratorMember {
23
 public class CustomIteratorMember extends DefinitionMember implements IIteratorMember {
24
 	private final ITypeID[] iteratorTypes;
24
 	private final ITypeID[] iteratorTypes;
25
-	private Statement content;
25
+	public Statement body;
26
 	
26
 	
27
 	public CustomIteratorMember(CodePosition position, HighLevelDefinition definition, int modifiers, ITypeID[] iteratorTypes) {
27
 	public CustomIteratorMember(CodePosition position, HighLevelDefinition definition, int modifiers, ITypeID[] iteratorTypes) {
28
 		super(position, definition, modifiers);
28
 		super(position, definition, modifiers);
30
 		this.iteratorTypes = iteratorTypes;
30
 		this.iteratorTypes = iteratorTypes;
31
 	}
31
 	}
32
 	
32
 	
33
-	public void setContent(Statement content) {
34
-		this.content = content;
33
+	public void setContent(Statement body) {
34
+		this.body = body;
35
 	}
35
 	}
36
 
36
 
37
 	@Override
37
 	@Override

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

19
  * @author Hoofdgebruiker
19
  * @author Hoofdgebruiker
20
  */
20
  */
21
 public class StaticInitializerMember extends Taggable implements IDefinitionMember {
21
 public class StaticInitializerMember extends Taggable implements IDefinitionMember {
22
-	private final CodePosition position;
22
+	public final CodePosition position;
23
 	public Statement body;
23
 	public Statement body;
24
 	public MemberAnnotation[] annotations = MemberAnnotation.NONE;
24
 	public MemberAnnotation[] annotations = MemberAnnotation.NONE;
25
 	
25
 	

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

71
 
71
 
72
 	@Override
72
 	@Override
73
 	public <T> T acceptForIterator(ForeachIteratorVisitor<T> visitor) {
73
 	public <T> T acceptForIterator(ForeachIteratorVisitor<T> visitor) {
74
-		return visitor.visitArrayKeyValueIterator();
74
+		return visitor.visitAssocKeyValueIterator();
75
 	}
75
 	}
76
 }
76
 }

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

69
 		return target.getKind() == FunctionalKind.OPERATOR;
69
 		return target.getKind() == FunctionalKind.OPERATOR;
70
 	}
70
 	}
71
 	
71
 	
72
+	// TODO: shouldn't this be a call operator?
72
 	public boolean isCaller() {
73
 	public boolean isCaller() {
73
 		return target.getKind() == FunctionalKind.CALLER;
74
 		return target.getKind() == FunctionalKind.CALLER;
74
 	}
75
 	}

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 
11
 
64
 		return false;
65
 		return false;
65
 	}
66
 	}
66
 
67
 
68
+	@Override
69
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
70
+		elementType.extractTypeParameters(typeParameters);
71
+	}
72
+
67
 	@Override
73
 	@Override
68
 	public int hashCode() {
74
 	public int hashCode() {
69
 		int hash = 7;
75
 		int hash = 7;

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 
11
 
63
 		return true;
64
 		return true;
64
 	}
65
 	}
65
 
66
 
67
+	@Override
68
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
69
+		keyType.extractTypeParameters(typeParameters);
70
+		valueType.extractTypeParameters(typeParameters);
71
+	}
72
+
66
 	@Override
73
 	@Override
67
 	public int hashCode() {
74
 	public int hashCode() {
68
 		int hash = 7;
75
 		int hash = 7;

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

86
 	public boolean hasDefaultValue() {
86
 	public boolean hasDefaultValue() {
87
 		return true;
87
 		return true;
88
 	}
88
 	}
89
+
90
+	@Override
91
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
92
+		
93
+	}
89
 }
94
 }

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import java.util.Objects;
9
 import java.util.Objects;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
67
 		return baseType.isObjectType();
68
 		return baseType.isObjectType();
68
 	}
69
 	}
69
 
70
 
71
+	@Override
72
+	public boolean hasDefaultValue() {
73
+		return baseType.hasDefaultValue();
74
+	}
75
+
76
+	@Override
77
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
78
+		baseType.extractTypeParameters(typeParameters);
79
+	}
80
+
70
 	@Override
81
 	@Override
71
 	public int hashCode() {
82
 	public int hashCode() {
72
 		int hash = 3;
83
 		int hash = 3;
93
 	public String toString() {
104
 	public String toString() {
94
 		return "const " + baseType.toString();
105
 		return "const " + baseType.toString();
95
 	}
106
 	}
96
-
97
-	@Override
98
-	public boolean hasDefaultValue() {
99
-		return baseType.hasDefaultValue();
100
-	}
101
 }
107
 }

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

8
 import java.util.Arrays;
8
 import java.util.Arrays;
9
 import java.util.Collections;
9
 import java.util.Collections;
10
 import java.util.HashMap;
10
 import java.util.HashMap;
11
+import java.util.List;
11
 import java.util.Map;
12
 import java.util.Map;
12
 import java.util.Objects;
13
 import java.util.Objects;
13
 import org.openzen.zenscript.codemodel.GenericMapper;
14
 import org.openzen.zenscript.codemodel.GenericMapper;
216
 	public boolean hasDefaultValue() {
217
 	public boolean hasDefaultValue() {
217
 		return definition.hasEmptyConstructor();
218
 		return definition.hasEmptyConstructor();
218
 	}
219
 	}
220
+
221
+	@Override
222
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
223
+		for (ITypeID type : this.typeParameters)
224
+			type.extractTypeParameters(typeParameters);
225
+	}
219
 	
226
 	
220
 	private class OuterTypeEntry {
227
 	private class OuterTypeEntry {
221
 		private final TypeParameter parameter;
228
 		private final TypeParameter parameter;

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

6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
 import java.util.Arrays;
8
 import java.util.Arrays;
9
+import java.util.List;
9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
 import org.openzen.zenscript.codemodel.FunctionParameter;
11
 import org.openzen.zenscript.codemodel.FunctionParameter;
11
 import org.openzen.zenscript.codemodel.GenericMapper;
12
 import org.openzen.zenscript.codemodel.GenericMapper;
62
 		return false;
63
 		return false;
63
 	}
64
 	}
64
 
65
 
66
+	@Override
67
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
68
+		header.returnType.extractTypeParameters(typeParameters);
69
+		for (FunctionParameter parameter : header.parameters)
70
+			parameter.type.extractTypeParameters(typeParameters);
71
+	}
72
+
65
 	@Override
73
 	@Override
66
 	public int hashCode() {
74
 	public int hashCode() {
67
 		int hash = 5;
75
 		int hash = 5;

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import java.util.Objects;
9
 import java.util.Objects;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
61
 	public boolean isObjectType() {
62
 	public boolean isObjectType() {
62
 		return true;
63
 		return true;
63
 	}
64
 	}
65
+
66
+	@Override
67
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
68
+		value.extractTypeParameters(typeParameters);
69
+		typeParameters.remove(key);
70
+	}
64
 	
71
 	
65
 	@Override
72
 	@Override
66
 	public String toString() {
73
 	public String toString() {

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
11
 import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
68
 		return false;
69
 		return false;
69
 	}
70
 	}
70
 
71
 
72
+	@Override
73
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
74
+		if (!typeParameters.contains(parameter))
75
+			typeParameters.add(parameter);
76
+	}
77
+
71
 	@Override
78
 	@Override
72
 	public int hashCode() {
79
 	public int hashCode() {
73
 		int hash = 7;
80
 		int hash = 7;

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import java.util.Map;
9
 import java.util.Map;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
64
 		return accept(new MatchingTypeVisitor(cache, targetType, mapping));
65
 		return accept(new MatchingTypeVisitor(cache, targetType, mapping));
65
 	}
66
 	}
66
 	
67
 	
68
+	public void extractTypeParameters(List<TypeParameter> typeParameters);
69
+	
67
 	public static class MatchingTypeVisitor implements ITypeVisitor<Boolean> {
70
 	public static class MatchingTypeVisitor implements ITypeVisitor<Boolean> {
68
 		private final ITypeID type;
71
 		private final ITypeID type;
69
 		private final Map<TypeParameter, ITypeID> mapping;
72
 		private final Map<TypeParameter, ITypeID> mapping;

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

6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
 import java.util.Arrays;
8
 import java.util.Arrays;
9
+import java.util.List;
9
 import java.util.Map;
10
 import java.util.Map;
10
 import org.openzen.zenscript.codemodel.GenericMapper;
11
 import org.openzen.zenscript.codemodel.GenericMapper;
11
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
68
 		return false;
69
 		return false;
69
 	}
70
 	}
70
 
71
 
72
+	@Override
73
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
74
+		for (ITypeID type : iteratorTypes)
75
+			type.extractTypeParameters(typeParameters);
76
+	}
77
+
71
 	@Override
78
 	@Override
72
 	public int hashCode() {
79
 	public int hashCode() {
73
 		int hash = 5;
80
 		int hash = 5;

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import java.util.Objects;
9
 import java.util.Objects;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.GenericMapper;
10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
77
 		return true;
78
 		return true;
78
 	}
79
 	}
79
 
80
 
81
+	@Override
82
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
83
+		baseType.extractTypeParameters(typeParameters);
84
+	}
85
+
80
 	@Override
86
 	@Override
81
 	public int hashCode() {
87
 	public int hashCode() {
82
 		int hash = 7;
88
 		int hash = 7;

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

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.type;
6
 package org.openzen.zenscript.codemodel.type;
7
 
7
 
8
+import java.util.List;
8
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.GenericMapper;
9
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
10
 
11
 
65
 		return false;
66
 		return false;
66
 	}
67
 	}
67
 
68
 
69
+	@Override
70
+	public void extractTypeParameters(List<TypeParameter> typeParameters) {
71
+		from.extractTypeParameters(typeParameters);
72
+		to.extractTypeParameters(typeParameters);
73
+	}
74
+
68
 	@Override
75
 	@Override
69
 	public int hashCode() {
76
 	public int hashCode() {
70
 		int hash = 5;
77
 		int hash = 5;

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

396
 	GENERICMAP_GETOPTIONAL,
396
 	GENERICMAP_GETOPTIONAL,
397
 	GENERICMAP_PUT,
397
 	GENERICMAP_PUT,
398
 	GENERICMAP_CONTAINS,
398
 	GENERICMAP_CONTAINS,
399
+	GENERICMAP_ADDALL,
399
 	GENERICMAP_SIZE,
400
 	GENERICMAP_SIZE,
400
 	GENERICMAP_ISEMPTY,
401
 	GENERICMAP_ISEMPTY,
401
 	GENERICMAP_HASHCODE,
402
 	GENERICMAP_HASHCODE,
441
 	RANGE_FROM,
442
 	RANGE_FROM,
442
 	RANGE_TO,
443
 	RANGE_TO,
443
 	
444
 	
445
+	OPTIONAL_IS_NULL,
446
+	OPTIONAL_IS_NOT_NULL,
444
 	AUTOOP_NOTEQUALS
447
 	AUTOOP_NOTEQUALS
445
 }
448
 }

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

300
 	
300
 	
301
 	public FunctionalMemberRef selectMethod(CodePosition position, TypeScope scope, CallArguments arguments, boolean allowNonStatic, boolean allowStatic) {
301
 	public FunctionalMemberRef selectMethod(CodePosition position, TypeScope scope, CallArguments arguments, boolean allowNonStatic, boolean allowStatic) {
302
 		// try to match with exact types
302
 		// try to match with exact types
303
-		outer: for (TypeMember<FunctionalMemberRef> method : methods) {
303
+		for (TypeMember<FunctionalMemberRef> method : methods) {
304
 			if (!(method.member.isStatic() ? allowStatic : allowNonStatic))
304
 			if (!(method.member.isStatic() ? allowStatic : allowNonStatic))
305
 				continue;
305
 				continue;
306
 			
306
 			
307
 			FunctionHeader header = method.member.header;
307
 			FunctionHeader header = method.member.header;
308
-			if (header.parameters.length != arguments.arguments.length)
309
-				continue;
310
-			if (header.getNumberOfTypeParameters() != arguments.getNumberOfTypeArguments())
311
-				continue;
312
-			
313
-			if (arguments.typeArguments.length > 0) {
314
-				header = header.fillGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
315
-			}
316
-			
317
-			for (int i = 0; i < header.parameters.length; i++) {
318
-				if (arguments.arguments[i].type != header.parameters[i].type)
319
-					continue outer;
320
-			}
321
-			
322
-			return method.member;
308
+			if (header.matchesExactly(arguments, scope))
309
+				return method.member;
323
 		}
310
 		}
324
 		
311
 		
325
 		// try to match with approximate types
312
 		// try to match with approximate types
326
 		FunctionalMemberRef selected = null;
313
 		FunctionalMemberRef selected = null;
327
-		outer: for (TypeMember<FunctionalMemberRef> method : methods) {
314
+		for (TypeMember<FunctionalMemberRef> method : methods) {
328
 			if (!(method.member.isStatic() ? allowStatic : allowNonStatic))
315
 			if (!(method.member.isStatic() ? allowStatic : allowNonStatic))
329
 				continue;
316
 				continue;
330
 			
317
 			
331
 			FunctionHeader header = method.member.header;
318
 			FunctionHeader header = method.member.header;
332
-			if (header.parameters.length != arguments.arguments.length)
319
+			if (!header.matchesImplicitly(arguments, scope))
333
 				continue;
320
 				continue;
334
-			if (header.getNumberOfTypeParameters() != arguments.getNumberOfTypeArguments())
335
-				continue;
336
-			
337
-			if (arguments.typeArguments.length > 0) {
338
-				header = header.fillGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
339
-			}
340
-			
341
-			for (int i = 0; i < header.parameters.length; i++) {
342
-				if (!scope.getTypeMembers(arguments.arguments[i].type).canCastImplicit(header.parameters[i].type))
343
-					continue outer;
344
-			}
345
 			
321
 			
346
 			if (selected != null) {
322
 			if (selected != null) {
347
 				StringBuilder explanation = new StringBuilder();
323
 				StringBuilder explanation = new StringBuilder();

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

355
 		method(builtin, "getOptional", getOptionalHeader, GENERICMAP_GETOPTIONAL);
355
 		method(builtin, "getOptional", getOptionalHeader, GENERICMAP_GETOPTIONAL);
356
 		method(builtin, "put", putHeader, GENERICMAP_PUT);
356
 		method(builtin, "put", putHeader, GENERICMAP_PUT);
357
 		method(builtin, "contains", containsHeader, GENERICMAP_CONTAINS);
357
 		method(builtin, "contains", containsHeader, GENERICMAP_CONTAINS);
358
+		method(builtin, "addAll", new FunctionHeader(VOID, map), GENERICMAP_ADDALL);
358
 		
359
 		
359
 		getter(builtin, GENERICMAP_SIZE, "size", INT);
360
 		getter(builtin, GENERICMAP_SIZE, "size", INT);
360
 		getter(builtin, GENERICMAP_ISEMPTY, "isEmpty", BOOL);
361
 		getter(builtin, GENERICMAP_ISEMPTY, "isEmpty", BOOL);
535
 	public Void visitOptional(OptionalTypeID optional) {
536
 	public Void visitOptional(OptionalTypeID optional) {
536
 		ClassDefinition builtin = new ClassDefinition(BUILTIN, null, "optional", Modifiers.EXPORT, null);
537
 		ClassDefinition builtin = new ClassDefinition(BUILTIN, null, "optional", Modifiers.EXPORT, null);
537
 		optional.baseType.accept(this);
538
 		optional.baseType.accept(this);
539
+		operator(builtin, OperatorType.EQUALS, new FunctionHeader(BOOL, NULL), BuiltinID.OPTIONAL_IS_NULL);
540
+		operator(builtin, OperatorType.NOTEQUALS, new FunctionHeader(BOOL, NULL), BuiltinID.OPTIONAL_IS_NOT_NULL);
538
 		processType(builtin, optional);
541
 		processType(builtin, optional);
539
 		return null;
542
 		return null;
540
 	}
543
 	}

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

87
     public Void visitCustomIterator() {
87
     public Void visitCustomIterator() {
88
         return null;
88
         return null;
89
     }
89
     }
90
+
91
+	@Override
92
+	public Void visitAssocKeyIterator() {
93
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
94
+	}
95
+
96
+	@Override
97
+	public Void visitAssocKeyValueIterator() {
98
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
99
+	}
90
 }
100
 }

+ 166
- 0
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/BaseMemberCompiler.java View File

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.javasource;
7
+
8
+import java.util.Collections;
9
+import org.openzen.zenscript.codemodel.FunctionHeader;
10
+import org.openzen.zenscript.codemodel.FunctionParameter;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
+import org.openzen.zenscript.codemodel.Modifiers;
13
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
14
+import org.openzen.zenscript.codemodel.member.MemberVisitor;
15
+import org.openzen.zenscript.codemodel.statement.BlockStatement;
16
+import org.openzen.zenscript.codemodel.statement.EmptyStatement;
17
+import org.openzen.zenscript.codemodel.statement.Statement;
18
+import org.openzen.zenscript.codemodel.type.ITypeID;
19
+import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
20
+import org.openzen.zenscript.javasource.scope.JavaSourceStatementScope;
21
+
22
+/**
23
+ *
24
+ * @author Hoofdgebruiker
25
+ */
26
+public abstract class BaseMemberCompiler implements MemberVisitor<Void> {
27
+	protected final String indent;
28
+	protected final StringBuilder output;
29
+	protected final JavaSourceFileScope scope;
30
+	protected final JavaSourceStatementScope fieldInitializerScope;
31
+	protected final JavaSourceFormattingSettings settings;
32
+	protected final ITypeID expansionTarget;
33
+	protected final HighLevelDefinition definition;
34
+	
35
+	private ElementType currentElementType = null;
36
+	
37
+	public BaseMemberCompiler(
38
+			JavaSourceFormattingSettings settings,
39
+			String indent,
40
+			StringBuilder output,
41
+			JavaSourceFileScope scope,
42
+			ITypeID expansionTarget,
43
+			HighLevelDefinition definition)
44
+	{
45
+		this.indent = indent;
46
+		this.output = output;
47
+		this.scope = scope;
48
+		this.settings = settings;
49
+		this.expansionTarget = expansionTarget;
50
+		this.definition = definition;
51
+		
52
+		fieldInitializerScope = new JavaSourceStatementScope(
53
+				scope,
54
+				settings,
55
+				null,
56
+				indent + settings.indent,
57
+				null,
58
+				null,
59
+				true);
60
+	}
61
+	
62
+	protected void begin(ElementType type) {
63
+		if (currentElementType != null) {
64
+			if (currentElementType != ElementType.FIELD || type != ElementType.FIELD)
65
+				output.append(indent).append('\n');
66
+		}
67
+		
68
+		this.currentElementType = type;
69
+	}
70
+	
71
+	protected void modifiers(int modifiers) {
72
+		if (Modifiers.isPublic(modifiers))
73
+			output.append("public ");
74
+		if (Modifiers.isProtected(modifiers))
75
+			output.append("protected ");
76
+		if (Modifiers.isPrivate(modifiers))
77
+			output.append("private ");
78
+		if (Modifiers.isStatic(modifiers))
79
+			output.append("static ");
80
+		if (Modifiers.isFinal(modifiers))
81
+			output.append("final ");
82
+	}
83
+	
84
+	protected void compileBody(Statement body, FunctionHeader header) {
85
+		if (body == null || body instanceof EmptyStatement) {
86
+			output.append(";\n");
87
+		} else {
88
+			if (!(body instanceof BlockStatement))
89
+				body = new BlockStatement(body.position, Collections.singletonList(body));
90
+			
91
+			JavaSourceStatementScope scope = new JavaSourceStatementScope(this.scope, settings, header, indent + settings.indent, null, null, expansionTarget != null);
92
+			body.accept(new JavaSourceStatementCompiler(scope, output, true, false));
93
+			output.append('\n');
94
+		}
95
+	}
96
+	
97
+	protected void formatParameters(boolean isStatic, FunctionHeader header) {
98
+		formatParameters(isStatic, null, header);
99
+	}
100
+	
101
+	protected void formatParameters(boolean isStatic, TypeParameter[] targetTypeParameters, FunctionHeader header) {
102
+		output.append("(");
103
+		boolean first = true;
104
+		if (expansionTarget != null && !isStatic) {
105
+			if (targetTypeParameters != null) {
106
+				for (TypeParameter parameter : targetTypeParameters) {
107
+					if (first)
108
+						first = false;
109
+					else
110
+						output.append(", ");
111
+
112
+					output.append("Class<").append(parameter.name).append("> typeOf").append(parameter.name);
113
+				}
114
+			}
115
+			if (first)
116
+				first = false;
117
+			else
118
+				output.append(", ");
119
+			
120
+			output.append(scope.type(expansionTarget));
121
+			output.append(" self");
122
+		}
123
+		if (header.typeParameters != null) {
124
+			for (TypeParameter typeParameter : header.typeParameters) {
125
+				if (first)
126
+					first = false;
127
+				else
128
+					output.append(", ");
129
+
130
+				output.append("Class<")
131
+						.append(typeParameter.name)
132
+						.append(">")
133
+						.append(" ")
134
+						.append("typeOf")
135
+						.append(typeParameter.name);
136
+			}
137
+		}
138
+		
139
+		for (int i = 0; i < header.parameters.length; i++) {
140
+			if (first)
141
+				first = false;
142
+			else
143
+				output.append(", ");
144
+			
145
+			FunctionParameter parameter = header.parameters[i];
146
+			output.append(scope.type(parameter.type));
147
+			output.append(" ").append(parameter.name);
148
+			if (parameter.variadic)
149
+				output.append("...");
150
+		}
151
+		output.append(")");
152
+		
153
+		if (header.thrownType != null) {
154
+			output.append(" throws ");
155
+			output.append(scope.type(header.thrownType));
156
+		}
157
+	}
158
+	
159
+	public enum ElementType {
160
+		STATICINIT,
161
+		FIELD,
162
+		CONSTRUCTOR,
163
+		METHOD,
164
+		INNERCLASS
165
+	}
166
+}

+ 92
- 22
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaDefinitionVisitor.java View File

7
 
7
 
8
 import java.util.ArrayList;
8
 import java.util.ArrayList;
9
 import java.util.List;
9
 import java.util.List;
10
+import java.util.Map;
10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.Modifiers;
12
 import org.openzen.zenscript.codemodel.Modifiers;
12
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
13
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
21
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
22
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
22
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
23
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
23
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
24
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
25
+import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
26
+import org.openzen.zenscript.codemodel.type.ITypeID;
27
+import org.openzen.zenscript.compiler.CompileScope;
28
+import org.openzen.zenscript.compiler.SemanticModule;
29
+import org.openzen.zenscript.javasource.prepare.JavaNativeClass;
24
 import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
30
 import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
31
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
25
 
32
 
26
 /**
33
 /**
27
  *
34
  *
28
  * @author Hoofdgebruiker
35
  * @author Hoofdgebruiker
29
  */
36
  */
30
 public class JavaDefinitionVisitor implements DefinitionVisitor<Void> {
37
 public class JavaDefinitionVisitor implements DefinitionVisitor<Void> {
31
-	private final JavaSourceFileScope scope;
38
+	private final JavaSourceCompiler compiler;
39
+	private final JavaSourceClass cls;
40
+	private final JavaSourceFile file;
32
 	private final JavaSourceFormattingSettings settings;
41
 	private final JavaSourceFormattingSettings settings;
42
+	private final List<ExpansionDefinition> expansions;
33
 	private final StringBuilder output;
43
 	private final StringBuilder output;
44
+	private final Map<HighLevelDefinition, SemanticModule> modules;
34
 	
45
 	
35
-	public JavaDefinitionVisitor(JavaSourceFormattingSettings settings, JavaSourceFileScope scope, StringBuilder output) {
36
-		this.settings = settings;
37
-		this.scope = scope;
46
+	public JavaDefinitionVisitor(
47
+			JavaSourceCompiler compiler,
48
+			JavaSourceClass cls,
49
+			JavaSourceFile file,
50
+			StringBuilder output,
51
+			List<ExpansionDefinition> expansions,
52
+			Map<HighLevelDefinition, SemanticModule> modules)
53
+	{
54
+		this.compiler = compiler;
55
+		this.cls = cls;
56
+		this.file = file;
57
+		this.settings = compiler.settings;
38
 		this.output = output;
58
 		this.output = output;
59
+		this.expansions = expansions;
60
+		this.modules = modules;
61
+	}
62
+	
63
+	private JavaSourceFileScope createScope(HighLevelDefinition definition) {
64
+		SemanticModule module = modules.get(definition);
65
+		CompileScope scope = new CompileScope(definition.access, module.compilationUnit.globalTypeRegistry, module.expansions, module.annotations);
66
+		return new JavaSourceFileScope(file.importer, compiler.typeGenerator, compiler.helperGenerator, cls, scope, definition instanceof InterfaceDefinition);
39
 	}
67
 	}
40
 
68
 
41
 	@Override
69
 	@Override
42
 	public Void visitClass(ClassDefinition definition) {
70
 	public Void visitClass(ClassDefinition definition) {
71
+		JavaSourceFileScope scope = createScope(definition);
72
+		
43
 		convertModifiers(definition.modifiers);
73
 		convertModifiers(definition.modifiers);
44
 		output.append("class ").append(definition.name);
74
 		output.append("class ").append(definition.name);
45
-		JavaSourceUtils.formatTypeParameters(scope, output, definition.genericParameters);
75
+		JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, definition.genericParameters);
46
 		if (definition.superType != null) {
76
 		if (definition.superType != null) {
47
 			output.append(" extends ");
77
 			output.append(" extends ");
48
 			output.append(scope.type(definition.superType));
78
 			output.append(scope.type(definition.superType));
67
 		}
97
 		}
68
 		
98
 		
69
 		output.append(" {\n");
99
 		output.append(" {\n");
70
-		compileMembers(definition);
100
+		compileMembers(scope, definition);
101
+		compileExpansions();
71
 		output.append("}\n");
102
 		output.append("}\n");
72
 		return null;
103
 		return null;
73
 	}
104
 	}
74
 
105
 
75
 	@Override
106
 	@Override
76
 	public Void visitInterface(InterfaceDefinition definition) {
107
 	public Void visitInterface(InterfaceDefinition definition) {
108
+		JavaSourceFileScope scope = createScope(definition);
109
+		
77
 		convertModifiers(definition.modifiers | Modifiers.VIRTUAL); // to prevent 'final'
110
 		convertModifiers(definition.modifiers | Modifiers.VIRTUAL); // to prevent 'final'
78
 		output.append("interface ").append(definition.name);
111
 		output.append("interface ").append(definition.name);
79
-		JavaSourceUtils.formatTypeParameters(scope, output, definition.genericParameters);
112
+		JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, definition.genericParameters);
80
 		output.append(" {\n");
113
 		output.append(" {\n");
81
-		compileMembers(definition);
114
+		compileMembers(scope, definition);
115
+		compileExpansions();
82
 		output.append("}\n");
116
 		output.append("}\n");
83
 		return null;
117
 		return null;
84
 	}
118
 	}
85
 
119
 
86
 	@Override
120
 	@Override
87
 	public Void visitEnum(EnumDefinition definition) {
121
 	public Void visitEnum(EnumDefinition definition) {
122
+		JavaSourceFileScope scope = createScope(definition);
123
+		
88
 		convertModifiers(definition.modifiers | Modifiers.VIRTUAL); // to prevent 'final'
124
 		convertModifiers(definition.modifiers | Modifiers.VIRTUAL); // to prevent 'final'
89
 		output.append("enum ").append(definition.name);
125
 		output.append("enum ").append(definition.name);
90
 		
126
 		
104
 		
140
 		
105
 		if (definition.members.size() > 0) {
141
 		if (definition.members.size() > 0) {
106
 			output.append(";\n");
142
 			output.append(";\n");
107
-			compileMembers(definition);
143
+			compileMembers(scope, definition);
108
 		} else {
144
 		} else {
109
 			output.append("\n");
145
 			output.append("\n");
110
 		}
146
 		}
111
 		
147
 		
148
+		compileExpansions();
112
 		output.append("}\n");
149
 		output.append("}\n");
113
 		return null;
150
 		return null;
114
 	}
151
 	}
115
 
152
 
116
 	@Override
153
 	@Override
117
 	public Void visitStruct(StructDefinition definition) {
154
 	public Void visitStruct(StructDefinition definition) {
155
+		JavaSourceFileScope scope = createScope(definition);
156
+		
118
 		convertModifiers(definition.modifiers | Modifiers.FINAL);
157
 		convertModifiers(definition.modifiers | Modifiers.FINAL);
119
 		output.append("class ").append(definition.name);
158
 		output.append("class ").append(definition.name);
120
-		JavaSourceUtils.formatTypeParameters(scope, output, definition.genericParameters);
159
+		JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, definition.genericParameters);
121
 		output.append(" {\n");
160
 		output.append(" {\n");
122
-		compileMembers(definition);
161
+		compileMembers(scope, definition);
162
+		compileExpansions();
123
 		output.append("}\n");
163
 		output.append("}\n");
124
 		return null;
164
 		return null;
125
 	}
165
 	}
126
 
166
 
127
 	@Override
167
 	@Override
128
 	public Void visitFunction(FunctionDefinition definition) {
168
 	public Void visitFunction(FunctionDefinition definition) {
169
+		JavaSourceFileScope scope = createScope(definition);
170
+		
129
 		convertModifiers(definition.modifiers | Modifiers.STATIC);
171
 		convertModifiers(definition.modifiers | Modifiers.STATIC);
130
 		
172
 		
131
 		return null;
173
 		return null;
133
 
175
 
134
 	@Override
176
 	@Override
135
 	public Void visitExpansion(ExpansionDefinition definition) {
177
 	public Void visitExpansion(ExpansionDefinition definition) {
178
+		JavaSourceFileScope scope = createScope(definition);
179
+		
136
 		convertModifiers(definition.modifiers);
180
 		convertModifiers(definition.modifiers);
137
 		output.append("class ");
181
 		output.append("class ");
138
-		output.append(scope.className);
182
+		output.append(cls.name);
139
 		output.append(" {\n");
183
 		output.append(" {\n");
140
-		output.append(settings.indent).append("private ").append(scope.className).append("() {}\n");
184
+		output.append(settings.indent).append("private ").append(cls.name).append("() {}\n");
141
 		
185
 		
142
-		JavaExpansionMemberCompiler memberCompiler = new JavaExpansionMemberCompiler(settings, definition.target, "\t", output, scope);
186
+		JavaExpansionMemberCompiler memberCompiler = new JavaExpansionMemberCompiler(settings, definition.target, definition.genericParameters, "\t", output, scope, definition);
143
 		for (IDefinitionMember member : definition.members)
187
 		for (IDefinitionMember member : definition.members)
144
 			member.accept(memberCompiler);
188
 			member.accept(memberCompiler);
145
 		memberCompiler.finish();
189
 		memberCompiler.finish();
146
 		
190
 		
191
+		compileExpansions();
147
 		output.append("}");
192
 		output.append("}");
148
 		return null;
193
 		return null;
149
 	}
194
 	}
155
 
200
 
156
 	@Override
201
 	@Override
157
 	public Void visitVariant(VariantDefinition variant) {
202
 	public Void visitVariant(VariantDefinition variant) {
203
+		JavaSourceFileScope scope = createScope(variant);
204
+		
158
 		convertModifiers(variant.modifiers | Modifiers.VIRTUAL | Modifiers.ABSTRACT);
205
 		convertModifiers(variant.modifiers | Modifiers.VIRTUAL | Modifiers.ABSTRACT);
159
 		output.append("class ").append(variant.name);
206
 		output.append("class ").append(variant.name);
160
-		JavaSourceUtils.formatTypeParameters(scope, output, variant.genericParameters);
207
+		JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, variant.genericParameters);
161
 		output.append("{\n");
208
 		output.append("{\n");
162
-		compileMembers(variant);
209
+		compileMembers(scope, variant);
163
 		output.append(settings.indent).append("public abstract Discriminant getDiscriminant();\n");
210
 		output.append(settings.indent).append("public abstract Discriminant getDiscriminant();\n");
164
 		
211
 		
165
 		output.append(settings.indent).append("\n");
212
 		output.append(settings.indent).append("\n");
172
 		for (VariantDefinition.Option option : variant.options) {
219
 		for (VariantDefinition.Option option : variant.options) {
173
 			output.append(settings.indent).append("\n");
220
 			output.append(settings.indent).append("\n");
174
 			output.append(settings.indent).append("public static class ").append(option.name);
221
 			output.append(settings.indent).append("public static class ").append(option.name);
175
-			JavaSourceUtils.formatTypeParameters(scope, output, variant.genericParameters);
222
+			JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, variant.genericParameters);
176
 			output.append(" extends ");
223
 			output.append(" extends ");
177
 			output.append(variant.name);
224
 			output.append(variant.name);
178
 			if (variant.genericParameters != null && variant.genericParameters.length > 0) {
225
 			if (variant.genericParameters != null && variant.genericParameters.length > 0) {
216
 			output.append(settings.indent).append("}\n");
263
 			output.append(settings.indent).append("}\n");
217
 		}
264
 		}
218
 		
265
 		
266
+		compileExpansions();
219
 		output.append("}\n");
267
 		output.append("}\n");
220
 		return null;
268
 		return null;
221
 	}
269
 	}
222
 	
270
 	
271
+	private void compileExpansions() {
272
+		for (ExpansionDefinition definition : expansions) {
273
+			JavaSourceFileScope scope = createScope(definition);
274
+			JavaExpansionMemberCompiler memberCompiler = new JavaExpansionMemberCompiler(settings, definition.target, definition.genericParameters, "\t", output, scope, definition);
275
+			for (IDefinitionMember member : definition.members)
276
+				member.accept(memberCompiler);
277
+			memberCompiler.finish();
278
+		}
279
+	}
280
+	
223
 	private void convertModifiers(int modifiers) {
281
 	private void convertModifiers(int modifiers) {
224
 		if (Modifiers.isExport(modifiers) || Modifiers.isPublic(modifiers))
282
 		if (Modifiers.isExport(modifiers) || Modifiers.isPublic(modifiers))
225
 			output.append("public ");
283
 			output.append("public ");
239
 		return true; // TODO: check merging conflicts
297
 		return true; // TODO: check merging conflicts
240
 	}
298
 	}
241
 	
299
 	
242
-	private void compileMembers(HighLevelDefinition definition) {
243
-		JavaMemberCompiler memberCompiler = new JavaMemberCompiler(settings, "\t", output, scope, false, scope.isInterface);
244
-		for (IDefinitionMember member : definition.members)
245
-			member.accept(memberCompiler);
246
-		memberCompiler.finish();
300
+	private void compileMembers(JavaSourceFileScope scope, HighLevelDefinition definition) {
301
+		if (definition.hasTag(JavaNativeClass.class)) {
302
+			ITypeID[] typeParameters = new ITypeID[definition.getNumberOfGenericParameters()];
303
+			for (int i = 0; i < typeParameters.length; i++)
304
+				typeParameters[i] = scope.semanticScope.getTypeRegistry().getGeneric(definition.genericParameters[i]);
305
+			ITypeID targetType = new DefinitionTypeID(definition, typeParameters);
306
+			
307
+			JavaExpansionMemberCompiler memberCompiler = new JavaExpansionMemberCompiler(settings, targetType, definition.genericParameters, "\t", output, scope, definition);
308
+			for (IDefinitionMember member : definition.members)
309
+				member.accept(memberCompiler);
310
+			memberCompiler.finish();
311
+		} else {
312
+			JavaMemberCompiler memberCompiler = new JavaMemberCompiler(settings, "\t", output, scope, scope.isInterface, definition);
313
+			for (IDefinitionMember member : definition.members)
314
+				member.accept(memberCompiler);
315
+			memberCompiler.finish();
316
+		}
247
 	}
317
 	}
248
 }
318
 }

+ 50
- 247
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaExpansionMemberCompiler.java View File

6
 package org.openzen.zenscript.javasource;
6
 package org.openzen.zenscript.javasource;
7
 
7
 
8
 import java.util.ArrayList;
8
 import java.util.ArrayList;
9
-import java.util.Collections;
10
 import java.util.List;
9
 import java.util.List;
11
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
12
 import org.openzen.zenscript.codemodel.FunctionParameter;
11
 import org.openzen.zenscript.codemodel.FunctionParameter;
12
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
13
 import org.openzen.zenscript.codemodel.Modifiers;
13
 import org.openzen.zenscript.codemodel.Modifiers;
14
-import org.openzen.zenscript.codemodel.OperatorType;
15
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
14
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
16
 import org.openzen.zenscript.codemodel.member.CallerMember;
15
 import org.openzen.zenscript.codemodel.member.CallerMember;
17
 import org.openzen.zenscript.codemodel.member.CasterMember;
16
 import org.openzen.zenscript.codemodel.member.CasterMember;
18
 import org.openzen.zenscript.codemodel.member.ConstMember;
17
 import org.openzen.zenscript.codemodel.member.ConstMember;
19
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
18
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
20
 import org.openzen.zenscript.codemodel.member.CustomIteratorMember;
19
 import org.openzen.zenscript.codemodel.member.CustomIteratorMember;
20
+import org.openzen.zenscript.codemodel.member.DefinitionMember;
21
 import org.openzen.zenscript.codemodel.member.DestructorMember;
21
 import org.openzen.zenscript.codemodel.member.DestructorMember;
22
 import org.openzen.zenscript.codemodel.member.FieldMember;
22
 import org.openzen.zenscript.codemodel.member.FieldMember;
23
 import org.openzen.zenscript.codemodel.member.GetterMember;
23
 import org.openzen.zenscript.codemodel.member.GetterMember;
24
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
24
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
25
 import org.openzen.zenscript.codemodel.member.InnerDefinitionMember;
25
 import org.openzen.zenscript.codemodel.member.InnerDefinitionMember;
26
-import org.openzen.zenscript.codemodel.member.MemberVisitor;
27
 import org.openzen.zenscript.codemodel.member.MethodMember;
26
 import org.openzen.zenscript.codemodel.member.MethodMember;
28
 import org.openzen.zenscript.codemodel.member.OperatorMember;
27
 import org.openzen.zenscript.codemodel.member.OperatorMember;
29
 import org.openzen.zenscript.codemodel.member.SetterMember;
28
 import org.openzen.zenscript.codemodel.member.SetterMember;
30
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
29
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
31
-import org.openzen.zenscript.codemodel.statement.BlockStatement;
32
-import org.openzen.zenscript.codemodel.statement.EmptyStatement;
33
 import org.openzen.zenscript.codemodel.statement.Statement;
30
 import org.openzen.zenscript.codemodel.statement.Statement;
34
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
31
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
35
 import org.openzen.zenscript.codemodel.type.ITypeID;
32
 import org.openzen.zenscript.codemodel.type.ITypeID;
36
 import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
33
 import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
37
-import org.openzen.zenscript.javasource.scope.JavaSourceStatementScope;
38
-import org.openzen.zenscript.shared.StringUtils;
34
+import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
39
 
35
 
40
 /**
36
 /**
41
  *
37
  *
42
  * @author Hoofdgebruiker
38
  * @author Hoofdgebruiker
43
  */
39
  */
44
-public class JavaExpansionMemberCompiler implements MemberVisitor<Void> {
45
-	private final String indent;
46
-	private final StringBuilder output;
47
-	private final JavaSourceFileScope scope;
48
-	private final JavaSourceStatementScope fieldInitializerScope;
49
-	private final JavaSourceFormattingSettings settings;
40
+public class JavaExpansionMemberCompiler extends BaseMemberCompiler {
50
 	private final List<FieldMember> fields = new ArrayList<>();
41
 	private final List<FieldMember> fields = new ArrayList<>();
51
-	private final ITypeID targetType;
52
-	private boolean first = true;
42
+	private final TypeParameter[] expansionTypeParameters;
53
 	
43
 	
54
-	public JavaExpansionMemberCompiler(JavaSourceFormattingSettings settings, ITypeID targetType, String indent, StringBuilder output, JavaSourceFileScope scope) {
55
-		this.indent = indent;
56
-		this.output = output;
57
-		this.scope = scope;
58
-		this.settings = settings;
59
-		this.targetType = targetType;
44
+	public JavaExpansionMemberCompiler(
45
+			JavaSourceFormattingSettings settings,
46
+			ITypeID targetType,
47
+			TypeParameter[] expansionTypeParameters,
48
+			String indent,
49
+			StringBuilder output,
50
+			JavaSourceFileScope scope,
51
+			HighLevelDefinition definition)
52
+	{
53
+		super(settings, indent, output, scope, targetType, definition);
60
 		
54
 		
61
-		fieldInitializerScope = new JavaSourceStatementScope(
62
-				scope,
63
-				settings,
64
-				null,
65
-				indent + settings.indent,
66
-				null,
67
-				null,
68
-				true);
55
+		this.expansionTypeParameters = expansionTypeParameters;
69
 	}
56
 	}
70
 	
57
 	
71
-	private void addSpacing() {
72
-		if (first)
73
-			first = false;
58
+	private void compileMethod(DefinitionMember member, FunctionHeader header, Statement body) {
59
+		JavaSourceMethod method = member.getTag(JavaSourceMethod.class);
60
+		if (method == null)
61
+			throw new AssertionError();
62
+		if (!method.compile)
63
+			return;
64
+		
65
+		begin(ElementType.METHOD);
66
+		output.append(indent);
67
+		
68
+		modifiers(member.modifiers | Modifiers.STATIC);
69
+		if (member.isStatic())
70
+			JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, header.typeParameters);
74
 		else
71
 		else
75
-			output.append(indent).append("\n");
72
+			JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, expansionTypeParameters, header.typeParameters);
73
+		
74
+		output.append(header.returnType.accept(scope.typeVisitor));
75
+		output.append(" ");
76
+		output.append(method.name);
77
+		formatParameters(member.isStatic(), expansionTypeParameters, header);
78
+		compileBody(body, header);
76
 	}
79
 	}
77
 	
80
 	
78
 	@Override
81
 	@Override
79
 	public Void visitConst(ConstMember member) {
82
 	public Void visitConst(ConstMember member) {
83
+		begin(ElementType.FIELD);
80
 		modifiers(member.modifiers | Modifiers.STATIC | Modifiers.FINAL);
84
 		modifiers(member.modifiers | Modifiers.STATIC | Modifiers.FINAL);
81
 		output.append(scope.type(member.type));
85
 		output.append(scope.type(member.type));
82
 		output.append(" ");
86
 		output.append(" ");
89
 
93
 
90
 	@Override
94
 	@Override
91
 	public Void visitField(FieldMember member) {
95
 	public Void visitField(FieldMember member) {
92
-		// TODO: nonstatic fields!
93
-		first = false;
96
+		begin(ElementType.FIELD);
94
 		
97
 		
95
 		output.append(indent);
98
 		output.append(indent);
96
 		int modifiers = 0;
99
 		int modifiers = 0;
120
 
123
 
121
 	@Override
124
 	@Override
122
 	public Void visitConstructor(ConstructorMember member) {
125
 	public Void visitConstructor(ConstructorMember member) {
123
-		// TODO: constructors
124
-		/*addSpacing();
125
-		
126
-		output.append(indent);
127
-		modifiers(member.modifiers);
128
-		JavaSourceUtils.formatTypeParameters(importer, output, member.header.typeParameters);
129
-		output.append(importer.getName());
130
-		formatParameters(true, member.header);
131
-		compileBody(member.body, member.header);*/
132
-		throw new UnsupportedOperationException("Expansions cannot declare constructors yet");
126
+		compileMethod(member, member.header, member.body);
127
+		return null;
133
 	}
128
 	}
134
 
129
 
135
 	@Override
130
 	@Override
139
 
134
 
140
 	@Override
135
 	@Override
141
 	public Void visitMethod(MethodMember member) {
136
 	public Void visitMethod(MethodMember member) {
142
-		addSpacing();
143
-		
144
-		output.append(indent);
145
-		
146
-		modifiers(member.modifiers | Modifiers.STATIC);
147
-		JavaSourceUtils.formatTypeParameters(scope, output, member.header.typeParameters);
148
-		output.append(scope.type(member.header.returnType));
149
-		output.append(" ");
150
-		output.append(member.name);
151
-		formatParameters(member.isStatic(), member.header);
152
-		compileBody(member.body, member.header);
137
+		compileMethod(member, member.header, member.body);
153
 		return null;
138
 		return null;
154
 	}
139
 	}
155
 
140
 
156
 	@Override
141
 	@Override
157
 	public Void visitGetter(GetterMember member) {
142
 	public Void visitGetter(GetterMember member) {
158
-		addSpacing();
159
-		
160
-		output.append(indent);
161
-		modifiers(member.modifiers | Modifiers.STATIC);
162
-		output.append(scope.type(member.type));
163
-		output.append(" ");
164
-		output.append("get").append(StringUtils.capitalize(member.name));
165
-		output.append("()");
166
-		compileBody(member.body, member.header);
143
+		compileMethod(member, member.header, member.body);
167
 		return null;
144
 		return null;
168
 	}
145
 	}
169
 
146
 
170
 	@Override
147
 	@Override
171
 	public Void visitSetter(SetterMember member) {
148
 	public Void visitSetter(SetterMember member) {
172
-		addSpacing();
173
-		
174
-		output.append(indent);
175
-		modifiers(member.modifiers | Modifiers.STATIC);
176
-		output.append("void set").append(StringUtils.capitalize(member.name));
177
-		output.append("(");
178
-		output.append(scope.type(member.type));
179
-		output.append(" ");
180
-		output.append("value");
181
-		output.append(")");
182
-		compileBody(member.body, member.header);
149
+		compileMethod(member, new FunctionHeader(BasicTypeID.VOID, new FunctionParameter(member.type, "value")), member.body);
183
 		return null;
150
 		return null;
184
 	}
151
 	}
185
 
152
 
186
 	@Override
153
 	@Override
187
 	public Void visitOperator(OperatorMember member) {
154
 	public Void visitOperator(OperatorMember member) {
188
-		addSpacing();
189
-		
190
-		output.append(indent);
191
-		modifiers(member.modifiers | Modifiers.STATIC);
192
-		output.append(scope.type(member.header.returnType));
193
-		output.append(' ');
194
-		output.append(getOperatorName(member.operator));
195
-		formatParameters(member.isStatic(), member.header);
196
-		compileBody(member.body, member.header);
155
+		compileMethod(member, member.header, member.body);
197
 		return null;
156
 		return null;
198
 	}
157
 	}
199
 
158
 
200
 	@Override
159
 	@Override
201
 	public Void visitCaster(CasterMember member) {
160
 	public Void visitCaster(CasterMember member) {
202
-		addSpacing();
203
-		
204
-		output.append(indent);
205
-		modifiers(member.modifiers | Modifiers.STATIC);
206
-		output.append(scope.type(member.toType));
207
-		output.append(" ");
208
-		output.append("to").append(member.toType.accept(new JavaSourceTypeNameVisitor()));
209
-		output.append("(").append(scope.type(targetType)).append(" self)");
210
-		compileBody(member.body, member.header);
161
+		compileMethod(member, member.header, member.body);
211
 		return null;
162
 		return null;
212
 	}
163
 	}
213
 
164
 
214
 	@Override
165
 	@Override
215
 	public Void visitCustomIterator(CustomIteratorMember member) {
166
 	public Void visitCustomIterator(CustomIteratorMember member) {
216
-		addSpacing();
217
-		
167
+		compileMethod(member, new FunctionHeader(scope.semanticScope.getTypeRegistry().getIterator(member.getLoopVariableTypes())), member.body);
218
 		return null;
168
 		return null;
219
 	}
169
 	}
220
 
170
 
221
 	@Override
171
 	@Override
222
 	public Void visitCaller(CallerMember member) {
172
 	public Void visitCaller(CallerMember member) {
223
-		addSpacing();
224
-		
173
+		compileMethod(member, member.header, member.body);
225
 		return null;
174
 		return null;
226
 	}
175
 	}
227
 
176
 
228
 	@Override
177
 	@Override
229
 	public Void visitImplementation(ImplementationMember member) {
178
 	public Void visitImplementation(ImplementationMember member) {
179
+		// TODO
230
 		return null;
180
 		return null;
231
 	}
181
 	}
232
 
182
 
233
 	@Override
183
 	@Override
234
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
184
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
185
+		// TODO
235
 		return null;
186
 		return null;
236
 	}
187
 	}
237
 
188
 
238
 	@Override
189
 	@Override
239
 	public Void visitStaticInitializer(StaticInitializerMember member) {
190
 	public Void visitStaticInitializer(StaticInitializerMember member) {
240
-		addSpacing();
191
+		begin(ElementType.STATICINIT);
241
 		output.append(indent).append("static ");
192
 		output.append(indent).append("static ");
242
 		compileBody(member.body, new FunctionHeader(BasicTypeID.VOID));
193
 		compileBody(member.body, new FunctionHeader(BasicTypeID.VOID));
243
 		return null;
194
 		return null;
252
 				visitSetter(field.autoSetter);
203
 				visitSetter(field.autoSetter);
253
 		}
204
 		}
254
 	}
205
 	}
255
-	
256
-	private void modifiers(int modifiers) {
257
-		if (Modifiers.isPublic(modifiers))
258
-			output.append("public ");
259
-		if (Modifiers.isProtected(modifiers))
260
-			output.append("protected ");
261
-		if (Modifiers.isPrivate(modifiers))
262
-			output.append("private ");
263
-		if (Modifiers.isStatic(modifiers))
264
-			output.append("static ");
265
-		if (Modifiers.isFinal(modifiers))
266
-			output.append("final ");
267
-	}
268
-	
269
-	private void compileBody(Statement body, FunctionHeader header) {
270
-		if (body == null) {
271
-			output.append(";\n");
272
-		} else {
273
-			if (!(body instanceof BlockStatement))
274
-				body = new BlockStatement(body.position, Collections.singletonList(body));
275
-			
276
-			JavaSourceStatementScope scope = new JavaSourceStatementScope(this.scope, settings, header, indent + settings.indent, null, null, true);
277
-			body.accept(new JavaSourceStatementCompiler(scope, output, true, false));
278
-			output.append('\n');
279
-		}
280
-	}
281
-	
282
-	private void formatParameters(boolean isStatic, FunctionHeader header) {
283
-		output.append("(");
284
-		boolean first = true;
285
-		if (!isStatic) {
286
-			first = false;
287
-			output.append(scope.type(targetType));
288
-			output.append(" self");
289
-		}
290
-		if (header.typeParameters != null) {
291
-			for (TypeParameter typeParameter : header.typeParameters) {
292
-				if (first)
293
-					first = false;
294
-				else
295
-					output.append(", ");
296
-
297
-				output.append("Class<")
298
-						.append(typeParameter.name)
299
-						.append(">")
300
-						.append(" ")
301
-						.append("typeOf")
302
-						.append(typeParameter.name);
303
-			}
304
-		}
305
-		
306
-		for (int i = 0; i < header.parameters.length; i++) {
307
-			if (first)
308
-				first = false;
309
-			else
310
-				output.append(", ");
311
-			
312
-			FunctionParameter parameter = header.parameters[i];
313
-			output.append(scope.type(parameter.type));
314
-			output.append(" ").append(parameter.name);
315
-			if (parameter.variadic)
316
-				output.append("...");
317
-		}
318
-		output.append(")");
319
-	}
320
-	
321
-	private String getOperatorName(OperatorType operator) {
322
-		switch (operator) {
323
-			case NEG:
324
-				return "negate";
325
-			case NOT:
326
-				return "invert";
327
-			case ADD:
328
-				return "add";
329
-			case ADDASSIGN:
330
-				return "addAssign";
331
-			case SUB:
332
-				return "subtract";
333
-			case SUBASSIGN:
334
-				return "subAssign";
335
-			case CAT:
336
-				return "concat";
337
-			case CATASSIGN:
338
-				return "append";
339
-			case MUL:
340
-				return "mul";
341
-			case MULASSIGN:
342
-				return "mulAssign";
343
-			case DIV:
344
-				return "div";
345
-			case DIVASSIGN:
346
-				return "divAssign";
347
-			case MOD:
348
-				return "mod";
349
-			case MODASSIGN:
350
-				return "modAssign";
351
-			case AND:
352
-				return "and";
353
-			case ANDASSIGN:
354
-				return "andAssign";
355
-			case OR:
356
-				return "or";
357
-			case ORASSIGN:
358
-				return "orAssign";
359
-			case XOR:
360
-				return "xor";
361
-			case XORASSIGN:
362
-				return "xorAssign";
363
-			case SHL:
364
-				return "shl";
365
-			case SHLASSIGN:
366
-				return "shlAssign";
367
-			case SHR:
368
-				return "shr";
369
-			case SHRASSIGN:
370
-				return "shrAssign";
371
-			case USHR:
372
-				return "ushr";
373
-			case USHRASSIGN:
374
-				return "ushrAssign";
375
-			case INDEXGET:
376
-				return "getAt";
377
-			case INDEXSET:
378
-				return "setAt";
379
-			case INCREMENT:
380
-				return "increment";
381
-			case DECREMENT:
382
-				return "decrement";
383
-			case CONTAINS:
384
-				return "contains";
385
-			case EQUALS:
386
-				return "equals";
387
-			case COMPARE:
388
-				return "compareTo";
389
-			case RANGE:
390
-				return "until";
391
-			case CAST:
392
-				return "cast";
393
-			case CALL:
394
-				return "call";
395
-			case MEMBERGETTER:
396
-				return "getMember";
397
-			case MEMBERSETTER:
398
-				return "setMember";
399
-			default:
400
-				throw new IllegalArgumentException("Invalid operator: " + operator);
401
-		}
402
-	}
403
 }
206
 }

+ 59
- 171
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaMemberCompiler.java View File

6
 package org.openzen.zenscript.javasource;
6
 package org.openzen.zenscript.javasource;
7
 
7
 
8
 import java.util.ArrayList;
8
 import java.util.ArrayList;
9
-import java.util.Collections;
10
 import java.util.List;
9
 import java.util.List;
11
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
12
 import org.openzen.zenscript.codemodel.FunctionParameter;
11
 import org.openzen.zenscript.codemodel.FunctionParameter;
12
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
13
 import org.openzen.zenscript.codemodel.Modifiers;
13
 import org.openzen.zenscript.codemodel.Modifiers;
14
-import org.openzen.zenscript.codemodel.generic.TypeParameter;
15
 import org.openzen.zenscript.codemodel.member.CallerMember;
14
 import org.openzen.zenscript.codemodel.member.CallerMember;
16
 import org.openzen.zenscript.codemodel.member.CasterMember;
15
 import org.openzen.zenscript.codemodel.member.CasterMember;
17
 import org.openzen.zenscript.codemodel.member.ConstMember;
16
 import org.openzen.zenscript.codemodel.member.ConstMember;
18
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
17
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
19
 import org.openzen.zenscript.codemodel.member.CustomIteratorMember;
18
 import org.openzen.zenscript.codemodel.member.CustomIteratorMember;
19
+import org.openzen.zenscript.codemodel.member.DefinitionMember;
20
 import org.openzen.zenscript.codemodel.member.DestructorMember;
20
 import org.openzen.zenscript.codemodel.member.DestructorMember;
21
 import org.openzen.zenscript.codemodel.member.FieldMember;
21
 import org.openzen.zenscript.codemodel.member.FieldMember;
22
 import org.openzen.zenscript.codemodel.member.GetterMember;
22
 import org.openzen.zenscript.codemodel.member.GetterMember;
23
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
23
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
24
 import org.openzen.zenscript.codemodel.member.InnerDefinitionMember;
24
 import org.openzen.zenscript.codemodel.member.InnerDefinitionMember;
25
-import org.openzen.zenscript.codemodel.member.MemberVisitor;
26
 import org.openzen.zenscript.codemodel.member.MethodMember;
25
 import org.openzen.zenscript.codemodel.member.MethodMember;
27
 import org.openzen.zenscript.codemodel.member.OperatorMember;
26
 import org.openzen.zenscript.codemodel.member.OperatorMember;
28
 import org.openzen.zenscript.codemodel.member.SetterMember;
27
 import org.openzen.zenscript.codemodel.member.SetterMember;
29
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
28
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
30
-import org.openzen.zenscript.codemodel.statement.BlockStatement;
31
 import org.openzen.zenscript.codemodel.statement.EmptyStatement;
29
 import org.openzen.zenscript.codemodel.statement.EmptyStatement;
32
 import org.openzen.zenscript.codemodel.statement.Statement;
30
 import org.openzen.zenscript.codemodel.statement.Statement;
33
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
31
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
34
 import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
32
 import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
35
-import org.openzen.zenscript.javasource.scope.JavaSourceStatementScope;
36
 import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
33
 import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
37
-import org.openzen.zenscript.shared.StringUtils;
38
 
34
 
39
 /**
35
 /**
40
  *
36
  *
41
  * @author Hoofdgebruiker
37
  * @author Hoofdgebruiker
42
  */
38
  */
43
-public class JavaMemberCompiler implements MemberVisitor<Void> {
44
-	private final String indent;
45
-	private final StringBuilder output;
46
-	private final JavaSourceFileScope scope;
47
-	private final JavaSourceStatementScope fieldInitializerScope;
48
-	private final JavaSourceFormattingSettings settings;
39
+public class JavaMemberCompiler extends BaseMemberCompiler {
49
 	private final List<FieldMember> fields = new ArrayList<>();
40
 	private final List<FieldMember> fields = new ArrayList<>();
50
-	private final boolean isExpansion;
51
 	private final boolean isInterface;
41
 	private final boolean isInterface;
52
-	private boolean first = true;
53
 	
42
 	
54
-	public JavaMemberCompiler(JavaSourceFormattingSettings settings, String indent, StringBuilder output, JavaSourceFileScope scope, boolean isExpansion, boolean isInterface) {
55
-		this.indent = indent;
56
-		this.output = output;
57
-		this.scope = scope;
58
-		this.settings = settings;
59
-		this.isExpansion = isExpansion;
60
-		this.isInterface = isInterface;
43
+	public JavaMemberCompiler(
44
+			JavaSourceFormattingSettings settings,
45
+			String indent,
46
+			StringBuilder output,
47
+			JavaSourceFileScope scope,
48
+			boolean isInterface,
49
+			HighLevelDefinition definition)
50
+	{
51
+		super(settings, indent, output, scope, null, definition);
61
 		
52
 		
62
-		fieldInitializerScope = new JavaSourceStatementScope(
63
-				scope,
64
-				settings,
65
-				null,
66
-				indent + settings.indent,
67
-				null,
68
-				null,
69
-				isExpansion);
53
+		this.isInterface = isInterface;
70
 	}
54
 	}
71
 	
55
 	
72
-	private void addSpacing() {
73
-		if (first)
74
-			first = false;
56
+	private void compileMethod(DefinitionMember member, FunctionHeader header, Statement body) {
57
+		JavaSourceMethod method = member.getTag(JavaSourceMethod.class);
58
+		if (method == null)
59
+			throw new AssertionError();
60
+		if (!method.compile)
61
+			return;
62
+		
63
+		boolean hasBody = body != null && !(body instanceof EmptyStatement);
64
+		if (isInterface && method.name.equals("toString") && header.parameters.length == 0) {
65
+			hasBody = false;
66
+		}
67
+			
68
+		
69
+		begin(ElementType.METHOD);
70
+		output.append(indent);
71
+		if (isInterface && hasBody)
72
+			output.append("default ");
73
+		
74
+		modifiers(member.modifiers);
75
+		JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, header.typeParameters);
76
+		output.append(header.returnType.accept(scope.typeVisitor));
77
+		output.append(" ");
78
+		output.append(method.name);
79
+		formatParameters(member.isStatic(), header);
80
+		
81
+		if (hasBody)
82
+			compileBody(body, header);
75
 		else
83
 		else
76
-			output.append(indent).append("\n");
84
+			output.append(";\n");
77
 	}
85
 	}
78
 	
86
 	
79
 	@Override
87
 	@Override
80
 	public Void visitConst(ConstMember member) {
88
 	public Void visitConst(ConstMember member) {
89
+		begin(ElementType.FIELD);
90
+		
81
 		output.append(indent);
91
 		output.append(indent);
82
 		modifiers(member.modifiers | Modifiers.STATIC | Modifiers.FINAL);
92
 		modifiers(member.modifiers | Modifiers.STATIC | Modifiers.FINAL);
83
 		output.append(scope.type(member.type));
93
 		output.append(scope.type(member.type));
91
 
101
 
92
 	@Override
102
 	@Override
93
 	public Void visitField(FieldMember member) {
103
 	public Void visitField(FieldMember member) {
94
-		first = false;
104
+		begin(ElementType.FIELD);
95
 		
105
 		
96
 		output.append(indent);
106
 		output.append(indent);
97
 		int modifiers = 0;
107
 		int modifiers = 0;
121
 
131
 
122
 	@Override
132
 	@Override
123
 	public Void visitConstructor(ConstructorMember member) {
133
 	public Void visitConstructor(ConstructorMember member) {
124
-		addSpacing();
134
+		begin(ElementType.CONSTRUCTOR);
125
 		
135
 		
126
 		output.append(indent);
136
 		output.append(indent);
127
 		modifiers(member.modifiers);
137
 		modifiers(member.modifiers);
128
-		JavaSourceUtils.formatTypeParameters(scope, output, member.header.typeParameters);
129
-		output.append(scope.className);
130
-		formatParameters(member.header);
138
+		JavaSourceUtils.formatTypeParameters(scope.typeVisitor, output, member.header.typeParameters);
139
+		output.append(scope.cls.name);
140
+		formatParameters(member.isStatic(), member.header);
131
 		compileBody(member.body, member.header);
141
 		compileBody(member.body, member.header);
132
 		return null;
142
 		return null;
133
 	}
143
 	}
134
 
144
 
135
 	@Override
145
 	@Override
136
 	public Void visitDestructor(DestructorMember member) {
146
 	public Void visitDestructor(DestructorMember member) {
137
-		addSpacing();
147
+		begin(ElementType.METHOD);
138
 		
148
 		
139
 		output.append(indent).append("@Override\n");
149
 		output.append(indent).append("@Override\n");
140
 		output.append(indent).append("public void close()");
150
 		output.append(indent).append("public void close()");
144
 
154
 
145
 	@Override
155
 	@Override
146
 	public Void visitMethod(MethodMember member) {
156
 	public Void visitMethod(MethodMember member) {
147
-		addSpacing();
148
-		
149
-		
150
-		output.append(indent);
151
-		if (isInterface && member.body != null && !(member.body instanceof EmptyStatement))
152
-			output.append("default ");
153
-		
154
-		modifiers(member.modifiers);
155
-		JavaSourceUtils.formatTypeParameters(scope, output, member.header.typeParameters);
156
-		output.append(member.header.returnType.accept(scope.typeVisitor));
157
-		output.append(" ");
158
-		output.append(member.name);
159
-		formatParameters(member.header);
160
-		compileBody(member.body, member.header);
157
+		compileMethod(member, member.header, member.body);
161
 		return null;
158
 		return null;
162
 	}
159
 	}
163
 
160
 
164
 	@Override
161
 	@Override
165
 	public Void visitGetter(GetterMember member) {
162
 	public Void visitGetter(GetterMember member) {
166
-		addSpacing();
167
-		
168
-		output.append(indent);
169
-		if (isInterface && member.body != null && !(member.body instanceof EmptyStatement))
170
-			output.append("default ");
171
-		
172
-		modifiers(member.modifiers);
173
-		output.append(scope.type(member.type));
174
-		output.append(" ");
175
-		output.append("get").append(StringUtils.capitalize(member.name));
176
-		output.append("()");
177
-		compileBody(member.body, member.header);
163
+		compileMethod(member, member.header, member.body);
178
 		return null;
164
 		return null;
179
 	}
165
 	}
180
 
166
 
181
 	@Override
167
 	@Override
182
 	public Void visitSetter(SetterMember member) {
168
 	public Void visitSetter(SetterMember member) {
183
-		addSpacing();
184
-		
185
-		output.append(indent);
186
-		if (isInterface && member.body != null && !(member.body instanceof EmptyStatement))
187
-			output.append("default ");
188
-		
189
-		modifiers(member.modifiers);
190
-		output.append("void set").append(StringUtils.capitalize(member.name));
191
-		output.append("(");
192
-		output.append(scope.type(member.type));
193
-		output.append(" ");
194
-		output.append("value");
195
-		output.append(")");
196
-		compileBody(member.body, member.header);
169
+		compileMethod(member, new FunctionHeader(BasicTypeID.VOID, new FunctionParameter(member.type, "value")), member.body);
197
 		return null;
170
 		return null;
198
 	}
171
 	}
199
 
172
 
200
 	@Override
173
 	@Override
201
 	public Void visitOperator(OperatorMember member) {
174
 	public Void visitOperator(OperatorMember member) {
202
-		addSpacing();
203
-		JavaSourceMethod method = member.getTag(JavaSourceMethod.class);
204
-		if (method == null)
205
-			throw new IllegalStateException("Missing method tag!");
206
-		
207
-		output.append(indent);
208
-		if (isInterface && member.body != null && !(member.body instanceof EmptyStatement))
209
-			output.append("default ");
210
-		
211
-		modifiers(member.modifiers);
212
-		output.append(scope.type(member.header.returnType));
213
-		output.append(' ');
214
-		output.append(method.name);
215
-		formatParameters(member.header);
216
-		compileBody(member.body, member.header);
175
+		compileMethod(member, member.header, member.body);
217
 		return null;
176
 		return null;
218
 	}
177
 	}
219
 
178
 
220
 	@Override
179
 	@Override
221
 	public Void visitCaster(CasterMember member) {
180
 	public Void visitCaster(CasterMember member) {
222
-		addSpacing();
223
-		
224
-		output.append(indent);
225
-		if (isInterface && member.body != null && !(member.body instanceof EmptyStatement))
226
-			output.append("default ");
227
-		
228
-		modifiers(member.modifiers);
229
-		output.append(scope.type(member.toType));
230
-		output.append(" ");
231
-		output.append("to").append(member.toType.accept(new JavaSourceTypeNameVisitor()));
232
-		output.append("()");
233
-		compileBody(member.body, member.header);
181
+		compileMethod(member, new FunctionHeader(member.toType), member.body);
234
 		return null;
182
 		return null;
235
 	}
183
 	}
236
 
184
 
237
 	@Override
185
 	@Override
238
 	public Void visitCustomIterator(CustomIteratorMember member) {
186
 	public Void visitCustomIterator(CustomIteratorMember member) {
239
-		addSpacing();
240
-		
187
+		compileMethod(member, new FunctionHeader(scope.semanticScope.getTypeRegistry().getIterator(member.getLoopVariableTypes())), member.body);
241
 		return null;
188
 		return null;
242
 	}
189
 	}
243
 
190
 
244
 	@Override
191
 	@Override
245
 	public Void visitCaller(CallerMember member) {
192
 	public Void visitCaller(CallerMember member) {
246
-		addSpacing();
247
-		
193
+		compileMethod(member, member.header, member.body);
248
 		return null;
194
 		return null;
249
 	}
195
 	}
250
 
196
 
251
 	@Override
197
 	@Override
252
 	public Void visitImplementation(ImplementationMember member) {
198
 	public Void visitImplementation(ImplementationMember member) {
199
+		// TODO
253
 		return null;
200
 		return null;
254
 	}
201
 	}
255
 
202
 
256
 	@Override
203
 	@Override
257
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
204
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
205
+		// TODO
258
 		return null;
206
 		return null;
259
 	}
207
 	}
260
 
208
 
261
 	@Override
209
 	@Override
262
 	public Void visitStaticInitializer(StaticInitializerMember member) {
210
 	public Void visitStaticInitializer(StaticInitializerMember member) {
263
-		addSpacing();
211
+		begin(ElementType.STATICINIT);
264
 		output.append(indent).append("static");
212
 		output.append(indent).append("static");
265
 		compileBody(member.body, new FunctionHeader(BasicTypeID.VOID));
213
 		compileBody(member.body, new FunctionHeader(BasicTypeID.VOID));
266
 		return null;
214
 		return null;
275
 				visitSetter(field.autoSetter);
223
 				visitSetter(field.autoSetter);
276
 		}
224
 		}
277
 	}
225
 	}
278
-	
279
-	private void modifiers(int modifiers) {
280
-		if (Modifiers.isPublic(modifiers))
281
-			output.append("public ");
282
-		if (Modifiers.isProtected(modifiers))
283
-			output.append("protected ");
284
-		if (Modifiers.isPrivate(modifiers))
285
-			output.append("private ");
286
-		if (Modifiers.isStatic(modifiers))
287
-			output.append("static ");
288
-		if (Modifiers.isFinal(modifiers))
289
-			output.append("final ");
290
-	}
291
-	
292
-	private void compileBody(Statement body, FunctionHeader header) {
293
-		if (body == null || body instanceof EmptyStatement) {
294
-			output.append(";\n");
295
-		} else {
296
-			if (!(body instanceof BlockStatement))
297
-				body = new BlockStatement(body.position, Collections.singletonList(body));
298
-			
299
-			JavaSourceStatementScope scope = new JavaSourceStatementScope(this.scope, settings, header, indent + settings.indent, null, null, isExpansion);
300
-			body.accept(new JavaSourceStatementCompiler(scope, output, true, false));
301
-			output.append('\n');
302
-		}
303
-	}
304
-	
305
-	private void formatParameters(FunctionHeader header) {
306
-		output.append("(");
307
-		boolean first = true;
308
-		if (header.typeParameters != null) {
309
-			for (TypeParameter typeParameter : header.typeParameters) {
310
-				if (first)
311
-					first = false;
312
-				else
313
-					output.append(", ");
314
-
315
-				output.append("Class<")
316
-						.append(typeParameter.name)
317
-						.append(">")
318
-						.append(" ")
319
-						.append("typeOf")
320
-						.append(typeParameter.name);
321
-			}
322
-		}
323
-		
324
-		for (int i = 0; i < header.parameters.length; i++) {
325
-			if (first)
326
-				first = false;
327
-			else
328
-				output.append(", ");
329
-			
330
-			FunctionParameter parameter = header.parameters[i];
331
-			output.append(scope.type(parameter.type));
332
-			output.append(" ").append(parameter.name);
333
-			if (parameter.variadic)
334
-				output.append("...");
335
-		}
336
-		output.append(")");
337
-	}
338
 }
226
 }

+ 24
- 12
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceCompiler.java View File

10
 import java.util.Map;
10
 import java.util.Map;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
 import org.openzen.zenscript.codemodel.ScriptBlock;
12
 import org.openzen.zenscript.codemodel.ScriptBlock;
13
-import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
14
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
13
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
15
 import org.openzen.zenscript.compiler.CompilationUnit;
14
 import org.openzen.zenscript.compiler.CompilationUnit;
16
 import org.openzen.zenscript.compiler.SemanticModule;
15
 import org.openzen.zenscript.compiler.SemanticModule;
17
 import org.openzen.zenscript.compiler.ZenCodeCompiler;
16
 import org.openzen.zenscript.compiler.ZenCodeCompiler;
17
+import org.openzen.zenscript.javasource.prepare.JavaSourcePrepareDefinitionVisitor;
18
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
18
 import org.openzen.zenscript.shared.SourceFile;
19
 import org.openzen.zenscript.shared.SourceFile;
19
 
20
 
20
 /**
21
 /**
29
 	private final File directory;
30
 	private final File directory;
30
 	private final Map<File, JavaSourceFile> sourceFiles = new HashMap<>();
31
 	private final Map<File, JavaSourceFile> sourceFiles = new HashMap<>();
31
 	
32
 	
33
+	private final Map<String, Integer> classNameCounters = new HashMap<>();
34
+	
32
 	public JavaSourceCompiler(File directory, CompilationUnit compilationUnit) {
35
 	public JavaSourceCompiler(File directory, CompilationUnit compilationUnit) {
33
 		if (!directory.exists())
36
 		if (!directory.exists())
34
 			directory.mkdirs();
37
 			directory.mkdirs();
42
 	
45
 	
43
 	@Override
46
 	@Override
44
 	public void addDefinition(HighLevelDefinition definition, SemanticModule module) {
47
 	public void addDefinition(HighLevelDefinition definition, SemanticModule module) {
45
-		File file = new File(getDirectory(definition.pkg), definition.name + ".java");
46
-		if (definition.name == null || definition instanceof FunctionDefinition) {
47
-			SourceFile source = definition.getTag(SourceFile.class);
48
-			if (source != null) {
49
-				int slash = Math.max(source.filename.lastIndexOf('/'), source.filename.lastIndexOf('\\'));
50
-				String filename = source.filename.substring(slash < 0 ? 0 : slash);
51
-				filename = filename.substring(0, filename.lastIndexOf('.'));
52
-				file = new File(getDirectory(definition.pkg), filename + ".java");
53
-			}
54
-		}
48
+		String filename = getFilename(definition);
49
+		JavaSourcePrepareDefinitionVisitor prepare = new JavaSourcePrepareDefinitionVisitor(filename);
50
+		JavaSourceClass cls = definition.accept(prepare);
51
+		if (cls.empty)
52
+			return;
55
 		
53
 		
54
+		File file = new File(getDirectory(definition.pkg), cls.name + ".java");
55
+		System.out.println("Compiling " + definition.name + " as " + cls.fullName);
56
 		JavaSourceFile sourceFile = sourceFiles.get(file);
56
 		JavaSourceFile sourceFile = sourceFiles.get(file);
57
 		if (sourceFile == null)
57
 		if (sourceFile == null)
58
-			sourceFiles.put(file, sourceFile = new JavaSourceFile(this, file, definition.pkg));
58
+			sourceFiles.put(file, sourceFile = new JavaSourceFile(this, file, cls, definition.pkg));
59
 		
59
 		
60
 		sourceFile.add(definition, module);
60
 		sourceFile.add(definition, module);
61
 	}
61
 	}
89
 		File base = getDirectory(pkg.parent);
89
 		File base = getDirectory(pkg.parent);
90
 		return new File(base, pkg.name.replace('.', '/'));
90
 		return new File(base, pkg.name.replace('.', '/'));
91
 	}
91
 	}
92
+	
93
+	private String getFilename(HighLevelDefinition definition) {
94
+		SourceFile source = definition.getTag(SourceFile.class);
95
+		if (source != null) {
96
+			int slash = Math.max(source.filename.lastIndexOf('/'), source.filename.lastIndexOf('\\'));
97
+			String filename = source.filename.substring(slash < 0 ? 0 : slash + 1);
98
+			filename = filename.substring(0, filename.lastIndexOf('.'));
99
+			return filename;
100
+		} else {
101
+			return definition.name == null ? "Expansion" : definition.name;
102
+		}
103
+	}
92
 }
104
 }

+ 108
- 50
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceExpressionFormatter.java View File

80
 import org.openzen.zenscript.codemodel.type.ArrayTypeID;
80
 import org.openzen.zenscript.codemodel.type.ArrayTypeID;
81
 import org.openzen.zenscript.codemodel.type.AssocTypeID;
81
 import org.openzen.zenscript.codemodel.type.AssocTypeID;
82
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
82
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
83
+import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
83
 import org.openzen.zenscript.codemodel.type.GenericTypeID;
84
 import org.openzen.zenscript.codemodel.type.GenericTypeID;
84
 import org.openzen.zenscript.codemodel.type.ITypeID;
85
 import org.openzen.zenscript.codemodel.type.ITypeID;
85
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
86
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
100
  * @author Hoofdgebruiker
101
  * @author Hoofdgebruiker
101
  */
102
  */
102
 public class JavaSourceExpressionFormatter implements ExpressionVisitor<ExpressionString> {
103
 public class JavaSourceExpressionFormatter implements ExpressionVisitor<ExpressionString> {
103
-	private final JavaSourceStatementScope scope;
104
-	private final StatementFormattingTarget target;
104
+	private static final JavaSourceClass RESULT = new JavaSourceClass("stdlib", "Result");
105
+	private static final JavaSourceClass RESULT_OK = new JavaSourceClass("stdlib", "Result.Ok");
106
+	private static final JavaSourceClass RESULT_ERROR = new JavaSourceClass("stdlib", "Result.Error");
107
+	
108
+	public final JavaSourceStatementScope scope;
109
+	public final StatementFormattingTarget target;
105
 	
110
 	
106
 	public JavaSourceExpressionFormatter(StatementFormattingTarget target, JavaSourceStatementScope scope) {
111
 	public JavaSourceExpressionFormatter(StatementFormattingTarget target, JavaSourceStatementScope scope) {
107
 		this.target = target;
112
 		this.target = target;
168
 		switch (method.kind) {
173
 		switch (method.kind) {
169
 			case EXPANSION: {
174
 			case EXPANSION: {
170
 				StringBuilder output = new StringBuilder();
175
 				StringBuilder output = new StringBuilder();
171
-				output.append(scope.sourceClass(method.cls));
176
+				output.append(scope.type(method.cls));
172
 				output.append('.');
177
 				output.append('.');
173
 				output.append(method.name);
178
 				output.append(method.name);
174
 				FormattingUtils.formatExpansionCall(output, this.target, scope, target.accept(this), arguments);
179
 				FormattingUtils.formatExpansionCall(output, this.target, scope, target.accept(this), arguments);
197
 			throw new IllegalStateException("No source method tag for " + expression.member.getCanonicalName() + "!");
202
 			throw new IllegalStateException("No source method tag for " + expression.member.getCanonicalName() + "!");
198
 		
203
 		
199
 		StringBuilder result = new StringBuilder();
204
 		StringBuilder result = new StringBuilder();
200
-		result.append(scope.sourceClass(method.cls));
205
+		result.append(scope.type(method.cls));
201
 		result.append('.');
206
 		result.append('.');
202
 		result.append(method.name);
207
 		result.append(method.name);
203
 		FormattingUtils.formatCall(result, target, scope, expression.arguments);
208
 		FormattingUtils.formatCall(result, target, scope, expression.arguments);
488
 		if (expression.constructor.getBuiltin() != null)
493
 		if (expression.constructor.getBuiltin() != null)
489
 			return visitBuiltinConstructor(expression);
494
 			return visitBuiltinConstructor(expression);
490
 		
495
 		
491
-		StringBuilder result = new StringBuilder();
492
-		result.append("new ");
493
-		result.append(scope.type(expression.type));
494
-		FormattingUtils.formatCall(result, target, scope, expression.arguments);
495
-		return new ExpressionString(result.toString(), JavaOperator.PRIMARY);
496
+		JavaSourceMethod method = expression.constructor.getTag(JavaSourceMethod.class);
497
+		switch (method.kind) {
498
+			case EXPANSION: {
499
+				StringBuilder output = new StringBuilder();
500
+				output.append(scope.type(method.cls));
501
+				output.append('.');
502
+				output.append(method.name);
503
+				FormattingUtils.formatCall(output, this.target, scope, expression.arguments);
504
+				return new ExpressionString(output.toString(), JavaOperator.CALL);
505
+			}
506
+			case CONSTRUCTOR: {
507
+				StringBuilder output = new StringBuilder();
508
+				output.append("new ");
509
+				output.append(scope.type(expression.type, method.cls));
510
+				FormattingUtils.formatCall(output, this.target, scope, expression.arguments);
511
+				return new ExpressionString(output.toString(), JavaOperator.PRIMARY);
512
+			}
513
+			default:
514
+				throw new IllegalStateException("Invalid method call kind: " + method.kind);
515
+		}
496
 	}
516
 	}
497
 
517
 
498
 	@Override
518
 	@Override
559
 		JavaSourceField field = expression.field.getTag(JavaSourceField.class);
579
 		JavaSourceField field = expression.field.getTag(JavaSourceField.class);
560
 		if (field == null)
580
 		if (field == null)
561
 			throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Missing field tag");
581
 			throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Missing field tag");
562
-		
563
-		return new ExpressionString(
564
-				scope.type(field.cls) + "." + field.name + " = " + expression.value.accept(this).value,
565
-				JavaOperator.ASSIGN);
582
+		if (field.cls.fullName.equals(scope.fileScope.cls.fullName) && !scope.hasLocalVariable(field.name)) {
583
+			return new ExpressionString(
584
+					field.name + " = " + expression.value.accept(this).value,
585
+					JavaOperator.ASSIGN);
586
+		} else {
587
+			return new ExpressionString(
588
+					scope.type(field.cls) + "." + field.name + " = " + expression.value.accept(this).value,
589
+					JavaOperator.ASSIGN);
590
+		}
566
 	}
591
 	}
567
 
592
 
568
 	@Override
593
 	@Override
613
 
638
 
614
 	@Override
639
 	@Override
615
 	public ExpressionString visitTryRethrowAsException(TryRethrowAsExceptionExpression expression) {
640
 	public ExpressionString visitTryRethrowAsException(TryRethrowAsExceptionExpression expression) {
641
+		DefinitionTypeID type = (DefinitionTypeID) expression.value.type;
642
+		
643
+		String errorType = scope.fileScope.importer.importType(RESULT_ERROR);
644
+		String okType = scope.fileScope.importer.importType(RESULT_OK);
645
+		
616
 		ExpressionString value = hoist(expression.value).accept(this);
646
 		ExpressionString value = hoist(expression.value).accept(this);
617
-		target.writeLine("if (" + value.value + " instanceof " + scope.fileScope.importer.importType("stdlib.Result.Error") + ")");
618
-		target.writeLine(scope.settings.indent + "throw (" + scope.fileScope.importer.importType("stdlib.Result.Error") + ")" + value.value + ".value;");
647
+		target.writeLine("if (" + value.value + " instanceof " + errorType + ")");
648
+		target.writeLine(scope.settings.indent + "throw ((" + errorType + formatTypeArguments(type.typeParameters) + ")" + value.value + ").value;");
619
 		
649
 		
620
 		return value
650
 		return value
621
-				.unaryPrefix(JavaOperator.CAST, "(" + scope.fileScope.importer.importType("stdlib.Result.Ok") + ")")
651
+				.unaryPrefix(JavaOperator.CAST, "(" + okType + formatTypeArguments(type.typeParameters) + ")")
622
 				.unaryPostfix(JavaOperator.MEMBER, ".value");
652
 				.unaryPostfix(JavaOperator.MEMBER, ".value");
623
 	}
653
 	}
624
 
654
 
625
 	@Override
655
 	@Override
626
 	public ExpressionString visitTryRethrowAsResult(TryRethrowAsResultExpression expression) {
656
 	public ExpressionString visitTryRethrowAsResult(TryRethrowAsResultExpression expression) {
657
+		DefinitionTypeID type = (DefinitionTypeID) expression.value.type;
658
+		
659
+		String errorType = scope.fileScope.importer.importType(RESULT_ERROR);
660
+		String okType = scope.fileScope.importer.importType(RESULT_OK);
661
+		
627
 		ExpressionString value = hoist(expression.value).accept(this);
662
 		ExpressionString value = hoist(expression.value).accept(this);
628
-		target.writeLine("if (" + value.value + " instanceof " + scope.fileScope.importer.importType("stdlib.Result.Error") + ")");
629
-		target.writeLine(scope.settings.indent + "return new " + scope.fileScope.importer.importType("stdlib.Result.Error") + "<>((" + scope.fileScope.importer.importType("stdlib.Result.Error") + ")" + value.value + ".value);");
663
+		target.writeLine("if (" + value.value + " instanceof " + errorType + ")");
664
+		target.writeLine(scope.settings.indent + "return new " + errorType + "<>(((" + errorType + formatTypeArguments(type.typeParameters) + ")" + value.value + ").value);");
630
 		
665
 		
631
 		return value
666
 		return value
632
-				.unaryPrefix(JavaOperator.CAST, "(" + scope.fileScope.importer.importType("stdlib.Result.Ok") + ")")
667
+				.unaryPrefix(JavaOperator.CAST, "(" + okType + formatTypeArguments(type.typeParameters) + ")")
633
 				.unaryPostfix(JavaOperator.MEMBER, ".value");
668
 				.unaryPostfix(JavaOperator.MEMBER, ".value");
634
 	}
669
 	}
635
 	
670
 	
648
 		return expression.value.accept(this);
683
 		return expression.value.accept(this);
649
 	}
684
 	}
650
 	
685
 	
686
+	private String formatTypeArguments(ITypeID[] types) {
687
+		if (types == null || types.length == 0)
688
+			return "";
689
+		
690
+		StringBuilder output = new StringBuilder();
691
+		output.append("<");
692
+		
693
+		for (int i = 0; i < types.length; i++) {
694
+			if (i > 0)
695
+				output.append(", ");
696
+			
697
+			output.append(types[i].accept(scope.fileScope.objectTypeVisitor));
698
+		}
699
+		output.append(">");
700
+		return output.toString();
701
+	}
702
+	
703
+	public ExpressionString newArray(ITypeID elementType, ExpressionString length) {
704
+		if (elementType instanceof GenericTypeID) {
705
+			// generic array creation
706
+			GenericTypeID generic = (GenericTypeID)elementType;
707
+			String array = scope.type(new JavaSourceClass("java.lang.reflect", "Array"));
708
+			return new ExpressionString("(" + generic.parameter.name + "[])(" + array + ".newInstance(typeOf" + generic.parameter.name + ", " + length.value + "))", JavaOperator.CAST);
709
+		} else {
710
+			return new ExpressionString("new " + scope.type(elementType) + "[" + length.value + "]", JavaOperator.NEW);
711
+		}
712
+	}
713
+	
651
 	public ExpressionString listToArray(CastExpression expression) {
714
 	public ExpressionString listToArray(CastExpression expression) {
652
 		Expression target = duplicable(expression.target);
715
 		Expression target = duplicable(expression.target);
653
 		ExpressionString targetString = target.accept(this);
716
 		ExpressionString targetString = target.accept(this);
654
 		ArrayTypeID resultType = (ArrayTypeID)expression.type;
717
 		ArrayTypeID resultType = (ArrayTypeID)expression.type;
655
 		return new ExpressionString(
718
 		return new ExpressionString(
656
-				targetString.value + ".toArray(new " + scope.type(resultType.elementType) + "[" + targetString.value + ".size()])",
719
+				targetString.value + ".toArray(" + newArray(resultType.elementType, targetString.unaryPostfix(JavaOperator.CALL, ".size()")).value + ")",
657
 				JavaOperator.CALL);
720
 				JavaOperator.CALL);
658
 	}
721
 	}
659
 	
722
 	
829
 		return cast.isImplicit ? cast.target.accept(this) : cast(cast, type);
892
 		return cast.isImplicit ? cast.target.accept(this) : cast(cast, type);
830
 	}
893
 	}
831
 	
894
 	
832
-	private Expression duplicable(Expression expression) {
895
+	public Expression duplicable(Expression expression) {
833
 		boolean shouldHoist = expression.accept(ExpressionHoistingChecker.INSTANCE);
896
 		boolean shouldHoist = expression.accept(ExpressionHoistingChecker.INSTANCE);
834
 		if (!shouldHoist)
897
 		if (!shouldHoist)
835
 			return expression;
898
 			return expression;
843
 		return new GetLocalVariableExpression(value.position, temp);
906
 		return new GetLocalVariableExpression(value.position, temp);
844
 	}
907
 	}
845
 	
908
 	
846
-	private ExpressionString hoist(ExpressionString value, String type) {
909
+	public ExpressionString hoist(ExpressionString value, String type) {
847
 		String temp = scope.createTempVariable();
910
 		String temp = scope.createTempVariable();
848
 		target.writeLine(type + " " + temp + " = " + value.value + ";");
911
 		target.writeLine(type + " " + temp + " = " + value.value + ";");
849
 		return new ExpressionString(temp, JavaOperator.PRIMARY);
912
 		return new ExpressionString(temp, JavaOperator.PRIMARY);
1014
 			case GENERICMAP_GETOPTIONAL: return call("get", call).unaryPrefix(JavaOperator.CAST, "(" + scope.type(call.type) + ")");
1077
 			case GENERICMAP_GETOPTIONAL: return call("get", call).unaryPrefix(JavaOperator.CAST, "(" + scope.type(call.type) + ")");
1015
 			case GENERICMAP_PUT: return call("put", call);
1078
 			case GENERICMAP_PUT: return call("put", call);
1016
 			case GENERICMAP_CONTAINS: return call("containsKey", call);
1079
 			case GENERICMAP_CONTAINS: return call("containsKey", call);
1080
+			case GENERICMAP_ADDALL: return call("putAll", call);
1017
 			case GENERICMAP_EQUALS: throw new UnsupportedOperationException("Not yet supported!");
1081
 			case GENERICMAP_EQUALS: throw new UnsupportedOperationException("Not yet supported!");
1018
 			case GENERICMAP_NOTEQUALS: throw new UnsupportedOperationException("Not yet supported!");
1082
 			case GENERICMAP_NOTEQUALS: throw new UnsupportedOperationException("Not yet supported!");
1019
 			case GENERICMAP_SAME: return binary(call, JavaOperator.EQUALS);
1083
 			case GENERICMAP_SAME: return binary(call, JavaOperator.EQUALS);
1038
 			}
1102
 			}
1039
 			case ARRAY_CONTAINS: {
1103
 			case ARRAY_CONTAINS: {
1040
 				JavaSourceMethod method = scope.fileScope.helperGenerator.createArrayContains((ArrayTypeID)call.target.type);
1104
 				JavaSourceMethod method = scope.fileScope.helperGenerator.createArrayContains((ArrayTypeID)call.target.type);
1041
-				return callAsStatic(scope.fileScope.importer.importType(method.cls.fullName) + '.' + method.name, call);
1105
+				return callAsStatic(scope.fileScope.importer.importType(method.cls) + '.' + method.name, call);
1042
 			}
1106
 			}
1043
 			case ARRAY_EQUALS: return callAsStatic("Arrays.equals", call);
1107
 			case ARRAY_EQUALS: return callAsStatic("Arrays.equals", call);
1044
 			case ARRAY_NOTEQUALS: return callAsStatic("!Arrays.equals", call);
1108
 			case ARRAY_NOTEQUALS: return callAsStatic("!Arrays.equals", call);
1062
 			case FUNCTION_NOTSAME: return binary(call, JavaOperator.NOTEQUALS);
1126
 			case FUNCTION_NOTSAME: return binary(call, JavaOperator.NOTEQUALS);
1063
 			case OBJECT_SAME: return binary(call, JavaOperator.EQUALS);
1127
 			case OBJECT_SAME: return binary(call, JavaOperator.EQUALS);
1064
 			case OBJECT_NOTSAME: return binary(call, JavaOperator.NOTEQUALS);
1128
 			case OBJECT_NOTSAME: return binary(call, JavaOperator.NOTEQUALS);
1129
+			case OPTIONAL_IS_NULL: return call.target.accept(this).unaryPostfix(JavaOperator.EQUALS, " == null");
1130
+			case OPTIONAL_IS_NOT_NULL: return call.target.accept(this).unaryPostfix(JavaOperator.NOTEQUALS, " != null");
1065
 			case AUTOOP_NOTEQUALS:
1131
 			case AUTOOP_NOTEQUALS:
1066
 				throw new UnsupportedOperationException("Not yet supported!");
1132
 				throw new UnsupportedOperationException("Not yet supported!");
1067
 		}
1133
 		}
1377
 			case STRING_CONSTRUCTOR_CHARACTERS:
1443
 			case STRING_CONSTRUCTOR_CHARACTERS:
1378
 				return callStatic("new String", expression.arguments.arguments[0]);
1444
 				return callStatic("new String", expression.arguments.arguments[0]);
1379
 			case ASSOC_CONSTRUCTOR: {
1445
 			case ASSOC_CONSTRUCTOR: {
1380
-				String typeName = scope.type(new JavaSourceClass("HashMap", "java.util.HashMap"));
1446
+				String typeName = scope.type(new JavaSourceClass("java.util", "HashMap"));
1381
 				AssocTypeID type = (AssocTypeID) expression.type;
1447
 				AssocTypeID type = (AssocTypeID) expression.type;
1382
 				
1448
 				
1383
 				StringBuilder result = new StringBuilder();
1449
 				StringBuilder result = new StringBuilder();
1384
 				result.append("new ").append(typeName).append("<");
1450
 				result.append("new ").append(typeName).append("<");
1385
-				result.append(scope.type(type.keyType));
1386
-				result.append(", ");
1387
-				result.append(scope.type(type.valueType));
1451
+				//result.append(scope.type(type.keyType));
1452
+				//result.append(", ");
1453
+				//result.append(scope.type(type.valueType));
1388
 				result.append(">()");
1454
 				result.append(">()");
1389
 				return new ExpressionString(result.toString(), JavaOperator.NEW);
1455
 				return new ExpressionString(result.toString(), JavaOperator.NEW);
1390
 			}
1456
 			}
1391
 			case GENERICMAP_CONSTRUCTOR: {
1457
 			case GENERICMAP_CONSTRUCTOR: {
1392
-				String typeName = scope.type(new JavaSourceClass("HashMap", "java.util.HashMap"));
1458
+				String typeName = scope.type(new JavaSourceClass("java.util", "HashMap"));
1393
 				StringBuilder result = new StringBuilder();
1459
 				StringBuilder result = new StringBuilder();
1394
 				result.append("new ").append(typeName).append("<Class<?>, Object>()");
1460
 				result.append("new ").append(typeName).append("<Class<?>, Object>()");
1395
 				return new ExpressionString(result.toString(), JavaOperator.NEW);
1461
 				return new ExpressionString(result.toString(), JavaOperator.NEW);
1398
 				ArrayTypeID type = (ArrayTypeID) expression.type;
1464
 				ArrayTypeID type = (ArrayTypeID) expression.type;
1399
 				if (type.dimension == 1) {
1465
 				if (type.dimension == 1) {
1400
 					ExpressionString size = expression.arguments.arguments[0].accept(this);
1466
 					ExpressionString size = expression.arguments.arguments[0].accept(this);
1401
-					String typeName = scope.type(type.elementType);
1402
-					return new ExpressionString("new " + typeName + "[" + size.value + "]", JavaOperator.NEW);
1467
+					return newArray(type.elementType, size);
1403
 				} else {
1468
 				} else {
1404
 					// TODO: implement
1469
 					// TODO: implement
1405
 					throw new UnsupportedOperationException("Not yet supported!");
1470
 					throw new UnsupportedOperationException("Not yet supported!");
1418
 							.append(' ')
1483
 							.append(' ')
1419
 							.append(temp)
1484
 							.append(temp)
1420
 							.append(" = ")
1485
 							.append(" = ")
1421
-							.append(" new ")
1422
-							.append(scope.type(type.elementType))
1423
-							.append("[")
1424
-							.append(size.value)
1425
-							.append("];")
1486
+							.append(newArray(type.elementType, size).value)
1487
+							.append(";")
1426
 							.toString());
1488
 							.toString());
1427
 					target.writeLine(new StringBuilder()
1489
 					target.writeLine(new StringBuilder()
1428
 							.append("for (int ")
1490
 							.append("for (int ")
1465
 								.append(scope.type(type))
1527
 								.append(scope.type(type))
1466
 								.append(' ')
1528
 								.append(' ')
1467
 								.append(temp)
1529
 								.append(temp)
1468
-								.append(" = new ")
1469
-								.append(scope.type(type.elementType))
1470
-								.append("[")
1471
-								.append(size.value)
1472
-								.append("];")
1530
+								.append(" = ")
1531
+								.append(newArray(type.elementType, size))
1532
+								.append(";")
1473
 								.toString());
1533
 								.toString());
1474
 					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT, null, true);
1534
 					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT, null, true);
1475
 					target.writeLine(new StringBuilder()
1535
 					target.writeLine(new StringBuilder()
1537
 							.append(scope.type(type))
1597
 							.append(scope.type(type))
1538
 							.append(' ')
1598
 							.append(' ')
1539
 							.append(temp)
1599
 							.append(temp)
1540
-							.append(" = new ")
1541
-							.append(scope.type(type.elementType))
1542
-							.append("[")
1543
-							.append(originalString.value)
1544
-							.append(".length];")
1600
+							.append(" = ")
1601
+							.append(newArray(type.elementType, originalString.unaryPostfix(JavaOperator.MEMBER, ".length")))
1602
+							.append(";")
1545
 							.toString());
1603
 							.toString());
1546
 					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT, null, true);
1604
 					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT, null, true);
1547
 					target.writeLine(new StringBuilder()
1605
 					target.writeLine(new StringBuilder()
1615
 							.append(scope.type(type))
1673
 							.append(scope.type(type))
1616
 							.append(' ')
1674
 							.append(' ')
1617
 							.append(temp)
1675
 							.append(temp)
1618
-							.append(" = new ")
1619
-							.append(scope.type(type.elementType))
1620
-							.append("[")
1621
-							.append(originalString.value)
1622
-							.append(".length];")
1676
+							.append(" = ")
1677
+							.append(newArray(type.elementType, originalString.unaryPostfix(JavaOperator.MEMBER, ".length")))
1678
+							.append(";")
1623
 							.toString());
1679
 							.toString());
1624
 					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT, null, true);
1680
 					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT, null, true);
1625
 					target.writeLine(new StringBuilder()
1681
 					target.writeLine(new StringBuilder()
1666
 								.append("] = ")
1722
 								.append("] = ")
1667
 								.append(lambdaString.value)
1723
 								.append(lambdaString.value)
1668
 								.append(".invoke(")
1724
 								.append(".invoke(")
1725
+								.append(tempI.name)
1726
+								.append(", ")
1669
 								.append(originalString.value)
1727
 								.append(originalString.value)
1670
 								.append("[")
1728
 								.append("[")
1671
 								.append(tempI.name)
1729
 								.append(tempI.name)

+ 38
- 30
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceFile.java View File

12
 import java.io.OutputStreamWriter;
12
 import java.io.OutputStreamWriter;
13
 import java.io.Writer;
13
 import java.io.Writer;
14
 import java.nio.charset.StandardCharsets;
14
 import java.nio.charset.StandardCharsets;
15
+import java.util.ArrayList;
15
 import java.util.HashMap;
16
 import java.util.HashMap;
16
 import java.util.HashSet;
17
 import java.util.HashSet;
18
+import java.util.List;
17
 import java.util.Map;
19
 import java.util.Map;
18
 import java.util.Set;
20
 import java.util.Set;
19
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
21
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
20
-import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
22
+import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
21
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
23
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
22
-import org.openzen.zenscript.compiler.CompileScope;
23
 import org.openzen.zenscript.compiler.SemanticModule;
24
 import org.openzen.zenscript.compiler.SemanticModule;
24
-import org.openzen.zenscript.javasource.prepare.JavaSourcePrepareDefinitionVisitor;
25
-import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
25
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
26
 
26
 
27
 /**
27
 /**
28
  *
28
  *
29
  * @author Hoofdgebruiker
29
  * @author Hoofdgebruiker
30
  */
30
  */
31
 public class JavaSourceFile {
31
 public class JavaSourceFile {
32
-	private final JavaSourceImporter importer;
32
+	public final JavaSourceImporter importer;
33
 	private final JavaSourceCompiler compiler;
33
 	private final JavaSourceCompiler compiler;
34
 	private final File file;
34
 	private final File file;
35
+	private final JavaSourceClass cls;
35
 	private final StringBuilder contents = new StringBuilder();
36
 	private final StringBuilder contents = new StringBuilder();
36
 	private final ZSPackage pkg;
37
 	private final ZSPackage pkg;
37
 	
38
 	
38
-	private final Map<HighLevelDefinition, SemanticModule> definitions = new HashMap<>();
39
+	private HighLevelDefinition mainDefinition;
40
+	private final List<ExpansionDefinition> expansions = new ArrayList<>();
41
+	
42
+	private final Map<HighLevelDefinition, SemanticModule> modules = new HashMap<>();
39
 	private final Set<String> existing = new HashSet<>();
43
 	private final Set<String> existing = new HashSet<>();
40
 	
44
 	
41
-	public JavaSourceFile(JavaSourceCompiler compiler, File file, ZSPackage pkg) {
45
+	public JavaSourceFile(JavaSourceCompiler compiler, File file, JavaSourceClass cls, ZSPackage pkg) {
42
 		this.compiler = compiler;
46
 		this.compiler = compiler;
43
 		this.pkg = pkg;
47
 		this.pkg = pkg;
48
+		this.cls = cls;
44
 		this.file = file;
49
 		this.file = file;
45
 		
50
 		
46
-		importer = new JavaSourceImporter(pkg);
51
+		importer = new JavaSourceImporter(cls);
47
 	}
52
 	}
48
 	
53
 	
49
 	public String getName() {
54
 	public String getName() {
50
-		return file.getName().substring(0, file.getName().lastIndexOf('.'));
55
+		return cls.name;
51
 	}
56
 	}
52
 	
57
 	
53
 	public void add(HighLevelDefinition definition, SemanticModule module) {
58
 	public void add(HighLevelDefinition definition, SemanticModule module) {
54
-		if (existing.contains(definition.name))
55
-			throw new IllegalStateException("Duplicate " + definition.name);
56
-		
57
-		System.out.println("adding " + definition.name + " to " + file.getName());
59
+		if (definition instanceof ExpansionDefinition) {
60
+			expansions.add((ExpansionDefinition)definition);
61
+		} else if (mainDefinition != null) {
62
+			throw new IllegalStateException("Multiple main definitions!");
63
+		} else {
64
+			mainDefinition = definition;
65
+		}
58
 		
66
 		
59
-		JavaSourcePrepareDefinitionVisitor prepare = new JavaSourcePrepareDefinitionVisitor(this);
60
-		definition.accept(prepare);
61
-		definitions.put(definition, module);
67
+		modules.put(definition, module);
62
 	}
68
 	}
63
 	
69
 	
64
 	public void write() {
70
 	public void write() {
65
 		System.out.println("Calling write on " + file.getName());
71
 		System.out.println("Calling write on " + file.getName());
66
 		
72
 		
67
-		for (Map.Entry<HighLevelDefinition, SemanticModule> entry : definitions.entrySet()) {
68
-			HighLevelDefinition definition = entry.getKey();
69
-			SemanticModule module = entry.getValue();
70
-			CompileScope scope = new CompileScope(definition.access, module.compilationUnit.globalTypeRegistry, module.expansions, module.annotations);
71
-			JavaDefinitionVisitor visitor = new JavaDefinitionVisitor(
72
-					compiler.settings,
73
-					new JavaSourceFileScope(importer, compiler.typeGenerator, compiler.helperGenerator, getName(), scope, definition instanceof InterfaceDefinition),
74
-					contents);
75
-			definition.accept(visitor);
76
-		}
73
+		if (mainDefinition == null)
74
+			mainDefinition = expansions.remove(0);
75
+		
76
+		HighLevelDefinition definition = mainDefinition;
77
+		JavaDefinitionVisitor visitor = new JavaDefinitionVisitor(
78
+				compiler,
79
+				cls,
80
+				this,
81
+				contents,
82
+				expansions,
83
+				modules);
84
+		definition.accept(visitor);
77
 		
85
 		
78
 		if (!file.getParentFile().exists())
86
 		if (!file.getParentFile().exists())
79
 			file.getParentFile().mkdirs();
87
 			file.getParentFile().mkdirs();
83
 			writer.write(pkg.fullName);
91
 			writer.write(pkg.fullName);
84
 			writer.write(";\n\n");
92
 			writer.write(";\n\n");
85
 			
93
 			
86
-			JavaSourceImporter.Import[] imports = importer.getUsedImports();
94
+			JavaSourceClass[] imports = importer.getUsedImports();
87
 			if (imports.length > 0) {
95
 			if (imports.length > 0) {
88
-				for (JavaSourceImporter.Import import_ : imports) {
89
-					if (import_.actualName.startsWith("java.lang."))
96
+				for (JavaSourceClass import_ : imports) {
97
+					if (import_.pkg.equals("java.lang"))
90
 						continue;
98
 						continue;
91
 					
99
 					
92
 					writer.write("import ");
100
 					writer.write("import ");
93
-					writer.write(import_.actualName);
101
+					writer.write(import_.fullName);
94
 					writer.write(";\n");
102
 					writer.write(";\n");
95
 				}
103
 				}
96
 
104
 

+ 21
- 39
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceImporter.java View File

11
 import java.util.Map;
11
 import java.util.Map;
12
 import java.util.Set;
12
 import java.util.Set;
13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
14
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
14
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
15
 
15
 
16
 /**
16
 /**
17
  *
17
  *
18
  * @author Hoofdgebruiker
18
  * @author Hoofdgebruiker
19
  */
19
  */
20
 public class JavaSourceImporter {
20
 public class JavaSourceImporter {
21
-	private final ZSPackage pkg;
22
-	private final Map<String, Import> imports = new HashMap<>();
23
-	private final Set<Import> usedImports = new HashSet<>();
21
+	private final JavaSourceClass cls;
22
+	private final Map<String, JavaSourceClass> imports = new HashMap<>();
23
+	private final Set<JavaSourceClass> usedImports = new HashSet<>();
24
 	
24
 	
25
-	public JavaSourceImporter(ZSPackage pkg) {
26
-		this.pkg = pkg;
27
-		
28
-		imports.put("IllegalArgumentException", new Import("IllegalArgumentException", "stdlib.IllegalArgumentException", "java.lang.IllegalArgumentException"));
29
-		imports.put("StringBuilder", new Import("StringBuilder", "stdlib.StringBuilder", "java.lang.StringBuilder"));
25
+	public JavaSourceImporter(JavaSourceClass cls) {
26
+		this.cls = cls;
30
 	}
27
 	}
31
 	
28
 	
32
 	public String importType(HighLevelDefinition definition) {
29
 	public String importType(HighLevelDefinition definition) {
33
-		if (definition.pkg == pkg)
34
-			return definition.name;
30
+		JavaSourceClass cls = definition.getTag(JavaSourceClass.class);
31
+		if (cls == null)
32
+			throw new IllegalStateException("Missing source class tag on " + definition.name);
33
+		if (cls.pkg.equals(this.cls.pkg))
34
+			return cls.name;
35
 		
35
 		
36
-		return importType(definition.pkg.fullName + "." + definition.name);
36
+		return importType(cls);
37
 	}
37
 	}
38
 	
38
 	
39
-	public String importType(String fullName) {
40
-		String name = fullName.substring(fullName.lastIndexOf('.') + 1);
41
-		if (imports.containsKey(name)) {
42
-			Import imported = imports.get(name);
39
+	public String importType(JavaSourceClass cls) {
40
+		if (imports.containsKey(cls.name)) {
41
+			JavaSourceClass imported = imports.get(cls.name);
43
 			usedImports.add(imported);
42
 			usedImports.add(imported);
44
-			return imported.originalName.equals(fullName) ? name : fullName;
43
+			return imported.fullName.equals(cls.fullName) ? cls.name : cls.fullName;
45
 		}
44
 		}
46
 		
45
 		
47
-		Import imported = new Import(name, fullName, fullName);
48
-		imports.put(name, imported);
49
-		return name;
46
+		imports.put(cls.name, cls);
47
+		usedImports.add(cls);
48
+		return cls.name;
50
 	}
49
 	}
51
 	
50
 	
52
-	public Import[] getUsedImports() {
53
-		Import[] imports = usedImports.toArray(new Import[usedImports.size()]);
51
+	public JavaSourceClass[] getUsedImports() {
52
+		JavaSourceClass[] imports = usedImports.toArray(new JavaSourceClass[usedImports.size()]);
54
 		Arrays.sort(imports);
53
 		Arrays.sort(imports);
55
 		return imports;
54
 		return imports;
56
 	}
55
 	}
57
-	
58
-	public static class Import implements Comparable<Import> {
59
-		public final String name;
60
-		public final String originalName;
61
-		public final String actualName;
62
-		
63
-		public Import(String name, String originalName, String actualName) {
64
-			this.name = name;
65
-			this.originalName = originalName;
66
-			this.actualName = actualName;
67
-		}
68
-
69
-		@Override
70
-		public int compareTo(Import o) {
71
-			return actualName.compareTo(o.actualName);
72
-		}
73
-	}
74
 }
56
 }

+ 44
- 36
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceStatementFormatter.java View File

9
 import java.util.Collections;
9
 import java.util.Collections;
10
 import java.util.List;
10
 import java.util.List;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
12
-import org.openzen.zenscript.codemodel.OperatorType;
13
-import org.openzen.zenscript.codemodel.expression.CallArguments;
14
 import org.openzen.zenscript.codemodel.expression.Expression;
12
 import org.openzen.zenscript.codemodel.expression.Expression;
15
-import org.openzen.zenscript.codemodel.expression.GetLocalVariableExpression;
16
 import org.openzen.zenscript.codemodel.expression.RangeExpression;
13
 import org.openzen.zenscript.codemodel.expression.RangeExpression;
17
-import org.openzen.zenscript.codemodel.expression.SetLocalVariableExpression;
18
 import org.openzen.zenscript.codemodel.expression.switchvalue.CharSwitchValue;
14
 import org.openzen.zenscript.codemodel.expression.switchvalue.CharSwitchValue;
19
 import org.openzen.zenscript.codemodel.expression.switchvalue.EnumConstantSwitchValue;
15
 import org.openzen.zenscript.codemodel.expression.switchvalue.EnumConstantSwitchValue;
20
 import org.openzen.zenscript.codemodel.expression.switchvalue.IntSwitchValue;
16
 import org.openzen.zenscript.codemodel.expression.switchvalue.IntSwitchValue;
32
 import org.openzen.zenscript.codemodel.statement.ForeachStatement;
28
 import org.openzen.zenscript.codemodel.statement.ForeachStatement;
33
 import org.openzen.zenscript.codemodel.statement.IfStatement;
29
 import org.openzen.zenscript.codemodel.statement.IfStatement;
34
 import org.openzen.zenscript.codemodel.statement.LockStatement;
30
 import org.openzen.zenscript.codemodel.statement.LockStatement;
31
+import org.openzen.zenscript.codemodel.statement.LoopStatement;
35
 import org.openzen.zenscript.codemodel.statement.ReturnStatement;
32
 import org.openzen.zenscript.codemodel.statement.ReturnStatement;
36
-import org.openzen.zenscript.codemodel.statement.Statement;
37
 import org.openzen.zenscript.codemodel.statement.SwitchCase;
33
 import org.openzen.zenscript.codemodel.statement.SwitchCase;
38
 import org.openzen.zenscript.codemodel.statement.SwitchStatement;
34
 import org.openzen.zenscript.codemodel.statement.SwitchStatement;
39
 import org.openzen.zenscript.codemodel.statement.ThrowStatement;
35
 import org.openzen.zenscript.codemodel.statement.ThrowStatement;
41
 import org.openzen.zenscript.codemodel.statement.VarStatement;
37
 import org.openzen.zenscript.codemodel.statement.VarStatement;
42
 import org.openzen.zenscript.codemodel.statement.WhileStatement;
38
 import org.openzen.zenscript.codemodel.statement.WhileStatement;
43
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
39
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
44
-import org.openzen.zenscript.codemodel.type.member.TypeMembers;
45
 import org.openzen.zenscript.formattershared.ExpressionString;
40
 import org.openzen.zenscript.formattershared.ExpressionString;
46
 import org.openzen.zenscript.formattershared.StatementFormatter;
41
 import org.openzen.zenscript.formattershared.StatementFormatter;
47
 import org.openzen.zenscript.formattershared.StatementFormattingSubBlock;
42
 import org.openzen.zenscript.formattershared.StatementFormattingSubBlock;
60
 	public JavaSourceStatementFormatter(JavaSourceStatementScope scope) {
55
 	public JavaSourceStatementFormatter(JavaSourceStatementScope scope) {
61
 		this.scope = scope;
56
 		this.scope = scope;
62
 	}
57
 	}
58
+	
59
+	@Override
60
+	public JavaSourceStatementFormatter forLoop(LoopStatement statement) {
61
+		return new JavaSourceStatementFormatter(scope.createBlockScope(statement));
62
+	}
63
 
63
 
64
 	@Override
64
 	@Override
65
 	public void formatBlock(StatementFormattingTarget target, BlockStatement statement) {
65
 	public void formatBlock(StatementFormattingTarget target, BlockStatement statement) {
68
 
68
 
69
 	@Override
69
 	@Override
70
 	public void formatBreak(StatementFormattingTarget target, BreakStatement statement) {
70
 	public void formatBreak(StatementFormattingTarget target, BreakStatement statement) {
71
-		if (target.getInnerLoop() == statement.target)
71
+		if (scope.innerLoop == statement.target)
72
 			target.writeLine("break;");
72
 			target.writeLine("break;");
73
 		else
73
 		else
74
 			target.writeLine("break " + statement.target.label + ";");
74
 			target.writeLine("break " + statement.target.label + ";");
76
 
76
 
77
 	@Override
77
 	@Override
78
 	public void formatContinue(StatementFormattingTarget target, ContinueStatement statement) {
78
 	public void formatContinue(StatementFormattingTarget target, ContinueStatement statement) {
79
-		if (target.getInnerLoop() == statement.target)
79
+		if (scope.innerLoop == statement.target)
80
 			target.writeLine("continue;");
80
 			target.writeLine("continue;");
81
 		else
81
 		else
82
 			target.writeLine("continue " + statement.target.label + ";");
82
 			target.writeLine("continue " + statement.target.label + ";");
133
 			DefinitionTypeID variantType = (DefinitionTypeID)statement.value.type;
133
 			DefinitionTypeID variantType = (DefinitionTypeID)statement.value.type;
134
 			HighLevelDefinition variant = variantType.definition;
134
 			HighLevelDefinition variant = variantType.definition;
135
 			String variantTypeName = scope.type(variant.getTag(JavaSourceClass.class));
135
 			String variantTypeName = scope.type(variant.getTag(JavaSourceClass.class));
136
-			JavaSourceStatementScope innerScope = scope.createBlockScope(statement);
137
 			for (SwitchCase switchCase : statement.cases) {
136
 			for (SwitchCase switchCase : statement.cases) {
138
 				VariantOptionSwitchValue switchValue = (VariantOptionSwitchValue)switchCase.value;
137
 				VariantOptionSwitchValue switchValue = (VariantOptionSwitchValue)switchCase.value;
139
 				String header = switchValue == null ? "default:" : "case " + switchValue.option.getName() + ":";
138
 				String header = switchValue == null ? "default:" : "case " + switchValue.option.getName() + ":";
276
 
275
 
277
 		@Override
276
 		@Override
278
 		public Void visitArrayKeyValueIterator() {
277
 		public Void visitArrayKeyValueIterator() {
279
-			Statement content = statement.content;
280
-			
281
-			Expression list = scope.duplicable(target, statement.list);
282
-			
283
-			List<Statement> modifiedContent = new ArrayList<>();
284
-			TypeMembers arrayMembers = scope.fileScope.semanticScope.getTypeMembers(statement.list.type);
285
-			
286
-			Expression getElement = arrayMembers
287
-							.getOrCreateGroup(OperatorType.INDEXGET)
288
-							.call(statement.position,
289
-									scope.fileScope.semanticScope,
290
-									list,
291
-									new CallArguments(new GetLocalVariableExpression(statement.position, statement.loopVariables[0])), true);
292
-			Expression setLocal = new SetLocalVariableExpression(statement.position, statement.loopVariables[1], getElement);
293
-			
294
-			modifiedContent.add(new ExpressionStatement(
295
-					statement.position,
296
-					setLocal));
297
-			if (content instanceof BlockStatement) {
298
-				modifiedContent.addAll(((BlockStatement) content).statements);
299
-			} else {
300
-				modifiedContent.add(content);
301
-			}
278
+			ExpressionString list = scope.expression(target, scope.duplicable(target, statement.list));
302
 			
279
 			
303
 			target.writeInner(
280
 			target.writeInner(
304
-					"for (" + scope.type(statement.loopVariables[0].type) + " " + statement.loopVariables[0].name + " : " + scope.expression(target, list) + ")",
305
-					new BlockStatement(statement.position, modifiedContent),
281
+					"for (int " + statement.loopVariables[0].name + " = 0; i < " + list.value + ".length; i++) {",
282
+					new String[] {
283
+						scope.type(statement.loopVariables[1].type) + " " + statement.loopVariables[1].name + " = " + list.value + "[" + statement.loopVariables[0].name + "];"
284
+					},
285
+					statement.content,
306
 					statement,
286
 					statement,
307
-					"");
287
+					"}");
308
 			
288
 			
309
 			return null;
289
 			return null;
310
 		}
290
 		}
317
 		@Override
297
 		@Override
318
 		public Void visitStringCharacterIterator() {
298
 		public Void visitStringCharacterIterator() {
319
 			target.writeInner(
299
 			target.writeInner(
320
-					"for (char " + statement.loopVariables[0].name + " : " + scope.expression(target, statement.list) + ".toCharArray())",
300
+					"for (char " + statement.loopVariables[0].name + " : " + scope.expression(target, statement.list).value + ".toCharArray())",
301
+					statement.content,
302
+					statement,
303
+					"");
304
+			return null;
305
+		}
306
+
307
+		@Override
308
+		public Void visitAssocKeyIterator() {
309
+			VarStatement key = statement.loopVariables[0];
310
+			target.writeInner(
311
+					"for (" + scope.type(key.type) + " " + key + " : " + scope.expression(target, statement.list).value + ".keySet())",
321
 					statement.content,
312
 					statement.content,
322
 					statement,
313
 					statement,
323
 					"");
314
 					"");
324
 			return null;
315
 			return null;
325
 		}
316
 		}
317
+
318
+		@Override
319
+		public Void visitAssocKeyValueIterator() {
320
+			String temp = scope.createTempVariable();
321
+			VarStatement key = statement.loopVariables[0];
322
+			VarStatement value = statement.loopVariables[1];
323
+			target.writeInner(
324
+					"for (Map.Entry<" + scope.type(key.type) + ", " + scope.type(value.type) + "> " + temp + " : " + scope.expression(target, statement.list).value + ".entrySet()) {",
325
+					new String[] {
326
+						scope.type(key.type) + " " + key.name + " = " + temp + ".getKey();",
327
+						scope.type(value.type) + " " + value.name + " = " + temp + ".getValue();"
328
+					},
329
+					statement.content,
330
+					statement,
331
+					"}");
332
+			return null;
333
+		}
326
 	}
334
 	}
327
 }
335
 }

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

39
 	private final File directory;
39
 	private final File directory;
40
 	private final JavaSourceFormattingSettings settings;
40
 	private final JavaSourceFormattingSettings settings;
41
 	private final Map<String, List<String>> members = new HashMap<>();
41
 	private final Map<String, List<String>> members = new HashMap<>();
42
-	private final JavaSourceClass arrayHelpers = new JavaSourceClass("ArrayHelpers", "zsynthetic.ArrayHelpers");
42
+	private final JavaSourceClass arrayHelpers = new JavaSourceClass("zsynthetic", "ArrayHelpers");
43
 	private final Map<ArrayKind, JavaSourceMethod> existingContains = new HashMap<>();
43
 	private final Map<ArrayKind, JavaSourceMethod> existingContains = new HashMap<>();
44
 	private final Map<ArrayKind, JavaSourceMethod> existingIndexOf = new HashMap<>();
44
 	private final Map<ArrayKind, JavaSourceMethod> existingIndexOf = new HashMap<>();
45
 	
45
 	
56
 		String method = generateContains(kind);
56
 		String method = generateContains(kind);
57
 		addMember(arrayHelpers, method);
57
 		addMember(arrayHelpers, method);
58
 		
58
 		
59
-		JavaSourceMethod sourceMethod = new JavaSourceMethod(arrayHelpers, JavaSourceMethod.Kind.EXPANSION, kind.containsName);
59
+		JavaSourceMethod sourceMethod = new JavaSourceMethod(arrayHelpers, JavaSourceMethod.Kind.EXPANSION, kind.containsName, false);
60
 		existingContains.put(kind, sourceMethod);
60
 		existingContains.put(kind, sourceMethod);
61
 		return sourceMethod;
61
 		return sourceMethod;
62
 	}
62
 	}
69
 		String method = generateContains(kind);
69
 		String method = generateContains(kind);
70
 		addMember(arrayHelpers, method);
70
 		addMember(arrayHelpers, method);
71
 		
71
 		
72
-		JavaSourceMethod sourceMethod = new JavaSourceMethod(arrayHelpers, JavaSourceMethod.Kind.EXPANSION, kind.containsName);
72
+		JavaSourceMethod sourceMethod = new JavaSourceMethod(arrayHelpers, JavaSourceMethod.Kind.EXPANSION, kind.containsName, false);
73
 		existingContains.put(kind, sourceMethod);
73
 		existingContains.put(kind, sourceMethod);
74
 		return sourceMethod;
74
 		return sourceMethod;
75
 	}
75
 	}

+ 20
- 9
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceSyntheticTypeGenerator.java View File

12
 import java.io.OutputStreamWriter;
12
 import java.io.OutputStreamWriter;
13
 import java.io.Writer;
13
 import java.io.Writer;
14
 import java.nio.charset.StandardCharsets;
14
 import java.nio.charset.StandardCharsets;
15
+import java.util.ArrayList;
15
 import java.util.HashMap;
16
 import java.util.HashMap;
17
+import java.util.List;
16
 import java.util.Map;
18
 import java.util.Map;
17
 import org.openzen.zenscript.codemodel.FunctionParameter;
19
 import org.openzen.zenscript.codemodel.FunctionParameter;
18
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
20
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
19
 import org.openzen.zenscript.codemodel.type.FunctionTypeID;
21
 import org.openzen.zenscript.codemodel.type.FunctionTypeID;
22
+import org.openzen.zenscript.codemodel.type.ITypeID;
20
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
23
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
21
 
24
 
22
 /**
25
 /**
24
  * @author Hoofdgebruiker
27
  * @author Hoofdgebruiker
25
  */
28
  */
26
 public class JavaSourceSyntheticTypeGenerator {
29
 public class JavaSourceSyntheticTypeGenerator {
27
-	private final Map<FunctionTypeID, JavaSourceClass> functions = new HashMap<>();
30
+	private final Map<FunctionTypeID, JavaSynthesizedClass> functions = new HashMap<>();
28
 	private final File directory;
31
 	private final File directory;
29
 	private final JavaSourceFormattingSettings settings;
32
 	private final JavaSourceFormattingSettings settings;
30
 	
33
 	
33
 		this.settings = settings;
36
 		this.settings = settings;
34
 	}
37
 	}
35
 	
38
 	
36
-	public JavaSourceClass createFunction(FunctionTypeID function) {
39
+	public JavaSynthesizedClass createFunction(JavaSourceTypeVisitor typeFormatter, FunctionTypeID function) {
37
 		if (functions.containsKey(function))
40
 		if (functions.containsKey(function))
38
 			return functions.get(function);
41
 			return functions.get(function);
39
 		
42
 		
40
 		String className = createFunctionClassName(function);
43
 		String className = createFunctionClassName(function);
41
-		JavaSourceClass result = new JavaSourceClass(className, "zsynthetic." + className);
44
+		JavaSourceClass cls = new JavaSourceClass("zsynthetic", className);
45
+		JavaSynthesizedClass result = new JavaSynthesizedClass(cls, extractTypeParameters(function));
42
 		functions.put(function, result);
46
 		functions.put(function, result);
43
 		
47
 		
44
-		JavaSourceImporter importer = new JavaSourceImporter(new ZSPackage(null, "zsynthetic"));
48
+		JavaSourceImporter importer = new JavaSourceImporter(cls);
45
 		JavaSourceTypeVisitor typeVisitor = new JavaSourceTypeVisitor(importer, this);
49
 		JavaSourceTypeVisitor typeVisitor = new JavaSourceTypeVisitor(importer, this);
46
 		
50
 		
47
 		StringBuilder contents = new StringBuilder();
51
 		StringBuilder contents = new StringBuilder();
48
 		contents.append("@FunctionalInterface\n");
52
 		contents.append("@FunctionalInterface\n");
49
 		contents.append("public interface ");
53
 		contents.append("public interface ");
50
 		contents.append(className);
54
 		contents.append(className);
55
+		JavaSourceUtils.formatTypeParameters(typeFormatter, contents, result.typeParameters);
51
 		contents.append(" {\n");
56
 		contents.append(" {\n");
52
 		contents.append(settings.indent);
57
 		contents.append(settings.indent);
53
 		if (function.header.getNumberOfTypeParameters() > 0) {
58
 		if (function.header.getNumberOfTypeParameters() > 0) {
83
 		try (Writer writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file)), StandardCharsets.UTF_8)) {
88
 		try (Writer writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file)), StandardCharsets.UTF_8)) {
84
 			writer.write("package zsynthetic;\n");
89
 			writer.write("package zsynthetic;\n");
85
 			
90
 			
86
-			JavaSourceImporter.Import[] imports = importer.getUsedImports();
91
+			JavaSourceClass[] imports = importer.getUsedImports();
87
 			if (imports.length > 0) {
92
 			if (imports.length > 0) {
88
-				for (JavaSourceImporter.Import import_ : imports) {
89
-					if (import_.actualName.startsWith("java.lang."))
93
+				for (JavaSourceClass import_ : imports) {
94
+					if (import_.pkg.equals("java.lang"))
90
 						continue;
95
 						continue;
91
 					
96
 					
92
 					writer.write("import ");
97
 					writer.write("import ");
93
-					writer.write(import_.actualName);
98
+					writer.write(import_.fullName);
94
 					writer.write(";\n");
99
 					writer.write(";\n");
95
 				}
100
 				}
96
 
101
 
111
 		className.append(functions.size() + 1); // TODO: create more meaningful names
116
 		className.append(functions.size() + 1); // TODO: create more meaningful names
112
 		return className.toString();
117
 		return className.toString();
113
 	}
118
 	}
119
+	
120
+	private TypeParameter[] extractTypeParameters(ITypeID type) {
121
+		List<TypeParameter> result = new ArrayList<>();
122
+		type.extractTypeParameters(result);
123
+		return result.toArray(new TypeParameter[result.size()]);
124
+	}
114
 }
125
 }

+ 33
- 7
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceTypeVisitor.java View File

21
 import org.openzen.zenscript.codemodel.type.OptionalTypeID;
21
 import org.openzen.zenscript.codemodel.type.OptionalTypeID;
22
 import org.openzen.zenscript.codemodel.type.RangeTypeID;
22
 import org.openzen.zenscript.codemodel.type.RangeTypeID;
23
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
23
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
24
+import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
24
 
25
 
25
 /**
26
 /**
26
  *
27
  *
27
  * @author Hoofdgebruiker
28
  * @author Hoofdgebruiker
28
  */
29
  */
29
 public class JavaSourceTypeVisitor implements ITypeVisitor<String>, GenericParameterBoundVisitor<String> {
30
 public class JavaSourceTypeVisitor implements ITypeVisitor<String>, GenericParameterBoundVisitor<String> {
31
+	private static final JavaSourceClass MAP = new JavaSourceClass("java.util", "Map");
32
+	private static final JavaSourceClass HASHMAP = new JavaSourceClass("java.util", "HashMap");
33
+	private static final JavaSourceClass ITERATOR = new JavaSourceClass("java.util", "Iterator");
34
+	
30
 	public final JavaSourceImporter importer;
35
 	public final JavaSourceImporter importer;
31
 	public final JavaSourceSyntheticTypeGenerator typeGenerator;
36
 	public final JavaSourceSyntheticTypeGenerator typeGenerator;
32
 	public final JavaSourceObjectTypeVisitor objectTypeVisitor;
37
 	public final JavaSourceObjectTypeVisitor objectTypeVisitor;
38
+	public final JavaSourceClass cls;
33
 	
39
 	
34
 	public JavaSourceTypeVisitor(JavaSourceImporter importer, JavaSourceSyntheticTypeGenerator typeGenerator) {
40
 	public JavaSourceTypeVisitor(JavaSourceImporter importer, JavaSourceSyntheticTypeGenerator typeGenerator) {
41
+		this(importer, typeGenerator, null);
42
+	}
43
+	
44
+	public JavaSourceTypeVisitor(JavaSourceImporter importer, JavaSourceSyntheticTypeGenerator typeGenerator, JavaSourceClass cls) {
35
 		this.importer = importer;
45
 		this.importer = importer;
36
 		this.typeGenerator = typeGenerator;
46
 		this.typeGenerator = typeGenerator;
47
+		this.cls = cls;
37
 		
48
 		
38
 		if (this instanceof JavaSourceObjectTypeVisitor) {
49
 		if (this instanceof JavaSourceObjectTypeVisitor) {
39
 			objectTypeVisitor = (JavaSourceObjectTypeVisitor)this;
50
 			objectTypeVisitor = (JavaSourceObjectTypeVisitor)this;
77
 
88
 
78
 	@Override
89
 	@Override
79
 	public String visitAssoc(AssocTypeID assoc) {
90
 	public String visitAssoc(AssocTypeID assoc) {
80
-		String map = importer.importType("java.util.Map");
91
+		String map = importer.importType(MAP);
81
 		return map + "<" + assoc.keyType.accept(new JavaSourceObjectTypeVisitor(importer, typeGenerator)) + ", " + assoc.valueType.accept(new JavaSourceObjectTypeVisitor(importer, typeGenerator)) + ">";
92
 		return map + "<" + assoc.keyType.accept(new JavaSourceObjectTypeVisitor(importer, typeGenerator)) + ", " + assoc.valueType.accept(new JavaSourceObjectTypeVisitor(importer, typeGenerator)) + ">";
82
 	}
93
 	}
83
 
94
 
84
 	@Override
95
 	@Override
85
 	public String visitGenericMap(GenericMapTypeID map) {
96
 	public String visitGenericMap(GenericMapTypeID map) {
86
-		String javaMap = importer.importType("java.util.Map");
87
-		return javaMap + "<Class<?>, Object>";
97
+		return importer.importType(MAP) + "<Class<?>, Object>";
88
 	}
98
 	}
89
 
99
 
90
 	@Override
100
 	@Override
91
 	public String visitIterator(IteratorTypeID iterator) {
101
 	public String visitIterator(IteratorTypeID iterator) {
92
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
102
+		if (iterator.iteratorTypes.length == 1) {
103
+			return importer.importType(ITERATOR) + "<" + iterator.iteratorTypes[0].accept(objectTypeVisitor) + '>';
104
+		} else {
105
+			throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
106
+		}
93
 	}
107
 	}
94
 
108
 
95
 	@Override
109
 	@Override
96
 	public String visitFunction(FunctionTypeID function) {
110
 	public String visitFunction(FunctionTypeID function) {
97
-		JavaSourceClass synthetic = typeGenerator.createFunction(function);
98
-		return importer.importType(synthetic.fullName);
111
+		JavaSynthesizedClass synthetic = typeGenerator.createFunction(this, function);
112
+		StringBuilder result = new StringBuilder();
113
+		result.append(importer.importType(synthetic.cls));
114
+		if (synthetic.typeParameters.length > 0) {
115
+			result.append('<');
116
+			for (int i = 0; i < synthetic.typeParameters.length; i++) {
117
+				if (i > 0)
118
+					result.append(", ");
119
+				
120
+				result.append(synthetic.typeParameters[i].name);
121
+			}
122
+			result.append('>');
123
+		}
124
+		return result.toString();
99
 	}
125
 	}
100
 
126
 
101
 	@Override
127
 	@Override
102
 	public String visitDefinition(DefinitionTypeID definition) {
128
 	public String visitDefinition(DefinitionTypeID definition) {
103
-		String javaType = importer.importType(definition.definition);
129
+		String javaType = cls == null ? importer.importType(definition.definition) : importer.importType(cls);
104
 		StringBuilder result = new StringBuilder(javaType);
130
 		StringBuilder result = new StringBuilder(javaType);
105
 		if (definition.typeParameters != null && definition.typeParameters.length > 0) {
131
 		if (definition.typeParameters != null && definition.typeParameters.length > 0) {
106
 			result.append("<");
132
 			result.append("<");

+ 50
- 8
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceUtils.java View File

10
 import org.openzen.zenscript.codemodel.generic.ParameterSuperBound;
10
 import org.openzen.zenscript.codemodel.generic.ParameterSuperBound;
11
 import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
11
 import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
-import org.openzen.zenscript.javasource.scope.JavaSourceFileScope;
13
+import org.openzen.zenscript.codemodel.type.ITypeID;
14
 
14
 
15
 /**
15
 /**
16
  *
16
  *
19
 public class JavaSourceUtils {
19
 public class JavaSourceUtils {
20
 	private JavaSourceUtils() {}
20
 	private JavaSourceUtils() {}
21
 	
21
 	
22
-	public static void formatTypeParameters(JavaSourceFileScope scope, StringBuilder output, TypeParameter[] parameters) {
22
+	public static void formatTypeParameters(JavaSourceTypeVisitor typeFormatter, StringBuilder output, TypeParameter[] parameters) {
23
 		if (parameters == null || parameters.length == 0)
23
 		if (parameters == null || parameters.length == 0)
24
 			return;
24
 			return;
25
 		
25
 		
26
-		TypeParameterBoundVisitor boundVisitor = new TypeParameterBoundVisitor(scope, output);
26
+		TypeParameterBoundVisitor boundVisitor = new TypeParameterBoundVisitor(typeFormatter, output);
27
 		output.append("<");
27
 		output.append("<");
28
 		for (int i = 0; i < parameters.length; i++) {
28
 		for (int i = 0; i < parameters.length; i++) {
29
 			if (i > 0)
29
 			if (i > 0)
40
 		output.append("> ");
40
 		output.append("> ");
41
 	}
41
 	}
42
 	
42
 	
43
+	public static void formatTypeParameters(JavaSourceTypeVisitor typeFormatter, StringBuilder output, TypeParameter[] expansion, TypeParameter[] parameters) {
44
+		if (((parameters == null ? 0 : parameters.length) + (expansion == null ? 0 : expansion.length)) == 0)
45
+			return;
46
+		
47
+		TypeParameterBoundVisitor boundVisitor = new TypeParameterBoundVisitor(typeFormatter, output);
48
+		output.append("<");
49
+		boolean first = true;
50
+		if (parameters != null) {
51
+			for (int i = 0; i < parameters.length; i++) {
52
+				if (first)
53
+					first = false;
54
+				else
55
+					output.append(", ");
56
+
57
+				TypeParameter typeParameter = parameters[i];
58
+				output.append(typeParameter.name);
59
+
60
+				if (typeParameter.bounds.size() > 0) {
61
+					for (GenericParameterBound bound : typeParameter.bounds)
62
+						bound.accept(boundVisitor);
63
+				}
64
+			}
65
+		}
66
+		if (expansion != null) {
67
+			for (int i = 0; i < expansion.length; i++) {
68
+				if (first)
69
+					first = false;
70
+				else
71
+					output.append(", ");
72
+
73
+				TypeParameter typeParameter = expansion[i];
74
+				output.append(typeParameter.name);
75
+
76
+				if (typeParameter.bounds.size() > 0) {
77
+					for (GenericParameterBound bound : typeParameter.bounds)
78
+						bound.accept(boundVisitor);
79
+				}
80
+			}
81
+		}
82
+		output.append("> ");
83
+	}
84
+	
43
 	private static class TypeParameterBoundVisitor implements GenericParameterBoundVisitor<Void> {
85
 	private static class TypeParameterBoundVisitor implements GenericParameterBoundVisitor<Void> {
44
-		private final JavaSourceFileScope scope;
86
+		private final JavaSourceTypeVisitor typeFormatter;
45
 		private final StringBuilder output;
87
 		private final StringBuilder output;
46
 		
88
 		
47
-		public TypeParameterBoundVisitor(JavaSourceFileScope scope, StringBuilder output) {
48
-			this.scope = scope;
89
+		public TypeParameterBoundVisitor(JavaSourceTypeVisitor typeFormatter, StringBuilder output) {
90
+			this.typeFormatter = typeFormatter;
49
 			this.output = output;
91
 			this.output = output;
50
 		}
92
 		}
51
 
93
 
52
 		@Override
94
 		@Override
53
 		public Void visitSuper(ParameterSuperBound bound) {
95
 		public Void visitSuper(ParameterSuperBound bound) {
54
-			output.append(" super ").append(scope.type(bound.type));
96
+			output.append(" super ").append(bound.type.accept(typeFormatter));
55
 			return null;
97
 			return null;
56
 		}
98
 		}
57
 
99
 
58
 		@Override
100
 		@Override
59
 		public Void visitType(ParameterTypeBound bound) {
101
 		public Void visitType(ParameterTypeBound bound) {
60
-			output.append(" extends ").append(scope.type(bound.type));
102
+			output.append(" extends ").append(bound.type.accept(typeFormatter));
61
 			return null;
103
 			return null;
62
 		}
104
 		}
63
 	}
105
 	}

+ 23
- 0
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSynthesizedClass.java View File

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.javasource;
7
+
8
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
9
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class JavaSynthesizedClass {
16
+	public final JavaSourceClass cls;
17
+	public final TypeParameter[] typeParameters;
18
+	
19
+	public JavaSynthesizedClass(JavaSourceClass cls, TypeParameter[] typeParameters) {
20
+		this.cls = cls;
21
+		this.typeParameters = typeParameters;
22
+	}
23
+}

+ 40
- 0
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaNativeClass.java View File

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.javasource.prepare;
7
+
8
+import java.util.HashMap;
9
+import java.util.Map;
10
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
11
+import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
12
+
13
+/**
14
+ *
15
+ * @author Hoofdgebruiker
16
+ */
17
+public class JavaNativeClass {
18
+	public final JavaSourceClass cls;
19
+	private final Map<String, JavaSourceMethod> methods = new HashMap<>();
20
+	
21
+	public JavaNativeClass(JavaSourceClass cls) {
22
+		this.cls = cls;
23
+	}
24
+	
25
+	public void addMethod(String key, JavaSourceMethod method) {
26
+		methods.put(key, method);
27
+	}
28
+	
29
+	public void addConstructor(String key, String name) {
30
+		methods.put(key, new JavaSourceMethod(cls, JavaSourceMethod.Kind.CONSTRUCTOR, name, false));
31
+	}
32
+	
33
+	public void addInstanceMethod(String key, String name) {
34
+		methods.put(key, new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, name, false));
35
+	}
36
+	
37
+	public JavaSourceMethod getMethod(String name) {
38
+		return methods.get(name);
39
+	}
40
+}

+ 28
- 73
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareClassMethodVisitor.java View File

7
 
7
 
8
 import org.openzen.zenscript.codemodel.OperatorType;
8
 import org.openzen.zenscript.codemodel.OperatorType;
9
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
9
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
10
-import org.openzen.zenscript.codemodel.expression.CastExpression;
11
 import org.openzen.zenscript.codemodel.member.CallerMember;
10
 import org.openzen.zenscript.codemodel.member.CallerMember;
12
 import org.openzen.zenscript.codemodel.member.CasterMember;
11
 import org.openzen.zenscript.codemodel.member.CasterMember;
13
 import org.openzen.zenscript.codemodel.member.ConstMember;
12
 import org.openzen.zenscript.codemodel.member.ConstMember;
24
 import org.openzen.zenscript.codemodel.member.OperatorMember;
23
 import org.openzen.zenscript.codemodel.member.OperatorMember;
25
 import org.openzen.zenscript.codemodel.member.SetterMember;
24
 import org.openzen.zenscript.codemodel.member.SetterMember;
26
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
25
 import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
27
-import org.openzen.zenscript.formattershared.ExpressionString;
28
-import org.openzen.zenscript.javasource.JavaOperator;
29
 import org.openzen.zenscript.javasource.JavaSourceTypeNameVisitor;
26
 import org.openzen.zenscript.javasource.JavaSourceTypeNameVisitor;
30
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
27
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
31
 import org.openzen.zenscript.javasource.tags.JavaSourceField;
28
 import org.openzen.zenscript.javasource.tags.JavaSourceField;
38
  */
35
  */
39
 public class JavaSourcePrepareClassMethodVisitor implements MemberVisitor<Void> {
36
 public class JavaSourcePrepareClassMethodVisitor implements MemberVisitor<Void> {
40
 	private final JavaSourceClass cls;
37
 	private final JavaSourceClass cls;
38
+	private final JavaNativeClass nativeClass;
41
 	
39
 	
42
-	public JavaSourcePrepareClassMethodVisitor(JavaSourceClass cls) {
40
+	public JavaSourcePrepareClassMethodVisitor(JavaSourceClass cls, JavaNativeClass nativeClass, boolean startsEmpty) {
43
 		this.cls = cls;
41
 		this.cls = cls;
42
+		this.nativeClass = nativeClass;
43
+		cls.empty = startsEmpty;
44
 	}
44
 	}
45
 	
45
 	
46
 	@Override
46
 	@Override
47
 	public Void visitConst(ConstMember member) {
47
 	public Void visitConst(ConstMember member) {
48
+		cls.empty = false;
48
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
49
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
49
 		return null;
50
 		return null;
50
 	}
51
 	}
51
 	
52
 	
52
 	@Override
53
 	@Override
53
 	public Void visitField(FieldMember member) {
54
 	public Void visitField(FieldMember member) {
55
+		cls.empty = false;
54
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
56
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
57
+		if (member.hasAutoGetter())
58
+			visitGetter(member.autoGetter);
59
+		if (member.hasAutoSetter())
60
+			visitSetter(member.autoSetter);
61
+		
55
 		return null;
62
 		return null;
56
 	}
63
 	}
57
 
64
 
63
 
70
 
64
 	@Override
71
 	@Override
65
 	public Void visitDestructor(DestructorMember member) {
72
 	public Void visitDestructor(DestructorMember member) {
73
+		cls.empty = false;
66
 		return null;
74
 		return null;
67
 	}
75
 	}
68
 
76
 
111
 	@Override
119
 	@Override
112
 	public Void visitImplementation(ImplementationMember member) {
120
 	public Void visitImplementation(ImplementationMember member) {
113
 		// TODO: implementation merge check
121
 		// TODO: implementation merge check
122
+		cls.empty = false;
114
 		return null;
123
 		return null;
115
 	}
124
 	}
116
 
125
 
117
 	@Override
126
 	@Override
118
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
127
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
119
 		// TODO
128
 		// TODO
129
+		cls.empty = false;
120
 		return null;
130
 		return null;
121
 	}
131
 	}
122
 
132
 
123
 	@Override
133
 	@Override
124
 	public Void visitStaticInitializer(StaticInitializerMember member) {
134
 	public Void visitStaticInitializer(StaticInitializerMember member) {
135
+		cls.empty = false;
125
 		return null;
136
 		return null;
126
 	}
137
 	}
127
 	
138
 	
128
 	private JavaSourceMethod.Kind getKind(DefinitionMember member) {
139
 	private JavaSourceMethod.Kind getKind(DefinitionMember member) {
140
+		if (member instanceof ConstructorMember)
141
+			return JavaSourceMethod.Kind.CONSTRUCTOR;
142
+		
129
 		return member.isStatic() ? JavaSourceMethod.Kind.STATIC : JavaSourceMethod.Kind.INSTANCE;
143
 		return member.isStatic() ? JavaSourceMethod.Kind.STATIC : JavaSourceMethod.Kind.INSTANCE;
130
 	}
144
 	}
131
 	
145
 	
194
 			case CONTAINS:
208
 			case CONTAINS:
195
 				return "contains";
209
 				return "contains";
196
 			case EQUALS:
210
 			case EQUALS:
197
-				return "equals";
211
+				return "equals_";
198
 			case COMPARE:
212
 			case COMPARE:
199
 				return "compareTo";
213
 				return "compareTo";
200
 			case RANGE:
214
 			case RANGE:
214
 	
228
 	
215
 	private void visitFunctional(DefinitionMember member, String name) {
229
 	private void visitFunctional(DefinitionMember member, String name) {
216
 		NativeTag nativeTag = member.getTag(NativeTag.class);
230
 		NativeTag nativeTag = member.getTag(NativeTag.class);
217
-		if (nativeTag == null) {
218
-			member.setTag(
219
-					JavaSourceMethod.class,
220
-					new JavaSourceMethod(cls, getKind(member), name));
221
-		} else {
222
-			member.setTag(JavaSourceMethod.class, getNative(nativeTag.value));
223
-		}
224
-	}
225
-	
226
-	private JavaSourceMethod getNative(String name) {
227
-		if (cls.fullName.equals("java.lang.StringBuilder"))
228
-			return getStringBuilderNative(name);
229
-		else if (cls.fullName.equals("java.util.List"))
230
-			return getListNative(name);
231
+		JavaSourceMethod method = null;
232
+		if (nativeTag != null && nativeClass != null)
233
+			method = nativeClass.getMethod(nativeTag.value);
234
+		if (method == null)
235
+			method = new JavaSourceMethod(cls, getKind(member), name, true);
231
 		
236
 		
232
-		throw new UnsupportedOperationException("Unknown native class: " + cls.fullName);
233
-	}
234
-	
235
-	private JavaSourceMethod getListNative(String name) {
236
-		switch (name) {
237
-			case "constructor":
238
-				return new JavaSourceMethod((formatter, call) -> new ExpressionString("new ArrayList<>()", JavaOperator.NEW));
239
-			case "add":
240
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "add");
241
-			case "getIndex":
242
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "get");
243
-			case "setIndex":
244
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "set");
245
-			case "toArray":
246
-				return new JavaSourceMethod((formatter, calle)
247
-						-> formatter.listToArray((CastExpression)calle));
248
-			case "length":
249
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "size");
250
-			case "isEmpty":
251
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "isEmpty");
252
-			default:
253
-				throw new UnsupportedOperationException("Unknown native method: " + name);
254
-		}
255
-	}
256
-	
257
-	private JavaSourceMethod getStringBuilderNative(String name) {
258
-		switch (name) {
259
-			case "constructor":
260
-			case "constructorWithCapacity":
261
-			case "constructorWithValue":
262
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "");
263
-			case "isEmpty":
264
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "isEmpty");
265
-			case "length":
266
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "length");
267
-			case "appendBool":
268
-			case "appendByte":
269
-			case "appendSByte":
270
-			case "appendShort":
271
-			case "appendUShort":
272
-			case "appendInt":
273
-			case "appendUInt":
274
-			case "appendLong":
275
-			case "appendULong":
276
-			case "appendFloat":
277
-			case "appendDouble":
278
-			case "appendChar":
279
-			case "appendString":
280
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "append");
281
-			case "asString":
282
-				return new JavaSourceMethod(cls, JavaSourceMethod.Kind.INSTANCE, "toString");
283
-			default:
284
-				throw new UnsupportedOperationException("Unknown native method: " + name);
285
-		}
237
+		if (method.compile)
238
+			cls.empty = false;
239
+		
240
+		member.setTag(JavaSourceMethod.class, method);
286
 	}
241
 	}
287
 }
242
 }

+ 191
- 50
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareDefinitionVisitor.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.javasource.prepare;
6
 package org.openzen.zenscript.javasource.prepare;
7
 
7
 
8
+import java.util.HashMap;
9
+import java.util.Map;
8
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
9
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
11
 import org.openzen.zenscript.codemodel.annotations.NativeTag;
10
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
12
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
16
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
18
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
17
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
19
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
18
 import org.openzen.zenscript.codemodel.definition.VariantDefinition;
20
 import org.openzen.zenscript.codemodel.definition.VariantDefinition;
21
+import org.openzen.zenscript.codemodel.expression.CallExpression;
22
+import org.openzen.zenscript.codemodel.expression.CastExpression;
23
+import org.openzen.zenscript.codemodel.expression.Expression;
19
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
24
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
25
+import org.openzen.zenscript.codemodel.type.ArrayTypeID;
26
+import org.openzen.zenscript.formattershared.ExpressionString;
27
+import org.openzen.zenscript.javasource.JavaOperator;
20
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
28
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
21
-import org.openzen.zenscript.javasource.JavaSourceFile;
22
 import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
29
 import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
23
 import org.openzen.zenscript.javasource.tags.JavaSourceVariantOption;
30
 import org.openzen.zenscript.javasource.tags.JavaSourceVariantOption;
24
 
31
 
26
  *
33
  *
27
  * @author Hoofdgebruiker
34
  * @author Hoofdgebruiker
28
  */
35
  */
29
-public class JavaSourcePrepareDefinitionVisitor implements DefinitionVisitor<Void> {
30
-	private final JavaSourceFile file;
36
+public class JavaSourcePrepareDefinitionVisitor implements DefinitionVisitor<JavaSourceClass> {
37
+	private static final Map<String, JavaNativeClass> nativeClasses = new HashMap<>();
31
 	
38
 	
32
-	public JavaSourcePrepareDefinitionVisitor(JavaSourceFile file) {
33
-		this.file = file;
39
+	static {
40
+		{
41
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.lang", "StringBuilder"));
42
+			cls.addConstructor("constructor", "");
43
+			cls.addConstructor("constructorWithCapacity", "");
44
+			cls.addConstructor("constructorWithValue", "");
45
+			cls.addMethod("isEmpty", new JavaSourceMethod((formatter, call) -> ((CallExpression)call).accept(formatter).unaryPostfix(JavaOperator.EQUALS, "length() == 0")));
46
+			cls.addInstanceMethod("length", "length");
47
+			cls.addInstanceMethod("appendBool", "append");
48
+			cls.addInstanceMethod("appendByte", "append");
49
+			cls.addInstanceMethod("appendSByte", "append");
50
+			cls.addInstanceMethod("appendShort", "append");
51
+			cls.addInstanceMethod("appendUShort", "append");
52
+			cls.addInstanceMethod("appendInt", "append");
53
+			cls.addInstanceMethod("appendUInt", "append");
54
+			cls.addInstanceMethod("appendLong", "append");
55
+			cls.addInstanceMethod("appendULong", "append");
56
+			cls.addInstanceMethod("appendFloat", "append");
57
+			cls.addInstanceMethod("appendDouble", "append");
58
+			cls.addInstanceMethod("appendChar", "append");
59
+			cls.addInstanceMethod("appendString", "append");
60
+			cls.addInstanceMethod("asString", "toString");
61
+			nativeClasses.put("stdlib::StringBuilder", cls);
62
+		}
63
+		
64
+		{
65
+			JavaNativeClass list = new JavaNativeClass(new JavaSourceClass("java.util", "List"));
66
+			JavaSourceClass arrayList = new JavaSourceClass("java.util", "ArrayList");
67
+			list.addMethod("constructor", new JavaSourceMethod(arrayList, JavaSourceMethod.Kind.CONSTRUCTOR, "", false));
68
+			list.addInstanceMethod("add", "add");
69
+			list.addInstanceMethod("insert", "add");
70
+			list.addInstanceMethod("getAtIndex", "get");
71
+			list.addInstanceMethod("setAtIndex", "set");
72
+			list.addMethod("toArray", new JavaSourceMethod((formatter, call) -> formatter.listToArray((CastExpression)call)));
73
+			list.addInstanceMethod("length", "length");
74
+			list.addInstanceMethod("isEmpty", "isEmpty");
75
+			nativeClasses.put("stdlib::List", list);
76
+		}
77
+		
78
+		{
79
+			JavaNativeClass comparable = new JavaNativeClass(new JavaSourceClass("java.lang", "Comparable"));
80
+			comparable.addInstanceMethod("compareTo", "compareTo");
81
+			nativeClasses.put("stdlib::Comparable", comparable);
82
+		}
83
+		
84
+		{
85
+			JavaSourceClass integer = new JavaSourceClass("java.lang", "Integer");
86
+			JavaSourceClass math = new JavaSourceClass("java.lang", "Math");
87
+			
88
+			JavaNativeClass cls = new JavaNativeClass(integer);
89
+			cls.addMethod("min", new JavaSourceMethod(math, JavaSourceMethod.Kind.STATIC, "min", false));
90
+			cls.addMethod("max", new JavaSourceMethod(math, JavaSourceMethod.Kind.STATIC, "max", false));
91
+			cls.addMethod("toHexString", new JavaSourceMethod(integer, JavaSourceMethod.Kind.EXPANSION, "toHexString", false));
92
+			nativeClasses.put("stdlib::Integer", cls);
93
+		}
94
+		
95
+		{
96
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.lang", "String"));
97
+			cls.addMethod("contains", new JavaSourceMethod((formatter, calle) -> {
98
+				CallExpression call = (CallExpression)calle;
99
+				ExpressionString str = call.arguments.arguments[0].accept(formatter);
100
+				ExpressionString character = call.arguments.arguments[1].accept(formatter);
101
+				return str.unaryPostfix(JavaOperator.GREATER_EQUALS, ".indexOf(" + character.value + ")");
102
+			}));
103
+			cls.addInstanceMethod("indexOf", "indexOf");
104
+			cls.addInstanceMethod("indexOfFrom", "indexOf");
105
+			cls.addInstanceMethod("lastIndexOf", "lastIndexOf");
106
+			cls.addInstanceMethod("lastIndexOfFrom", "lastIndexOf");
107
+			cls.addInstanceMethod("trim", "trim");
108
+			nativeClasses.put("stdlib::String", cls);
109
+		}
110
+		
111
+		{
112
+			JavaSourceClass arrays = new JavaSourceClass("java.lang", "Arrays");
113
+			JavaNativeClass cls = new JavaNativeClass(arrays);
114
+			cls.addMethod("sort", new JavaSourceMethod(arrays, JavaSourceMethod.Kind.EXPANSION, "sort", false));
115
+			cls.addMethod("sorted", new JavaSourceMethod((formatter, calle) -> {
116
+				Expression target = formatter.duplicable(((CallExpression)calle).target);
117
+				ExpressionString targetString = target.accept(formatter);
118
+				ExpressionString copy = new ExpressionString("Arrays.copyOf(" + targetString.value + ", " + targetString.value + ".length).sort()", JavaOperator.CALL);
119
+				ExpressionString source = formatter.hoist(copy, formatter.scope.type(target.type));
120
+				formatter.target.writeLine("Arrays.sort(" + source.value + ");");
121
+				return source;
122
+			}));
123
+			cls.addMethod("sortWithComparator", new JavaSourceMethod(arrays, JavaSourceMethod.Kind.EXPANSION, "sort", false));
124
+			cls.addMethod("sortedWithComparator", new JavaSourceMethod((formatter, calle) -> {
125
+				Expression target = formatter.duplicable(((CallExpression)calle).target);
126
+				ExpressionString comparator = ((CallExpression)calle).arguments.arguments[0].accept(formatter);
127
+				ExpressionString targetString = target.accept(formatter);
128
+				ExpressionString copy = new ExpressionString("Arrays.copyOf(" + targetString.value + ", " + targetString.value + ".length).sort()", JavaOperator.CALL);
129
+				ExpressionString source = formatter.hoist(copy, formatter.scope.type(target.type));
130
+				formatter.target.writeLine("Arrays.sort(" + source.value + ", " + comparator.value + ");");
131
+				return source;
132
+			}));
133
+			cls.addMethod("copy", new JavaSourceMethod((formatter, calle) -> {
134
+				Expression target = formatter.duplicable(((CallExpression)calle).target);
135
+				ExpressionString source = target.accept(formatter);
136
+				return new ExpressionString("Arrays.copyOf(" + source.value + ", " + source.value + ".length)", JavaOperator.CALL);
137
+			}));
138
+			cls.addMethod("copyResize", new JavaSourceMethod(arrays, JavaSourceMethod.Kind.EXPANSION, "copyOf", false));
139
+			cls.addMethod("copyTo", new JavaSourceMethod((formatter, calle) -> {
140
+				CallExpression call = (CallExpression)calle;
141
+				Expression source = call.target;
142
+				Expression target = call.arguments.arguments[0];
143
+				Expression sourceOffset = call.arguments.arguments[1];
144
+				Expression targetOffset = call.arguments.arguments[2];
145
+				Expression length = call.arguments.arguments[3];
146
+				return new ExpressionString("System.arraycopy("
147
+					+ source.accept(formatter) + ", "
148
+					+ sourceOffset.accept(formatter) + ", "
149
+					+ target.accept(formatter) + ", "
150
+					+ targetOffset.accept(formatter) + ", "
151
+					+ length.accept(formatter) + ")", JavaOperator.CALL);
152
+			}));
153
+			nativeClasses.put("stdlib::Arrays", cls);
154
+		}
155
+		
156
+		{
157
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.lang", "IllegalArgumentException"));
158
+			cls.addConstructor("constructor", "");
159
+			nativeClasses.put("stdlib::IllegalArgumentException", cls);
160
+		}
161
+		
162
+		{
163
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.lang", "Exception"));
164
+			cls.addConstructor("constructor", "");
165
+			cls.addConstructor("constructorWithCause", "");
166
+			nativeClasses.put("stdlib::Exception", cls);
167
+		}
168
+	}
169
+	
170
+	private final String filename;
171
+	
172
+	public JavaSourcePrepareDefinitionVisitor(String filename) {
173
+		this.filename = filename;
34
 	}
174
 	}
35
 	
175
 	
36
 	@Override
176
 	@Override
37
-	public Void visitClass(ClassDefinition definition) {
38
-		visitClassCompiled(definition);
39
-		return null;
177
+	public JavaSourceClass visitClass(ClassDefinition definition) {
178
+		return visitClassCompiled(definition, true);
40
 	}
179
 	}
41
 
180
 
42
 	@Override
181
 	@Override
43
-	public Void visitInterface(InterfaceDefinition definition) {
44
-		visitClassCompiled(definition);
45
-		return null;
182
+	public JavaSourceClass visitInterface(InterfaceDefinition definition) {
183
+		return visitClassCompiled(definition, true);
46
 	}
184
 	}
47
 
185
 
48
 	@Override
186
 	@Override
49
-	public Void visitEnum(EnumDefinition definition) {
50
-		visitClassCompiled(definition);
51
-		return null;
187
+	public JavaSourceClass visitEnum(EnumDefinition definition) {
188
+		return visitClassCompiled(definition, false);
52
 	}
189
 	}
53
 
190
 
54
 	@Override
191
 	@Override
55
-	public Void visitStruct(StructDefinition definition) {
56
-		visitClassCompiled(definition);
57
-		return null;
192
+	public JavaSourceClass visitStruct(StructDefinition definition) {
193
+		return visitClassCompiled(definition, true);
58
 	}
194
 	}
59
 
195
 
60
 	@Override
196
 	@Override
61
-	public Void visitFunction(FunctionDefinition definition) {
62
-		JavaSourceClass cls = new JavaSourceClass(file.getName(), definition.pkg.fullName + "." + file.getName());
197
+	public JavaSourceClass visitFunction(FunctionDefinition definition) {
198
+		JavaSourceClass cls = new JavaSourceClass(definition.pkg.fullName, filename);
63
 		definition.setTag(JavaSourceClass.class, cls);
199
 		definition.setTag(JavaSourceClass.class, cls);
64
-		JavaSourceMethod method = new JavaSourceMethod(cls, JavaSourceMethod.Kind.STATIC, definition.name);
200
+		JavaSourceMethod method = new JavaSourceMethod(cls, JavaSourceMethod.Kind.STATIC, definition.name, true);
65
 		definition.caller.setTag(JavaSourceMethod.class, method);
201
 		definition.caller.setTag(JavaSourceMethod.class, method);
66
-		return null;
202
+		return cls;
67
 	}
203
 	}
68
 
204
 
69
 	@Override
205
 	@Override
70
-	public Void visitExpansion(ExpansionDefinition definition) {
71
-		JavaSourceClass cls = new JavaSourceClass(file.getName(), definition.pkg.fullName + "." + file.getName());
72
-		definition.setTag(JavaSourceClass.class, cls);
73
-		JavaSourcePrepareExpansionMethodVisitor methodVisitor = new JavaSourcePrepareExpansionMethodVisitor(cls);
74
-		for (IDefinitionMember member : definition.members) {
75
-			member.accept(methodVisitor);
206
+	public JavaSourceClass visitExpansion(ExpansionDefinition definition) {
207
+		NativeTag nativeTag = definition.getTag(NativeTag.class);
208
+		JavaNativeClass nativeClass = null;
209
+		if (nativeTag != null) {
210
+			nativeClass = nativeClasses.get(nativeTag.value);
76
 		}
211
 		}
77
-		return null;
212
+		
213
+		JavaSourceClass cls = new JavaSourceClass(definition.pkg.fullName, filename);
214
+		definition.setTag(JavaSourceClass.class, cls);
215
+		visitExpansionMembers(definition, cls, nativeClass);
216
+		return cls;
78
 	}
217
 	}
79
 
218
 
80
 	@Override
219
 	@Override
81
-	public Void visitAlias(AliasDefinition definition) {
220
+	public JavaSourceClass visitAlias(AliasDefinition definition) {
82
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
221
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
83
 	}
222
 	}
84
 
223
 
85
 	@Override
224
 	@Override
86
-	public Void visitVariant(VariantDefinition variant) {
87
-		JavaSourceClass cls = new JavaSourceClass(variant.name, variant.pkg.fullName + "." + variant.name);
225
+	public JavaSourceClass visitVariant(VariantDefinition variant) {
226
+		JavaSourceClass cls = new JavaSourceClass(variant.pkg.fullName, variant.name);
88
 		variant.setTag(JavaSourceClass.class, cls);
227
 		variant.setTag(JavaSourceClass.class, cls);
89
 		
228
 		
90
 		for (VariantDefinition.Option option : variant.options) {
229
 		for (VariantDefinition.Option option : variant.options) {
91
-			JavaSourceClass variantCls = new JavaSourceClass(option.name, cls.fullName + "." + option.name);
230
+			JavaSourceClass variantCls = new JavaSourceClass(cls.fullName, option.name);
92
 			option.setTag(JavaSourceVariantOption.class, new JavaSourceVariantOption(cls, variantCls));
231
 			option.setTag(JavaSourceVariantOption.class, new JavaSourceVariantOption(cls, variantCls));
93
 		}
232
 		}
94
 		
233
 		
95
-		visitClassMembers(variant, cls);
96
-		return null;
234
+		visitClassMembers(variant, cls, null, false);
235
+		return cls;
97
 	}
236
 	}
98
 	
237
 	
99
-	private void visitClassCompiled(HighLevelDefinition definition) {
238
+	private JavaSourceClass visitClassCompiled(HighLevelDefinition definition, boolean startsEmpty) {
100
 		NativeTag nativeTag = definition.getTag(NativeTag.class);
239
 		NativeTag nativeTag = definition.getTag(NativeTag.class);
101
-		if (nativeTag == null) {
102
-			JavaSourceClass cls = new JavaSourceClass(definition.name, definition.pkg.fullName + "." + definition.name);
240
+		JavaNativeClass nativeClass = nativeTag == null ? null : nativeClasses.get(nativeTag.value);
241
+		if (nativeClass == null) {
242
+			JavaSourceClass cls = new JavaSourceClass(definition.pkg.fullName, definition.name);
103
 			definition.setTag(JavaSourceClass.class, cls);
243
 			definition.setTag(JavaSourceClass.class, cls);
104
-			visitClassMembers(definition, cls);
244
+			visitClassMembers(definition, cls, null, startsEmpty);
245
+			return cls;
105
 		} else {
246
 		} else {
106
-			JavaSourceClass cls = getNativeClass(nativeTag.value);
107
-			definition.setTag(JavaSourceClass.class, cls);
108
-			visitClassMembers(definition, cls);
247
+			JavaSourceClass cls = new JavaSourceClass(definition.pkg.fullName, filename);
248
+			definition.setTag(JavaSourceClass.class, nativeClass.cls);
249
+			definition.setTag(JavaNativeClass.class, nativeClass);
250
+			visitExpansionMembers(definition, cls, nativeClass);
251
+			return cls;
109
 		}
252
 		}
110
 	}
253
 	}
111
 	
254
 	
112
-	private JavaSourceClass getNativeClass(String name) {
113
-		if (name.equals("stdlib::StringBuilder"))
114
-			return new JavaSourceClass("StringBuilder", "java.lang.StringBuilder");
115
-		else if (name.equals("stdlib::List"))
116
-			return new JavaSourceClass("List", "java.util.List");
117
-		
118
-		throw new UnsupportedOperationException("Unknown native class: " + name);
255
+	private void visitClassMembers(HighLevelDefinition definition, JavaSourceClass cls, JavaNativeClass nativeClass, boolean startsEmpty) {
256
+		JavaSourcePrepareClassMethodVisitor methodVisitor = new JavaSourcePrepareClassMethodVisitor(cls, nativeClass, startsEmpty);
257
+		for (IDefinitionMember member : definition.members) {
258
+			member.accept(methodVisitor);
259
+		}
119
 	}
260
 	}
120
 	
261
 	
121
-	private void visitClassMembers(HighLevelDefinition definition, JavaSourceClass cls) {
122
-		JavaSourcePrepareClassMethodVisitor methodVisitor = new JavaSourcePrepareClassMethodVisitor(cls);
262
+	private void visitExpansionMembers(HighLevelDefinition definition, JavaSourceClass cls, JavaNativeClass nativeClass) {
263
+		JavaSourcePrepareExpansionMethodVisitor methodVisitor = new JavaSourcePrepareExpansionMethodVisitor(cls, nativeClass);
123
 		for (IDefinitionMember member : definition.members) {
264
 		for (IDefinitionMember member : definition.members) {
124
 			member.accept(methodVisitor);
265
 			member.accept(methodVisitor);
125
 		}
266
 		}

+ 24
- 6
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareExpansionMethodVisitor.java View File

6
 package org.openzen.zenscript.javasource.prepare;
6
 package org.openzen.zenscript.javasource.prepare;
7
 
7
 
8
 import org.openzen.zenscript.codemodel.OperatorType;
8
 import org.openzen.zenscript.codemodel.OperatorType;
9
+import org.openzen.zenscript.codemodel.annotations.NativeTag;
9
 import org.openzen.zenscript.codemodel.member.CallerMember;
10
 import org.openzen.zenscript.codemodel.member.CallerMember;
10
 import org.openzen.zenscript.codemodel.member.CasterMember;
11
 import org.openzen.zenscript.codemodel.member.CasterMember;
11
 import org.openzen.zenscript.codemodel.member.ConstMember;
12
 import org.openzen.zenscript.codemodel.member.ConstMember;
34
  */
35
  */
35
 public class JavaSourcePrepareExpansionMethodVisitor implements MemberVisitor<Void> {
36
 public class JavaSourcePrepareExpansionMethodVisitor implements MemberVisitor<Void> {
36
 	private final JavaSourceClass cls;
37
 	private final JavaSourceClass cls;
38
+	private final JavaNativeClass nativeClass;
37
 	
39
 	
38
-	public JavaSourcePrepareExpansionMethodVisitor(JavaSourceClass cls) {
40
+	public JavaSourcePrepareExpansionMethodVisitor(JavaSourceClass cls, JavaNativeClass nativeClass) {
39
 		this.cls = cls;
41
 		this.cls = cls;
42
+		this.nativeClass = nativeClass;
43
+		cls.empty = true;
40
 	}
44
 	}
41
 	
45
 	
42
 	@Override
46
 	@Override
43
 	public Void visitConst(ConstMember member) {
47
 	public Void visitConst(ConstMember member) {
44
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
48
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
49
+		cls.empty = false;
45
 		return null;
50
 		return null;
46
 	}
51
 	}
47
 	
52
 	
49
 	public Void visitField(FieldMember member) {
54
 	public Void visitField(FieldMember member) {
50
 		// TODO: expansion fields
55
 		// TODO: expansion fields
51
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
56
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
57
+		cls.empty = false;
52
 		return null;
58
 		return null;
53
 	}
59
 	}
54
 
60
 
55
 	@Override
61
 	@Override
56
 	public Void visitConstructor(ConstructorMember member) {
62
 	public Void visitConstructor(ConstructorMember member) {
63
+		visitFunctional(member, "");
57
 		return null;
64
 		return null;
58
 	}
65
 	}
59
 
66
 
60
 	@Override
67
 	@Override
61
 	public Void visitDestructor(DestructorMember member) {
68
 	public Void visitDestructor(DestructorMember member) {
62
-		return null;
69
+		throw new UnsupportedOperationException("Destructors not allowed on expansions");
63
 	}
70
 	}
64
 
71
 
65
 	@Override
72
 	@Override
107
 	@Override
114
 	@Override
108
 	public Void visitImplementation(ImplementationMember member) {
115
 	public Void visitImplementation(ImplementationMember member) {
109
 		// TODO: implementation merge check
116
 		// TODO: implementation merge check
117
+		cls.empty = false;
110
 		return null;
118
 		return null;
111
 	}
119
 	}
112
 
120
 
113
 	@Override
121
 	@Override
114
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
122
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
115
 		// TODO
123
 		// TODO
124
+		cls.empty = false;
116
 		return null;
125
 		return null;
117
 	}
126
 	}
118
 
127
 
119
 	@Override
128
 	@Override
120
 	public Void visitStaticInitializer(StaticInitializerMember member) {
129
 	public Void visitStaticInitializer(StaticInitializerMember member) {
130
+		cls.empty = false;
121
 		return null;
131
 		return null;
122
 	}
132
 	}
123
 	
133
 	
124
 	private void visitFunctional(DefinitionMember member, String name) {
134
 	private void visitFunctional(DefinitionMember member, String name) {
125
-		member.setTag(
126
-				JavaSourceMethod.class,
127
-				new JavaSourceMethod(cls, getKind(member), name));
135
+		NativeTag nativeTag = member.getTag(NativeTag.class);
136
+		JavaSourceMethod method = null;
137
+		if (nativeTag != null && nativeClass != null)
138
+			method = nativeClass.getMethod(nativeTag.value);
139
+		if (method == null)
140
+			method = new JavaSourceMethod(cls, getKind(member), name, true); 
141
+		
142
+		if (method.compile)
143
+			cls.empty = false;
144
+		
145
+		member.setTag(JavaSourceMethod.class, method);
128
 	}
146
 	}
129
 	
147
 	
130
 	private JavaSourceMethod.Kind getKind(DefinitionMember member) {
148
 	private JavaSourceMethod.Kind getKind(DefinitionMember member) {
196
 			case CONTAINS:
214
 			case CONTAINS:
197
 				return "contains";
215
 				return "contains";
198
 			case EQUALS:
216
 			case EQUALS:
199
-				return "equals";
217
+				return "equals_";
200
 			case COMPARE:
218
 			case COMPARE:
201
 				return "compareTo";
219
 				return "compareTo";
202
 			case RANGE:
220
 			case RANGE:

+ 8
- 3
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/scope/JavaSourceFileScope.java View File

12
 import org.openzen.zenscript.javasource.JavaSourceSyntheticHelperGenerator;
12
 import org.openzen.zenscript.javasource.JavaSourceSyntheticHelperGenerator;
13
 import org.openzen.zenscript.javasource.JavaSourceSyntheticTypeGenerator;
13
 import org.openzen.zenscript.javasource.JavaSourceSyntheticTypeGenerator;
14
 import org.openzen.zenscript.javasource.JavaSourceTypeVisitor;
14
 import org.openzen.zenscript.javasource.JavaSourceTypeVisitor;
15
+import org.openzen.zenscript.javasource.tags.JavaSourceClass;
15
 
16
 
16
 /**
17
 /**
17
  *
18
  *
21
 	public final JavaSourceImporter importer;
22
 	public final JavaSourceImporter importer;
22
 	public final JavaSourceSyntheticTypeGenerator typeGenerator;
23
 	public final JavaSourceSyntheticTypeGenerator typeGenerator;
23
 	public final JavaSourceSyntheticHelperGenerator helperGenerator;
24
 	public final JavaSourceSyntheticHelperGenerator helperGenerator;
24
-	public final String className;
25
+	public final JavaSourceClass cls;
25
 	public final JavaSourceTypeVisitor typeVisitor;
26
 	public final JavaSourceTypeVisitor typeVisitor;
26
 	public final JavaSourceObjectTypeVisitor objectTypeVisitor;
27
 	public final JavaSourceObjectTypeVisitor objectTypeVisitor;
27
 	public final TypeScope semanticScope;
28
 	public final TypeScope semanticScope;
31
 			JavaSourceImporter importer, 
32
 			JavaSourceImporter importer, 
32
 			JavaSourceSyntheticTypeGenerator typeGenerator,
33
 			JavaSourceSyntheticTypeGenerator typeGenerator,
33
 			JavaSourceSyntheticHelperGenerator helperGenerator,
34
 			JavaSourceSyntheticHelperGenerator helperGenerator,
34
-			String className,
35
+			JavaSourceClass cls,
35
 			TypeScope semanticScope,
36
 			TypeScope semanticScope,
36
 			boolean isInterface)
37
 			boolean isInterface)
37
 	{
38
 	{
38
 		this.importer = importer;
39
 		this.importer = importer;
39
 		this.typeGenerator = typeGenerator;
40
 		this.typeGenerator = typeGenerator;
40
 		this.helperGenerator = helperGenerator;
41
 		this.helperGenerator = helperGenerator;
41
-		this.className = className;
42
+		this.cls = cls;
42
 		this.semanticScope = semanticScope;
43
 		this.semanticScope = semanticScope;
43
 		this.isInterface = isInterface;
44
 		this.isInterface = isInterface;
44
 		
45
 		
49
 	public String type(ITypeID type) {
50
 	public String type(ITypeID type) {
50
 		return type.accept(typeVisitor);
51
 		return type.accept(typeVisitor);
51
 	}
52
 	}
53
+	
54
+	public String type(ITypeID type, JavaSourceClass rename) {
55
+		return type.accept(new JavaSourceTypeVisitor(importer, typeGenerator, rename));
56
+	}
52
 }
57
 }

+ 4
- 4
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/scope/JavaSourceStatementScope.java View File

74
 		return fileScope.type(type);
74
 		return fileScope.type(type);
75
 	}
75
 	}
76
 	
76
 	
77
-	public String type(JavaSourceClass cls) {
78
-		return fileScope.importer.importType(cls.fullName);
77
+	public String type(ITypeID type, JavaSourceClass renamed) {
78
+		return fileScope.type(type, renamed);
79
 	}
79
 	}
80
 	
80
 	
81
-	public String sourceClass(JavaSourceClass cls) {
82
-		return fileScope.importer.importType(cls.fullName);
81
+	public String type(JavaSourceClass cls) {
82
+		return fileScope.importer.importType(cls);
83
 	}
83
 	}
84
 	
84
 	
85
 	public void addLocalVariable(String localVariable) {
85
 	public void addLocalVariable(String localVariable) {

+ 11
- 3
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/tags/JavaSourceClass.java View File

9
  *
9
  *
10
  * @author Hoofdgebruiker
10
  * @author Hoofdgebruiker
11
  */
11
  */
12
-public class JavaSourceClass {
12
+public class JavaSourceClass implements Comparable<JavaSourceClass> {
13
+	public final String pkg;
13
 	public final String name;
14
 	public final String name;
14
 	public final String fullName;
15
 	public final String fullName;
16
+	public boolean empty = false;
15
 	
17
 	
16
-	public JavaSourceClass(String name, String fullName) {
18
+	public JavaSourceClass(String pkg, String name) {
19
+		this.pkg = pkg;
17
 		this.name = name;
20
 		this.name = name;
18
-		this.fullName = fullName;
21
+		this.fullName = pkg + '.' + name;
22
+	}
23
+
24
+	@Override
25
+	public int compareTo(JavaSourceClass o) {
26
+		return fullName.compareTo(o.fullName);
19
 	}
27
 	}
20
 }
28
 }

+ 5
- 1
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/tags/JavaSourceMethod.java View File

15
 	public final JavaSourceClass cls;
15
 	public final JavaSourceClass cls;
16
 	public final Kind kind;
16
 	public final Kind kind;
17
 	public final String name;
17
 	public final String name;
18
+	public final boolean compile;
18
 	public final JavaCallCompiler compiler;
19
 	public final JavaCallCompiler compiler;
19
 	
20
 	
20
-	public JavaSourceMethod(JavaSourceClass cls, Kind kind, String name) {
21
+	public JavaSourceMethod(JavaSourceClass cls, Kind kind, String name, boolean compile) {
21
 		this.cls = cls;
22
 		this.cls = cls;
22
 		this.kind = kind;
23
 		this.kind = kind;
23
 		this.name = name;
24
 		this.name = name;
25
+		this.compile = compile;
24
 		compiler = null;
26
 		compiler = null;
25
 	}
27
 	}
26
 	
28
 	
28
 		this.cls = null;
30
 		this.cls = null;
29
 		this.kind = Kind.COMPILED;
31
 		this.kind = Kind.COMPILED;
30
 		this.name = null;
32
 		this.name = null;
33
+		this.compile = false;
31
 		this.compiler = compiler;
34
 		this.compiler = compiler;
32
 	}
35
 	}
33
 	
36
 	
35
 		STATIC,
38
 		STATIC,
36
 		INSTANCE,
39
 		INSTANCE,
37
 		EXPANSION,
40
 		EXPANSION,
41
+		CONSTRUCTOR,
38
 		COMPILED
42
 		COMPILED
39
 	}
43
 	}
40
 }
44
 }

+ 2
- 2
Shared/src/main/java/org/openzen/zenscript/shared/ConcatMap.java View File

47
 	}
47
 	}
48
 	
48
 	
49
 	public V get(K key) {
49
 	public V get(K key) {
50
-		if (key == null)
50
+		if (this.key == null)
51
 			return null;
51
 			return null;
52
 		if (key.equals(this.key))
52
 		if (key.equals(this.key))
53
 			return value;
53
 			return value;
56
 	}
56
 	}
57
 	
57
 	
58
 	public V get(K key, V defaultValue) {
58
 	public V get(K key, V defaultValue) {
59
-		if (key == null)
59
+		if (this.key == null)
60
 			return defaultValue;
60
 			return defaultValue;
61
 		if (key.equals(this.key))
61
 		if (key.equals(this.key))
62
 			return value;
62
 			return value;

+ 4
- 1
Validator/src/main/java/org/openzen/zenscript/validator/ValidationLogEntry.java View File

63
 		SETTING_FINAL_VARIABLE,
63
 		SETTING_FINAL_VARIABLE,
64
 		INVALID_SUPERTYPE,
64
 		INVALID_SUPERTYPE,
65
 		MULTIPLE_DESTRUCTORS,
65
 		MULTIPLE_DESTRUCTORS,
66
-		PANIC_ARGUMENT_NO_STRING
66
+		PANIC_ARGUMENT_NO_STRING,
67
+		THROW_WITHOUT_THROWS,
68
+		DESTRUCTOR_CANNOT_THROW,
69
+		STATIC_INITIALIZER_CANNOT_THROW
67
 	}
70
 	}
68
 }
71
 }

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

20
 import org.openzen.zenscript.codemodel.member.DestructorMember;
20
 import org.openzen.zenscript.codemodel.member.DestructorMember;
21
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
21
 import org.openzen.zenscript.codemodel.member.EnumConstantMember;
22
 import org.openzen.zenscript.codemodel.member.FieldMember;
22
 import org.openzen.zenscript.codemodel.member.FieldMember;
23
+import org.openzen.zenscript.codemodel.member.FunctionalMember;
23
 import org.openzen.zenscript.codemodel.member.GetterMember;
24
 import org.openzen.zenscript.codemodel.member.GetterMember;
24
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
25
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
25
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
26
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
107
 		} else {
108
 		} else {
108
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
109
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
109
 			member.body.accept(statementValidator);
110
 			member.body.accept(statementValidator);
110
-			
111
+			validateThrow(member);
112
+				
111
 			if (member.definition.superType != null && !statementValidator.constructorForwarded) {
113
 			if (member.definition.superType != null && !statementValidator.constructorForwarded) {
112
 				validator.logError(ValidationLogEntry.Code.CONSTRUCTOR_FORWARD_MISSING, member.position, "Constructor not forwarded to base type");
114
 				validator.logError(ValidationLogEntry.Code.CONSTRUCTOR_FORWARD_MISSING, member.position, "Constructor not forwarded to base type");
113
 			}
115
 			}
125
 		if (member.body != null) {
127
 		if (member.body != null) {
126
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
128
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
127
 			member.body.accept(statementValidator);
129
 			member.body.accept(statementValidator);
130
+			validateThrow(member);
131
+			
132
+			if (member.header.thrownType != null)
133
+				validator.logError(ValidationLogEntry.Code.DESTRUCTOR_CANNOT_THROW, member.position, "Destructor cannot throw");
128
 		}
134
 		}
129
 		return null;
135
 		return null;
130
 	}
136
 	}
137
 		if (member.body != null) {
143
 		if (member.body != null) {
138
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
144
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
139
 			member.body.accept(statementValidator);
145
 			member.body.accept(statementValidator);
146
+			validateThrow(member);
140
 		}
147
 		}
141
 		return null;
148
 		return null;
142
 	}
149
 	}
149
 		if (member.body != null) {
156
 		if (member.body != null) {
150
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
157
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
151
 			member.body.accept(statementValidator);
158
 			member.body.accept(statementValidator);
159
+			validateThrow(member);
152
 		}
160
 		}
153
 		
161
 		
154
 		return null;
162
 		return null;
162
 		if (member.body != null) {
170
 		if (member.body != null) {
163
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
171
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
164
 			member.body.accept(statementValidator);
172
 			member.body.accept(statementValidator);
173
+			validateThrow(member);
165
 		}
174
 		}
166
 		
175
 		
167
 		return null;
176
 		return null;
186
 		if (member.body != null) {
195
 		if (member.body != null) {
187
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
196
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
188
 			member.body.accept(statementValidator);
197
 			member.body.accept(statementValidator);
198
+			validateThrow(member);
189
 		}
199
 		}
190
 		
200
 		
191
 		return null;
201
 		return null;
198
 		if (member.body != null) {
208
 		if (member.body != null) {
199
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
209
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
200
 			member.body.accept(statementValidator);
210
 			member.body.accept(statementValidator);
211
+			validateThrow(member);
201
 		}
212
 		}
202
 		
213
 		
203
 		return null;
214
 		return null;
216
 		if (member.body != null) {
227
 		if (member.body != null) {
217
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
228
 			StatementValidator statementValidator = new StatementValidator(validator, new ConstructorStatementScope(member.header));
218
 			member.body.accept(statementValidator);
229
 			member.body.accept(statementValidator);
230
+			validateThrow(member);
219
 		}
231
 		}
220
 		
232
 		
221
 		return null;
233
 		return null;
255
 	@Override
267
 	@Override
256
 	public Void visitStaticInitializer(StaticInitializerMember member) {
268
 	public Void visitStaticInitializer(StaticInitializerMember member) {
257
 		member.body.accept(new StatementValidator(validator, new StaticInitializerScope()));
269
 		member.body.accept(new StatementValidator(validator, new StaticInitializerScope()));
270
+		if (member.body.thrownType != null)
271
+			validator.logError(ValidationLogEntry.Code.STATIC_INITIALIZER_CANNOT_THROW, member.position, "Static initializer cannot throw");
258
 		return null;
272
 		return null;
259
 	}
273
 	}
260
 	
274
 	
275
+	private void validateThrow(FunctionalMember member) {
276
+		if (member.body.thrownType != null && member.header.thrownType == null) // TODO: validate thrown type
277
+			validator.logError(ValidationLogEntry.Code.THROW_WITHOUT_THROWS, member.position, "Method is throwing but doesn't declare throws type");
278
+	}
279
+	
261
 	private class FieldInitializerScope implements ExpressionScope {
280
 	private class FieldInitializerScope implements ExpressionScope {
262
 		private final FieldMember field;
281
 		private final FieldMember field;
263
 		
282
 		

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

449
 	@Override
449
 	@Override
450
 	public Void visitPanic(PanicExpression expression) {
450
 	public Void visitPanic(PanicExpression expression) {
451
 		expression.value.accept(this);
451
 		expression.value.accept(this);
452
-		if (expression.type != BasicTypeID.STRING)
452
+		if (expression.value.type != BasicTypeID.STRING)
453
 			validator.logError(ValidationLogEntry.Code.PANIC_ARGUMENT_NO_STRING, expression.position, "Argument to a panic must be a string");
453
 			validator.logError(ValidationLogEntry.Code.PANIC_ARGUMENT_NO_STRING, expression.position, "Argument to a panic must be a string");
454
 		return null;
454
 		return null;
455
 	}
455
 	}

Loading…
Cancel
Save