Преглед на файлове

- Continued work on the code formatter

- Static calls now remember the exact type they are called for
Stan Hebben преди 6 години
родител
ревизия
ba568c23b7
променени са 18 файла, в които са добавени 313 реда и са изтрити 188 реда
  1. 65
    3
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/DefinitionFormatter.java
  2. 20
    37
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java
  3. 19
    7
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FileFormatter.java
  4. 33
    2
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FormattingUtils.java
  5. 26
    1
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/MemberFormatter.java
  6. 75
    73
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/StatementFormatter.java
  7. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/WhitespaceInfo.java
  8. 4
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallStaticExpression.java
  9. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/EqualsMember.java
  10. 5
    5
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FunctionalMember.java
  11. 3
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ICallableMember.java
  12. 2
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/builtin/ComparatorMember.java
  13. 6
    4
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialStaticMemberGroupExpression.java
  14. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialTypeExpression.java
  15. 4
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java
  16. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java
  17. 3
    3
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java
  18. 42
    39
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatement.java

+ 65
- 3
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/DefinitionFormatter.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.formatter;
7 7
 
8
+import java.util.List;
8 9
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
9 10
 import org.openzen.zenscript.codemodel.definition.ClassDefinition;
10 11
 import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
@@ -13,6 +14,8 @@ import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
13 14
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
14 15
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
15 16
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
17
+import org.openzen.zenscript.codemodel.expression.CallArguments;
18
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
16 19
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
17 20
 
18 21
 /**
@@ -48,12 +51,12 @@ public class DefinitionFormatter implements DefinitionVisitor<Void> {
48 51
 		} else {
49 52
 			output.append("\n")
50 53
 					.append(indent)
51
-					.append("{\n")
52
-					.append(indent + settings.indent);
54
+					.append("{\n");
53 55
 		}
54 56
 		
57
+		MemberFormatter memberFormatter = new MemberFormatter(settings, output, indent + settings.indent, typeFormatter);
55 58
 		for (IDefinitionMember member : definition.members) {
56
-			member.accept(new MemberFormatter(settings, output, indent + settings.indent, typeFormatter));
59
+			member.accept(memberFormatter);
57 60
 		}
58 61
 		
59 62
 		output.append("}\n");
@@ -62,12 +65,70 @@ public class DefinitionFormatter implements DefinitionVisitor<Void> {
62 65
 
63 66
 	@Override
64 67
 	public Void visitInterface(InterfaceDefinition definition) {
68
+		FormattingUtils.formatModifiers(output, definition.modifiers);
69
+		output.append("class ");
70
+		output.append(definition.name);
71
+		FormattingUtils.formatTypeParameters(output, definition.genericParameters, typeFormatter);
72
+		output.append(" ");
73
+		
74
+		if (settings.classBracketOnSameLine) {
75
+			output.append("{\n");
76
+		} else {
77
+			output.append("\n")
78
+					.append(indent)
79
+					.append("{\n");
80
+		}
65 81
 		
82
+		MemberFormatter memberFormatter = new MemberFormatter(settings, output, indent + settings.indent, typeFormatter);
83
+		for (IDefinitionMember member : definition.members) {
84
+			member.accept(memberFormatter);
85
+		}
86
+		
87
+		output.append("}\n");
66 88
 		return null;
67 89
 	}
68 90
 
69 91
 	@Override
70 92
 	public Void visitEnum(EnumDefinition definition) {
93
+		FormattingUtils.formatModifiers(output, definition.modifiers);
94
+		output.append("enum ");
95
+		output.append(definition.name);
96
+		FormattingUtils.formatTypeParameters(output, definition.genericParameters, typeFormatter);
97
+		output.append(" ");
98
+		
99
+		if (settings.classBracketOnSameLine) {
100
+			output.append("{\n");
101
+		} else {
102
+			output.append("\n")
103
+					.append(indent)
104
+					.append("{\n");
105
+		}
106
+		
107
+		List<EnumConstantMember> enumConstants = definition.getEnumConstants();
108
+		boolean first = true;
109
+		ExpressionFormatter expressionFormatter = new ExpressionFormatter(settings, typeFormatter);
110
+		for (EnumConstantMember enumConstant : enumConstants) {
111
+			if (first)
112
+				first = false;
113
+			else
114
+				output.append(",\n");
115
+			
116
+			output.append(indent).append(settings.indent).append(enumConstant.name);
117
+			if (enumConstant.constructor != null) {
118
+				FormattingUtils.formatCall(output, typeFormatter, expressionFormatter, enumConstant.constructor.arguments);
119
+			}
120
+		}
121
+		
122
+		if (definition.members.size() > enumConstants.size()) {
123
+			output.append(";\n").append(indent).append(settings.indent).append("\n");
124
+
125
+			MemberFormatter memberFormatter = new MemberFormatter(settings, output, indent + settings.indent, typeFormatter);
126
+			for (IDefinitionMember member : definition.members) {
127
+				member.accept(memberFormatter);
128
+			}
129
+		}
130
+		
131
+		output.append("}\n");
71 132
 		return null;
72 133
 	}
73 134
 
@@ -96,6 +157,7 @@ public class DefinitionFormatter implements DefinitionVisitor<Void> {
96 157
 		return null;
97 158
 	}
98 159
 	
160
+	@Override
99 161
 	public String toString() {
100 162
 		return output.toString();
101 163
 	}

+ 20
- 37
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java Целия файл

@@ -5,10 +5,10 @@
5 5
  */
6 6
 package org.openzen.zenscript.formatter;
7 7
 
8
+import org.openzen.zenscript.codemodel.OperatorType;
8 9
 import org.openzen.zenscript.codemodel.expression.AndAndExpression;
9 10
 import org.openzen.zenscript.codemodel.expression.ArrayExpression;
10 11
 import org.openzen.zenscript.codemodel.expression.BasicCompareExpression;
11
-import org.openzen.zenscript.codemodel.expression.CallArguments;
12 12
 import org.openzen.zenscript.codemodel.expression.CallExpression;
13 13
 import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
14 14
 import org.openzen.zenscript.codemodel.expression.CapturedClosureExpression;
@@ -220,7 +220,7 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
220 220
 				case CALL: {
221 221
 					StringBuilder result = new StringBuilder();
222 222
 					result.append(".");
223
-					format(result, expression.arguments);
223
+					FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
224 224
 					return new ExpressionString(result.toString(), OperatorPriority.CALL);
225 225
 				}
226 226
 				case CAST: {
@@ -237,7 +237,7 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
237 237
 			result.append(expression.target.accept(this).value);
238 238
 			result.append(".");
239 239
 			result.append(expression.member.name);
240
-			format(result, expression.arguments);
240
+			FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
241 241
 			return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
242 242
 		}
243 243
 	}
@@ -245,38 +245,21 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
245 245
 	@Override
246 246
 	public ExpressionString visitCallStatic(CallStaticExpression expression) {
247 247
 		StringBuilder result = new StringBuilder();
248
-		result.append(expression.type.accept(typeFormatter));
249
-		result.append(".");
250
-		result.append(expression.member.name);
251
-		format(result, expression.arguments);
252
-		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
253
-	}
254
-	
255
-	private void format(StringBuilder result, CallArguments arguments) {
256
-		if (arguments == null || arguments.typeArguments == null)
257
-			throw new IllegalArgumentException("Arguments cannot be null!");
258
-		
259
-		if (arguments.typeArguments.length > 0) {
260
-			result.append("<");
261
-			
262
-			int index = 0;
263
-			for (ITypeID typeArgument : arguments.typeArguments) {
264
-				if (index > 0)
265
-					result.append(", ");
266
-				result.append(typeArgument.accept(typeFormatter));
267
-				index++;
248
+		result.append(expression.target.accept(typeFormatter));
249
+		if (expression.member instanceof OperatorMember) {
250
+			OperatorMember operator = (OperatorMember) expression.member;
251
+			if (operator.operator == OperatorType.CALL) {
252
+				// nothing
253
+			} else {
254
+				result.append(".");
255
+				result.append(expression.member.name);
268 256
 			}
269
-			result.append(">");
270
-		}
271
-		result.append("(");
272
-		int index = 0;
273
-		for (Expression argument : arguments.arguments) {
274
-			if (index > 0)
275
-				result.append(", ");
276
-			result.append(argument.accept(this).value);
277
-			index++;
257
+		} else {
258
+			result.append(".");
259
+			result.append(expression.member.name);
278 260
 		}
279
-		result.append(")");
261
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
262
+		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
280 263
 	}
281 264
 
282 265
 	@Override
@@ -410,7 +393,7 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
410 393
 	public ExpressionString visitConstructorThisCall(ConstructorThisCallExpression expression) {
411 394
 		StringBuilder result = new StringBuilder();
412 395
 		result.append("this");
413
-		format(result, expression.arguments);
396
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
414 397
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
415 398
 	}
416 399
 
@@ -418,7 +401,7 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
418 401
 	public ExpressionString visitConstructorSuperCall(ConstructorSuperCallExpression expression) {
419 402
 		StringBuilder result = new StringBuilder();
420 403
 		result.append("super");
421
-		format(result, expression.arguments);
404
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
422 405
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
423 406
 	}
424 407
 
@@ -483,7 +466,7 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
483 466
 	public ExpressionString visitGlobalCall(GlobalCallExpression expression) {
484 467
 		StringBuilder result = new StringBuilder();
485 468
 		result.append(expression.name);
486
-		format(result, expression.arguments);
469
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
487 470
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
488 471
 	}
489 472
 
@@ -530,7 +513,7 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
530 513
 		StringBuilder result = new StringBuilder();
531 514
 		result.append("new ");
532 515
 		result.append(expression.type.accept(typeFormatter));
533
-		format(result, expression.arguments);
516
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
534 517
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
535 518
 	}
536 519
 

+ 19
- 7
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FileFormatter.java Целия файл

@@ -41,7 +41,8 @@ public class FileFormatter {
41 41
 			definitionFormatters.add(definitionFormatter);
42 42
 		}
43 43
 		
44
-		StatementFormatter scriptFormatter = new StatementFormatter("", settings, expressionFormatter);
44
+		StringBuilder scriptOutput = new StringBuilder();
45
+		StatementFormatter scriptFormatter = new StatementFormatter(scriptOutput, "", settings, expressionFormatter);
45 46
 		for (Statement statement : script.statements) {
46 47
 			statement.accept(scriptFormatter);
47 48
 		}
@@ -49,16 +50,27 @@ public class FileFormatter {
49 50
 		StringBuilder output = new StringBuilder();
50 51
 		importer.write(output);
51 52
 		
53
+		boolean first = true;
52 54
 		for (DefinitionFormatter definition : definitionFormatters) {
55
+			if (first)
56
+				first = false;
57
+			else
58
+				output.append("\n");
59
+			
53 60
 			output.append(definition.toString());
54 61
 		}
55 62
 		
56
-		output.append(scriptFormatter.toString().trim());
57
-		
58
-		WhitespacePostComment postComment = script.getTag(WhitespacePostComment.class);
59
-		if (postComment != null) {
60
-			for (String comment : CommentFormatter.format(postComment.comments)) {
61
-				output.append("\n").append(comment);
63
+		if (script.statements.size() > 0) {
64
+			if (definitionFormatters.size() > 0)
65
+				output.append("\n");
66
+			
67
+			output.append(scriptOutput.toString().trim());
68
+
69
+			WhitespacePostComment postComment = script.getTag(WhitespacePostComment.class);
70
+			if (postComment != null) {
71
+				for (String comment : CommentFormatter.format(postComment.comments)) {
72
+					output.append("\n").append(comment);
73
+				}
62 74
 			}
63 75
 		}
64 76
 		

+ 33
- 2
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FormattingUtils.java Целия файл

@@ -8,6 +8,8 @@ package org.openzen.zenscript.formatter;
8 8
 import org.openzen.zenscript.codemodel.FunctionHeader;
9 9
 import org.openzen.zenscript.codemodel.FunctionParameter;
10 10
 import org.openzen.zenscript.codemodel.Modifiers;
11
+import org.openzen.zenscript.codemodel.expression.CallArguments;
12
+import org.openzen.zenscript.codemodel.expression.Expression;
11 13
 import org.openzen.zenscript.codemodel.generic.GenericParameterBound;
12 14
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
13 15
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
@@ -27,6 +29,7 @@ import org.openzen.zenscript.codemodel.statement.TryCatchStatement;
27 29
 import org.openzen.zenscript.codemodel.statement.VarStatement;
28 30
 import org.openzen.zenscript.codemodel.statement.WhileStatement;
29 31
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
32
+import org.openzen.zenscript.codemodel.type.ITypeID;
30 33
 
31 34
 /**
32 35
  *
@@ -113,6 +116,34 @@ public class FormattingUtils {
113 116
 	
114 117
 	public static void formatBody(StringBuilder output, FormattingSettings settings, String indent, TypeFormatter typeFormatter, Statement body) {
115 118
 		body.accept(new BodyFormatter(output, settings, indent, typeFormatter));
119
+		output.append("\n");
120
+	}
121
+	
122
+	public static void formatCall(StringBuilder result, TypeFormatter typeFormatter, ExpressionFormatter expressionFormatter, CallArguments arguments) {
123
+		if (arguments == null || arguments.typeArguments == null)
124
+			throw new IllegalArgumentException("Arguments cannot be null!");
125
+		
126
+		if (arguments.typeArguments.length > 0) {
127
+			result.append("<");
128
+			
129
+			int index = 0;
130
+			for (ITypeID typeArgument : arguments.typeArguments) {
131
+				if (index > 0)
132
+					result.append(", ");
133
+				result.append(typeArgument.accept(typeFormatter));
134
+				index++;
135
+			}
136
+			result.append(">");
137
+		}
138
+		result.append("(");
139
+		int index = 0;
140
+		for (Expression argument : arguments.arguments) {
141
+			if (index > 0)
142
+				result.append(", ");
143
+			result.append(argument.accept(expressionFormatter).value);
144
+			index++;
145
+		}
146
+		result.append(")");
116 147
 	}
117 148
 	
118 149
 	private static class BodyFormatter implements StatementVisitor<Void> {
@@ -128,7 +159,7 @@ public class FormattingUtils {
128 159
 			this.indent = indent;
129 160
 			this.typeFormatter = typeFormatter;
130 161
 			
131
-			statementFormatter = new StatementFormatter(indent + settings.indent, settings, new ExpressionFormatter(settings, typeFormatter)); 
162
+			statementFormatter = new StatementFormatter(output, indent, settings, new ExpressionFormatter(settings, typeFormatter)); 
132 163
 		}
133 164
 
134 165
 		@Override
@@ -153,7 +184,7 @@ public class FormattingUtils {
153 184
 
154 185
 		@Override
155 186
 		public Void visitEmpty(EmptyStatement statement) {
156
-			output.append(";\n");
187
+			output.append(";");
157 188
 			return null;
158 189
 		}
159 190
 

+ 26
- 1
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/MemberFormatter.java Целия файл

@@ -33,6 +33,8 @@ public class MemberFormatter implements MemberVisitor<Void> {
33 33
 	private final StringBuilder output;
34 34
 	private final String indent;
35 35
 	private final TypeFormatter typeFormatter;
36
+	private boolean isFirst = true;
37
+	private boolean wasField = false;
36 38
 	
37 39
 	public MemberFormatter(FormattingSettings settings, StringBuilder output, String indent, TypeFormatter typeFormatter) {
38 40
 		this.settings = settings;
@@ -40,9 +42,22 @@ public class MemberFormatter implements MemberVisitor<Void> {
40 42
 		this.indent = indent;
41 43
 		this.typeFormatter = typeFormatter;
42 44
 	}
45
+	
46
+	private void visit(boolean field) {
47
+		output.append(indent);
48
+		
49
+		if (isFirst) {
50
+			isFirst = false;
51
+		} else if (!field || (wasField != field)) {
52
+			output.append("\n").append(indent);
53
+		}
54
+		
55
+		wasField = field;
56
+	}
43 57
 
44 58
 	@Override
45 59
 	public Void visitField(FieldMember member) {
60
+		visit(true);
46 61
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
47 62
 		output.append(member.isFinal() ? "val " : "var ")
48 63
 				.append(member.name)
@@ -53,12 +68,13 @@ public class MemberFormatter implements MemberVisitor<Void> {
53 68
 			output.append(" = ")
54 69
 					.append(member.initializer.accept(new ExpressionFormatter(settings, typeFormatter)));
55 70
 		}
56
-		output.append(";").append("\n").append(indent);
71
+		output.append(";").append("\n");
57 72
 		return null;
58 73
 	}
59 74
 
60 75
 	@Override
61 76
 	public Void visitConstructor(ConstructorMember member) {
77
+		visit(false);
62 78
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
63 79
 		output.append("this");
64 80
 		FormattingUtils.formatHeader(output, settings, member.header, typeFormatter);
@@ -68,6 +84,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
68 84
 
69 85
 	@Override
70 86
 	public Void visitMethod(MethodMember member) {
87
+		visit(false);
71 88
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
72 89
 		output.append(member.name);
73 90
 		FormattingUtils.formatHeader(output, settings, member.header, typeFormatter);
@@ -77,6 +94,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
77 94
 
78 95
 	@Override
79 96
 	public Void visitGetter(GetterMember member) {
97
+		visit(false);
80 98
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
81 99
 		output.append("get ");
82 100
 		output.append(member.name);
@@ -88,6 +106,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
88 106
 
89 107
 	@Override
90 108
 	public Void visitSetter(SetterMember member) {
109
+		visit(false);
91 110
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
92 111
 		output.append("set ");
93 112
 		output.append(member.name);
@@ -104,6 +123,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
104 123
 
105 124
 	@Override
106 125
 	public Void visitOperator(OperatorMember member) {
126
+		visit(false);
107 127
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
108 128
 		switch (member.operator) {
109 129
 			case ADD: output.append("+"); break;
@@ -145,6 +165,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
145 165
 
146 166
 	@Override
147 167
 	public Void visitCaster(CasterMember member) {
168
+		visit(false);
148 169
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
149 170
 		output.append(" as ");
150 171
 		output.append(member.toType.accept(typeFormatter));
@@ -154,11 +175,13 @@ public class MemberFormatter implements MemberVisitor<Void> {
154 175
 
155 176
 	@Override
156 177
 	public Void visitCustomIterator(CustomIteratorMember member) {
178
+		visit(false);
157 179
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
158 180
 	}
159 181
 
160 182
 	@Override
161 183
 	public Void visitCaller(CallerMember member) {
184
+		visit(false);
162 185
 		FormattingUtils.formatModifiers(output, member.modifiers & ~Modifiers.FINAL);
163 186
 		FormattingUtils.formatHeader(output, settings, member.header, typeFormatter);
164 187
 		formatBody(member.body);
@@ -167,6 +190,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
167 190
 
168 191
 	@Override
169 192
 	public Void visitImplementation(ImplementationMember implementation) {
193
+		visit(false);
170 194
 		FormattingUtils.formatModifiers(output, implementation.modifiers & ~Modifiers.FINAL);
171 195
 		output.append("implements ");
172 196
 		output.append(implementation.type.accept(typeFormatter));
@@ -186,6 +210,7 @@ public class MemberFormatter implements MemberVisitor<Void> {
186 210
 
187 211
 	@Override
188 212
 	public Void visitInnerDefinition(InnerDefinitionMember member) {
213
+		visit(false);
189 214
 		String formatted = member.innerDefinition.accept(new DefinitionFormatter(settings, typeFormatter, indent + settings.indent)).toString();
190 215
 		output.append(formatted);
191 216
 		return null;

+ 75
- 73
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/StatementFormatter.java Целия файл

@@ -33,22 +33,22 @@ import org.openzen.zenscript.codemodel.type.BasicTypeID;
33 33
  */
34 34
 public class StatementFormatter implements StatementVisitor<Void> {
35 35
 	private final FormattingSettings settings;
36
-	private final StringBuilder result;
36
+	private final StringBuilder output;
37 37
 	private final ExpressionFormatter expressionFormatter;
38 38
 	
39 39
 	private String indent;
40 40
 	private ParentStatementType position = ParentStatementType.NONE;
41 41
 	
42
-	public StatementFormatter(String indent, FormattingSettings settings, ExpressionFormatter expressionFormatter) {
42
+	public StatementFormatter(StringBuilder output, String indent, FormattingSettings settings, ExpressionFormatter expressionFormatter) {
43
+		this.output = output;
43 44
 		this.indent = indent;
44 45
 		this.settings = settings;
45
-		result = new StringBuilder();
46 46
 		this.expressionFormatter = expressionFormatter;
47 47
 	}
48 48
 	
49 49
 	@Override
50 50
 	public String toString() {
51
-		return result.toString();
51
+		return output.toString();
52 52
 	}
53 53
 
54 54
 	@Override
@@ -77,10 +77,10 @@ public class StatementFormatter implements StatementVisitor<Void> {
77 77
 	public Void visitBreak(BreakStatement statement) {
78 78
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
79 79
 		beginSingleLine(whitespace);
80
-		result.append("break");
80
+		output.append("break");
81 81
 		if (statement.target.label != null)
82
-			result.append(' ').append(statement.target.label);
83
-		result.append(";");
82
+			output.append(' ').append(statement.target.label);
83
+		output.append(";");
84 84
 		endSingleLine(whitespace);
85 85
 		return null;
86 86
 	}
@@ -89,10 +89,10 @@ public class StatementFormatter implements StatementVisitor<Void> {
89 89
 	public Void visitContinue(ContinueStatement statement) {
90 90
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
91 91
 		beginSingleLine(whitespace);
92
-		result.append("continue");
92
+		output.append("continue");
93 93
 		if (statement.target.label != null)
94
-			result.append(' ').append(statement.target.label);
95
-		result.append(";");
94
+			output.append(' ').append(statement.target.label);
95
+		output.append(";");
96 96
 		endSingleLine(whitespace);
97 97
 		return null;
98 98
 	}
@@ -101,19 +101,19 @@ public class StatementFormatter implements StatementVisitor<Void> {
101 101
 	public Void visitDoWhile(DoWhileStatement statement) {
102 102
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
103 103
 		beginSingleLine(whitespace);
104
-		result.append("do");
104
+		output.append("do");
105 105
 		if (statement.label != null) {
106 106
 			if (settings.spaceBeforeLabelColon)
107
-				result.append(' ');
108
-			result.append(':');
107
+				output.append(' ');
108
+			output.append(':');
109 109
 			if (settings.spaceAfterLabelColon)
110
-				result.append(' ');
111
-			result.append(statement.label);
110
+				output.append(' ');
111
+			output.append(statement.label);
112 112
 		}
113 113
 		format(ParentStatementType.LOOP, statement.content);
114
-		result.append(" while ");
114
+		output.append(" while ");
115 115
 		appendCondition(statement.condition);
116
-		result.append(";");
116
+		output.append(";");
117 117
 		endSingleLine(whitespace);
118 118
 		return null;
119 119
 	}
@@ -122,7 +122,7 @@ public class StatementFormatter implements StatementVisitor<Void> {
122 122
 	public Void visitEmpty(EmptyStatement statement) {
123 123
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
124 124
 		beginSingleLine(whitespace);
125
-		result.append(";\n");
125
+		output.append(";\n");
126 126
 		endSingleLine(whitespace);
127 127
 		return null;
128 128
 	}
@@ -131,7 +131,7 @@ public class StatementFormatter implements StatementVisitor<Void> {
131 131
 	public Void visitExpression(ExpressionStatement statement) {
132 132
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
133 133
 		beginSingleLine(whitespace);
134
-		result.append(statement.expression.accept(expressionFormatter).value)
134
+		output.append(statement.expression.accept(expressionFormatter).value)
135 135
 			  .append(";");
136 136
 		endSingleLine(whitespace);
137 137
 		return null;
@@ -141,15 +141,15 @@ public class StatementFormatter implements StatementVisitor<Void> {
141 141
 	public Void visitForeach(ForeachStatement statement) {
142 142
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
143 143
 		beginSingleLine(whitespace);
144
-		result.append("for ");
144
+		output.append("for ");
145 145
 		for (int i = 0; i < statement.loopVariables.length; i++) {
146 146
 			if (i > 0)
147
-				result.append(", ");
147
+				output.append(", ");
148 148
 			
149
-			result.append(statement.loopVariables[i].name);
149
+			output.append(statement.loopVariables[i].name);
150 150
 		}
151
-		result.append(" in ");
152
-		result.append(statement.list.accept(expressionFormatter).value);
151
+		output.append(" in ");
152
+		output.append(statement.list.accept(expressionFormatter).value);
153 153
 		format(ParentStatementType.LOOP, statement.content);
154 154
 		endSingleLine(whitespace);
155 155
 		return null;
@@ -160,11 +160,11 @@ public class StatementFormatter implements StatementVisitor<Void> {
160 160
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
161 161
 		ParentStatementType position = this.position;
162 162
 		beginSingleLine(whitespace);
163
-		result.append("if ");
163
+		output.append("if ");
164 164
 		appendCondition(statement.condition);
165 165
 		format(statement.onElse == null ? ParentStatementType.IF : ParentStatementType.IF_WITH_ELSE, statement.onThen);
166 166
 		if (statement.onElse != null) {
167
-			result.append("else");
167
+			output.append("else");
168 168
 			format(ParentStatementType.ELSE, statement.onElse);
169 169
 		}
170 170
 		endSingleLine(whitespace);
@@ -175,8 +175,8 @@ public class StatementFormatter implements StatementVisitor<Void> {
175 175
 	public Void visitLock(LockStatement statement) {
176 176
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
177 177
 		beginSingleLine(whitespace);
178
-		result.append("lock ");
179
-		result.append(statement.object.accept(expressionFormatter).value);
178
+		output.append("lock ");
179
+		output.append(statement.object.accept(expressionFormatter).value);
180 180
 		statement.content.accept(this);
181 181
 		endSingleLine(whitespace);
182 182
 		return null;
@@ -186,12 +186,12 @@ public class StatementFormatter implements StatementVisitor<Void> {
186 186
 	public Void visitReturn(ReturnStatement statement) {
187 187
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
188 188
 		beginSingleLine(whitespace);
189
-		result.append("return");
189
+		output.append("return");
190 190
 		if (statement.value != null) {
191
-			result.append(' ');
192
-			result.append(statement.value.accept(expressionFormatter).value);
191
+			output.append(' ');
192
+			output.append(statement.value.accept(expressionFormatter).value);
193 193
 		}
194
-		result.append(";");
194
+		output.append(";");
195 195
 		endSingleLine(whitespace);
196 196
 		return null;
197 197
 	}
@@ -200,7 +200,7 @@ public class StatementFormatter implements StatementVisitor<Void> {
200 200
 	public Void visitThrow(ThrowStatement statement) {
201 201
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
202 202
 		beginSingleLine(whitespace);
203
-		result.append("throw ").append(statement.value.accept(expressionFormatter));
203
+		output.append("throw ").append(statement.value.accept(expressionFormatter));
204 204
 		endSingleLine(whitespace);
205 205
 		return null;
206 206
 	}
@@ -209,28 +209,28 @@ public class StatementFormatter implements StatementVisitor<Void> {
209 209
 	public Void visitTryCatch(TryCatchStatement statement) {
210 210
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
211 211
 		beginSingleLine(whitespace);
212
-		result.append("try");
212
+		output.append("try");
213 213
 		if (statement.resource != null) {
214
-			result.append(' ').append(statement.resource.name);
215
-			result.append(" = ");
216
-			result.append(statement.resource.initializer.accept(expressionFormatter).value);
214
+			output.append(' ').append(statement.resource.name);
215
+			output.append(" = ");
216
+			output.append(statement.resource.initializer.accept(expressionFormatter).value);
217 217
 		}
218 218
 		
219 219
 		format(ParentStatementType.TRY, statement.content);
220 220
 		
221 221
 		for (CatchClause catchClause : statement.catchClauses) {
222
-			result.append(indent).append("catch ");
222
+			output.append(indent).append("catch ");
223 223
 			if (catchClause.exceptionName != null)
224
-				result.append(catchClause.exceptionName);
224
+				output.append(catchClause.exceptionName);
225 225
 			if (catchClause.exceptionType != BasicTypeID.ANY) {
226
-				result.append(" as ");
226
+				output.append(" as ");
227 227
 				catchClause.exceptionType.accept(expressionFormatter.typeFormatter);
228 228
 			}
229 229
 			
230 230
 			format(ParentStatementType.CATCH, catchClause.content);
231 231
 		}
232 232
 		if (statement.finallyClause != null) {
233
-			result.append(indent).append("finally ");
233
+			output.append(indent).append("finally ");
234 234
 			
235 235
 			format(ParentStatementType.FINALLY, statement.finallyClause);
236 236
 		}
@@ -242,18 +242,18 @@ public class StatementFormatter implements StatementVisitor<Void> {
242 242
 	public Void visitVar(VarStatement statement) {
243 243
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
244 244
 		beginSingleLine(whitespace);
245
-		result.append(statement.isFinal ? "val " : "var ");
246
-		result.append(statement.name);
245
+		output.append(statement.isFinal ? "val " : "var ");
246
+		output.append(statement.name);
247 247
 		
248 248
 		if (statement.initializer == null || statement.initializer.type != statement.type) {
249
-			result.append(" as ");
250
-			result.append(statement.type.accept(expressionFormatter.typeFormatter));
249
+			output.append(" as ");
250
+			output.append(statement.type.accept(expressionFormatter.typeFormatter));
251 251
 		}
252 252
 		if (statement.initializer != null) {
253
-			result.append(" = ");
254
-			result.append(statement.initializer.accept(expressionFormatter).value);
253
+			output.append(" = ");
254
+			output.append(statement.initializer.accept(expressionFormatter).value);
255 255
 		}
256
-		result.append(";");
256
+		output.append(";");
257 257
 		endSingleLine(whitespace);
258 258
 		return null;
259 259
 	}
@@ -262,16 +262,16 @@ public class StatementFormatter implements StatementVisitor<Void> {
262 262
 	public Void visitWhile(WhileStatement statement) {
263 263
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
264 264
 		beginSingleLine(whitespace);
265
-		result.append("while");
265
+		output.append("while");
266 266
 		if (statement.label != null) {
267 267
 			if (settings.spaceBeforeLabelColon)
268
-				result.append(' ');
269
-			result.append(':');
268
+				output.append(' ');
269
+			output.append(':');
270 270
 			if (settings.spaceAfterLabelColon)
271
-				result.append(' ');
272
-			result.append(statement.label);
271
+				output.append(' ');
272
+			output.append(statement.label);
273 273
 		}
274
-		result.append(' ');
274
+		output.append(' ');
275 275
 		appendCondition(statement.condition);
276 276
 		
277 277
 		format(ParentStatementType.LOOP, statement.content);
@@ -288,42 +288,44 @@ public class StatementFormatter implements StatementVisitor<Void> {
288 288
 	
289 289
 	private void appendCondition(Expression condition) {
290 290
 		if (settings.bracketsAroundConditions)
291
-			result.append('(');
292
-		result.append(condition.accept(expressionFormatter).value);
291
+			output.append('(');
292
+		output.append(condition.accept(expressionFormatter).value);
293 293
 		if (settings.bracketsAroundConditions)
294
-			result.append(')');
294
+			output.append(')');
295 295
 	}
296 296
 	
297 297
 	private void beginBlock(WhitespaceInfo whitespace) {
298
-		result.append(settings.getBlockSeparator(indent, position));
298
+		if (whitespace != null && whitespace.emptyLine) {
299
+			output.append("\n").append(indent);
300
+		}
299 301
 		
300
-		if (whitespace != null) {
301
-			if (whitespace.emptyLine) {
302
-				result.append("\n").append(indent);
303
-			}
302
+		String separator = settings.getBlockSeparator(indent, position);
303
+		output.append(separator);
304
+		
305
+		if (whitespace != null)
304 306
 			writeComments(whitespace.commentsBefore);
305
-		}
306 307
 	}
307 308
 	
308 309
 	private void endBlock(WhitespaceInfo whitespace) {
309 310
 		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
310
-			result.append(' ').append(whitespace.commentsAfter);
311
+			output.append(' ').append(whitespace.commentsAfter);
311 312
 		
312
-		result.append("\n").append(indent).append("}");
313
+		output.append("\n").append(indent).append("}");
313 314
 		if (position == ParentStatementType.IF_WITH_ELSE) {
314 315
 			if (settings.elseBracketOnSameLine)
315
-				result.append(" ");
316
+				output.append(" ");
316 317
 			else
317
-				result.append("\n").append(indent);
318
+				output.append("\n").append(indent);
318 319
 		}
319 320
 	}
320 321
 	
321 322
 	private void beginSingleLine(WhitespaceInfo whitespace) {
322
-		result.append(settings.getSingleLineSeparator(indent, position));
323
+		String separator = settings.getSingleLineSeparator(indent, position);
324
+		output.append(separator);
323 325
 		
324 326
 		if (whitespace != null) {
325 327
 			if (whitespace.emptyLine) {
326
-				result.append("\n").append(indent);
328
+				output.append("\n").append(indent);
327 329
 			}
328 330
 			writeComments(whitespace.commentsBefore);
329 331
 		}
@@ -331,21 +333,21 @@ public class StatementFormatter implements StatementVisitor<Void> {
331 333
 	
332 334
 	private void endSingleLine(WhitespaceInfo whitespace) {
333 335
 		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
334
-			result.append(' ').append(whitespace.commentsAfter);
336
+			output.append(' ').append(whitespace.commentsAfter);
335 337
 		
336 338
 		if (position == ParentStatementType.IF_WITH_ELSE)
337
-			result.append("\n").append(indent);
339
+			output.append("\n").append(indent);
338 340
 	}
339 341
 	
340 342
 	private void writeComments(String[] comments) {
341 343
 		for (String comment : CommentFormatter.format(comments)) {
342
-			result.append(comment).append("\n").append(indent);
344
+			output.append(comment).append("\n").append(indent);
343 345
 		}
344 346
 	}
345 347
 	
346 348
 	private void writePostComments(String[] comments) {
347 349
 		for (String comment : CommentFormatter.format(comments)) {
348
-			result.append("\n").append(indent).append(comment);
350
+			output.append("\n").append(indent).append(comment);
349 351
 		}
350 352
 	}
351 353
 }

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/WhitespaceInfo.java Целия файл

@@ -14,7 +14,7 @@ import org.openzen.zenscript.shared.StringUtils;
14 14
  * @author Hoofdgebruiker
15 15
  */
16 16
 public class WhitespaceInfo {
17
-	public static WhitespaceInfo from(String whitespaceBefore, String lineAfter) {
17
+	public static WhitespaceInfo from(String whitespaceBefore, String lineAfter, boolean skipLineBefore) {
18 18
 		int numNewLines = 0;
19 19
 		for (char c : whitespaceBefore.toCharArray())
20 20
 			if (c == '\n')
@@ -30,7 +30,7 @@ public class WhitespaceInfo {
30 30
 			commentsBefore.add(trimmed);
31 31
 		}
32 32
 		
33
-		boolean emptyLine = numNewLines - commentsBefore.size() > 0;
33
+		boolean emptyLine = !skipLineBefore && numNewLines - commentsBefore.size() > 0;
34 34
 		return new WhitespaceInfo(
35 35
 				emptyLine,
36 36
 				commentsBefore.toArray(new String[commentsBefore.size()]),

+ 4
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallStaticExpression.java Целия файл

@@ -6,6 +6,7 @@
6 6
 package org.openzen.zenscript.codemodel.expression;
7 7
 
8 8
 import org.openzen.zenscript.codemodel.member.FunctionalMember;
9
+import org.openzen.zenscript.codemodel.type.ITypeID;
9 10
 import org.openzen.zenscript.shared.CodePosition;
10 11
 
11 12
 /**
@@ -14,12 +15,14 @@ import org.openzen.zenscript.shared.CodePosition;
14 15
  */
15 16
 public class CallStaticExpression extends Expression {
16 17
 	public final FunctionalMember member;
18
+	public final ITypeID target;
17 19
 	public final CallArguments arguments;
18 20
 	
19
-	public CallStaticExpression(CodePosition position, FunctionalMember member, CallArguments arguments) {
21
+	public CallStaticExpression(CodePosition position, ITypeID target, FunctionalMember member, CallArguments arguments) {
20 22
 		super(position, member.header.returnType);
21 23
 		
22 24
 		this.member = member;
25
+		this.target = target;
23 26
 		this.arguments = arguments;
24 27
 	}
25 28
 

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/EqualsMember.java Целия файл

@@ -56,12 +56,12 @@ public class EqualsMember extends Taggable implements ICallableMember {
56 56
 	}
57 57
 
58 58
 	@Override
59
-	public Expression callStatic(CodePosition position, FunctionHeader instancedHeader, CallArguments arguments) {
59
+	public Expression callStatic(CodePosition position, ITypeID target, FunctionHeader instancedHeader, CallArguments arguments) {
60 60
 		throw new UnsupportedOperationException("Cannot be called statically");
61 61
 	}
62 62
 
63 63
 	@Override
64
-	public Expression callStaticWithComparator(CodePosition position, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments) {
64
+	public Expression callStaticWithComparator(CodePosition position, ITypeID target, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments) {
65 65
 		throw new UnsupportedOperationException("Cannot be called statically");
66 66
 	}
67 67
 

+ 5
- 5
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/FunctionalMember.java Целия файл

@@ -5,7 +5,6 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel.member;
7 7
 
8
-import java.util.List;
9 8
 import org.openzen.zenscript.codemodel.CompareType;
10 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
11 10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
@@ -15,6 +14,7 @@ import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
15 14
 import org.openzen.zenscript.codemodel.expression.Expression;
16 15
 import org.openzen.zenscript.codemodel.expression.GenericCompareExpression;
17 16
 import org.openzen.zenscript.codemodel.statement.Statement;
17
+import org.openzen.zenscript.codemodel.type.ITypeID;
18 18
 import org.openzen.zenscript.shared.CodePosition;
19 19
 
20 20
 /**
@@ -57,12 +57,12 @@ public abstract class FunctionalMember extends DefinitionMember implements ICall
57 57
 	}
58 58
 	
59 59
 	@Override
60
-	public Expression callStatic(CodePosition position, FunctionHeader instancedHeader, CallArguments arguments) {
61
-		return new CallStaticExpression(position, this, arguments);
60
+	public Expression callStatic(CodePosition position, ITypeID target, FunctionHeader instancedHeader, CallArguments arguments) {
61
+		return new CallStaticExpression(position, target, this, arguments);
62 62
 	}
63 63
 	
64 64
 	@Override
65
-	public Expression callStaticWithComparator(CodePosition position, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments) {
66
-		return new GenericCompareExpression(position, callStatic(position, instancedHeader, arguments), operator);
65
+	public Expression callStaticWithComparator(CodePosition position, ITypeID target, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments) {
66
+		return new GenericCompareExpression(position, callStatic(position, target, instancedHeader, arguments), operator);
67 67
 	}
68 68
 }

+ 3
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ICallableMember.java Целия файл

@@ -9,6 +9,7 @@ import org.openzen.zenscript.codemodel.CompareType;
9 9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10 10
 import org.openzen.zenscript.codemodel.expression.CallArguments;
11 11
 import org.openzen.zenscript.codemodel.expression.Expression;
12
+import org.openzen.zenscript.codemodel.type.ITypeID;
12 13
 import org.openzen.zenscript.shared.CodePosition;
13 14
 
14 15
 /**
@@ -24,7 +25,7 @@ public interface ICallableMember extends IDefinitionMember {
24 25
 	
25 26
 	public Expression callWithComparator(CodePosition position, CompareType operator, Expression target, FunctionHeader instancedHeader, CallArguments arguments);
26 27
 	
27
-	public Expression callStatic(CodePosition position, FunctionHeader instancedHeader, CallArguments arguments);
28
+	public Expression callStatic(CodePosition position, ITypeID target, FunctionHeader instancedHeader, CallArguments arguments);
28 29
 	
29
-	public Expression callStaticWithComparator(CodePosition position, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments);
30
+	public Expression callStaticWithComparator(CodePosition position, ITypeID target, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments);
30 31
 }

+ 2
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/builtin/ComparatorMember.java Целия файл

@@ -58,12 +58,12 @@ public class ComparatorMember extends Taggable implements ICallableMember {
58 58
 	}
59 59
 
60 60
 	@Override
61
-	public Expression callStatic(CodePosition position, FunctionHeader instancedHeader, CallArguments arguments) {
61
+	public Expression callStatic(CodePosition position, ITypeID target, FunctionHeader instancedHeader, CallArguments arguments) {
62 62
 		throw new UnsupportedOperationException("Can't call a comparator");
63 63
 	}
64 64
 
65 65
 	@Override
66
-	public Expression callStaticWithComparator(CodePosition position, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments) {
66
+	public Expression callStaticWithComparator(CodePosition position, ITypeID target, CompareType operator, FunctionHeader instancedHeader, CallArguments arguments) {
67 67
 		throw new UnsupportedOperationException("Can't call a comparator statically");
68 68
 	}
69 69
 

+ 6
- 4
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialStaticMemberGroupExpression.java Целия файл

@@ -23,18 +23,20 @@ import org.openzen.zenscript.codemodel.type.member.TypeMemberPriority;
23 23
  * @author Hoofdgebruiker
24 24
  */
25 25
 public class PartialStaticMemberGroupExpression implements IPartialExpression {
26
-	public static PartialStaticMemberGroupExpression forMethod(CodePosition position, ICallableMember method) {
26
+	public static PartialStaticMemberGroupExpression forMethod(CodePosition position, ITypeID target, ICallableMember method) {
27 27
 		DefinitionMemberGroup group = new DefinitionMemberGroup();
28 28
 		group.addMethod(method, TypeMemberPriority.SPECIFIED);
29
-		return new PartialStaticMemberGroupExpression(position, group);
29
+		return new PartialStaticMemberGroupExpression(position, target, group);
30 30
 	}
31 31
 	
32 32
 	private final CodePosition position;
33
+	private final ITypeID target;
33 34
 	private final DefinitionMemberGroup group;
34 35
 	
35
-	public PartialStaticMemberGroupExpression(CodePosition position, DefinitionMemberGroup group) {
36
+	public PartialStaticMemberGroupExpression(CodePosition position, ITypeID target, DefinitionMemberGroup group) {
36 37
 		this.position = position;
37 38
 		this.group = group;
39
+		this.target = target;
38 40
 	}
39 41
 	
40 42
 	@Override
@@ -62,7 +64,7 @@ public class PartialStaticMemberGroupExpression implements IPartialExpression {
62 64
 
63 65
 	@Override
64 66
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
65
-		return group.callStatic(position, scope, arguments);
67
+		return group.callStatic(position, target, scope, arguments);
66 68
 	}
67 69
 	
68 70
 	@Override

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/partial/PartialTypeExpression.java Целия файл

@@ -58,6 +58,6 @@ public class PartialTypeExpression implements IPartialExpression {
58 58
 
59 59
 	@Override
60 60
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
61
-		return scope.getTypeMembers(type).getOrCreateGroup(OperatorType.CALL).callStatic(position, scope, arguments);
61
+		return scope.getTypeMembers(type).getOrCreateGroup(OperatorType.CALL).callStatic(position, type, scope, arguments);
62 62
 	}
63 63
 }

+ 4
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java Целия файл

@@ -244,20 +244,21 @@ public class DefinitionMemberGroup {
244 244
 		return method.callWithComparator(position, compareType, target, instancedHeader, arguments);
245 245
 	}
246 246
 	
247
-	public Expression callStatic(CodePosition position, TypeScope scope, CallArguments arguments) {
247
+	public Expression callStatic(CodePosition position, ITypeID target, TypeScope scope, CallArguments arguments) {
248 248
 		ICallableMember method = selectMethod(position, scope, arguments, false, true);
249 249
 		FunctionHeader instancedHeader = method.getHeader().withGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
250
-		return method.callStatic(position, instancedHeader, arguments);
250
+		return method.callStatic(position, target, instancedHeader, arguments);
251 251
 	}
252 252
 	
253 253
 	public Expression callStaticWithComparator(
254 254
 			CodePosition position,
255
+			ITypeID target, 
255 256
 			TypeScope scope,
256 257
 			CallArguments arguments,
257 258
 			CompareType compareType) {
258 259
 		ICallableMember method = selectMethod(position, scope, arguments, false, true);
259 260
 		FunctionHeader instancedHeader = method.getHeader().withGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
260
-		return method.callStaticWithComparator(position, compareType, instancedHeader, arguments);
261
+		return method.callStaticWithComparator(position, target, compareType, instancedHeader, arguments);
261 262
 	}
262 263
 	
263 264
 	public ICallableMember selectMethod(CodePosition position, TypeScope scope, CallArguments arguments, boolean allowNonStatic, boolean allowStatic) {

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMembers.java Целия файл

@@ -358,7 +358,7 @@ public final class TypeMembers {
358 358
 	
359 359
 	public IPartialExpression getStaticMemberExpression(CodePosition position, GenericName name) {
360 360
 		if (members.containsKey(name.name))
361
-			return new PartialStaticMemberGroupExpression(position, members.get(name.name));
361
+			return new PartialStaticMemberGroupExpression(position, type, members.get(name.name));
362 362
 		if (innerTypes.containsKey(name.name))
363 363
 			return new PartialTypeExpression(position, innerTypes.get(name.name).instance(cache.getRegistry(), name.arguments));
364 364
 		

+ 3
- 3
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java Целия файл

@@ -139,11 +139,11 @@ public class ZSTokenStream extends TokenStream<ZSToken, ZSTokenType> {
139 139
 	}
140 140
 	
141 141
 	public WhitespaceInfo collectWhitespaceInfoForBlock(String whitespace) {
142
-		return WhitespaceInfo.from(whitespace, "");
142
+		return WhitespaceInfo.from(whitespace, "", false);
143 143
 	}
144 144
 	
145
-	public WhitespaceInfo collectWhitespaceInfo(String whitespace) {
146
-		return WhitespaceInfo.from(whitespace, grabWhitespaceLine());
145
+	public WhitespaceInfo collectWhitespaceInfo(String whitespace, boolean skipLineBefore) {
146
+		return WhitespaceInfo.from(whitespace, grabWhitespaceLine(), skipLineBefore);
147 147
 	}
148 148
 	
149 149
 	@Override

+ 42
- 39
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatement.java Целия файл

@@ -33,42 +33,45 @@ public abstract class ParsedStatement {
33 33
 	}
34 34
 	
35 35
 	public static ParsedFunctionBody parseFunctionBody(ZSTokenStream tokens) {
36
-		ZSToken start = tokens.peek();
37
-		if (tokens.optional(T_LAMBDA) != null) {
36
+		if (tokens.optional(T_LAMBDA) != null)
38 37
 			return parseLambdaBody(tokens, false);
39
-		} else if (tokens.optional(T_SEMICOLON) != null) {
38
+		else if (tokens.optional(T_SEMICOLON) != null)
40 39
 			return new ParsedEmptyFunctionBody(tokens.getPosition());
41
-		} else {
42
-			tokens.required(T_AOPEN, "{ expected");
43
-			List<ParsedStatement> statements = new ArrayList<>();
44
-			while (tokens.optional(T_ACLOSE) == null) {
45
-				statements.add(ParsedStatement.parse(tokens));
46
-			}
47
-			return new ParsedStatementsFunctionBody(new ParsedStatementBlock(start.position, null, null, statements));
40
+		else
41
+			return new ParsedStatementsFunctionBody(parseBlock(tokens, true));
42
+	}
43
+	
44
+	public static ParsedStatementBlock parseBlock(ZSTokenStream parser, boolean isFirst) {
45
+		String ws = parser.grabWhitespace();
46
+		ZSToken t = parser.required(T_AOPEN, "{ expected");
47
+
48
+		parser.reloadWhitespace();
49
+		parser.skipWhitespaceNewline();
50
+
51
+		ArrayList<ParsedStatement> statements = new ArrayList<>();
52
+		ZSToken last;
53
+		boolean firstContent = true;
54
+		while ((last = parser.optional(T_ACLOSE)) == null) {
55
+			statements.add(parse(parser, firstContent));
56
+			firstContent = false;
48 57
 		}
58
+
59
+		WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
60
+		WhitespacePostComment postComment = WhitespacePostComment.fromWhitespace(last.whitespaceBefore);
61
+		return new ParsedStatementBlock(t.getPosition(), whitespace, postComment, statements);
49 62
 	}
50 63
 	
51 64
 	public static ParsedStatement parse(ZSTokenStream parser) {
65
+		return parse(parser, false);
66
+	}
67
+	
68
+	public static ParsedStatement parse(ZSTokenStream parser, boolean isFirst) {
52 69
 		String ws = parser.grabWhitespace();
53 70
 		ZSToken next = parser.peek();
54 71
 		switch (next.getType()) {
55
-			case T_AOPEN: {
56
-				ZSToken t = parser.next();
57
-				
58
-				parser.reloadWhitespace();
59
-				parser.skipWhitespaceNewline();
60
-				
61
-				ArrayList<ParsedStatement> statements = new ArrayList<>();
62
-				ZSToken last;
63
-				while ((last = parser.optional(T_ACLOSE)) == null) {
64
-					statements.add(parse(parser));
65
-				}
66
-				
67
-				parser.reloadWhitespace();
68
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfoForBlock(ws);
69
-				WhitespacePostComment postComment = WhitespacePostComment.fromWhitespace(last.whitespaceBefore);
70
-				return new ParsedStatementBlock(t.getPosition(), whitespace, postComment, statements);
71
-			}
72
+			case T_AOPEN:
73
+				return parseBlock(parser, isFirst);
74
+			
72 75
 			case K_RETURN: {
73 76
 				parser.next();
74 77
 				ParsedExpression expression = null;
@@ -77,7 +80,7 @@ public abstract class ParsedStatement {
77 80
 				}
78 81
 				parser.required(T_SEMICOLON, "; expected");
79 82
 				
80
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
83
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
81 84
 				return new ParsedStatementReturn(next.getPosition(), whitespace, expression);
82 85
 			}
83 86
 			case K_VAR:
@@ -95,7 +98,7 @@ public abstract class ParsedStatement {
95 98
 				}
96 99
 				parser.required(T_SEMICOLON, "; expected");
97 100
 				
98
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
101
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
99 102
 				return new ParsedStatementVar(start.getPosition(), whitespace, name, type, initializer, start.getType() == K_VAL);
100 103
 			}
101 104
 			case K_IF: {
@@ -110,7 +113,7 @@ public abstract class ParsedStatement {
110 113
 					onElse = parse(parser);
111 114
 				}
112 115
 				
113
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
116
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
114 117
 				return new ParsedStatementIf(t.getPosition(), whitespace, expression, onIf, onElse);
115 118
 			}
116 119
 			case K_FOR: {
@@ -127,7 +130,7 @@ public abstract class ParsedStatement {
127 130
 				ParsedExpression source = ParsedExpression.parse(parser);
128 131
 				ParsedStatement content = parse(parser);
129 132
 				
130
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
133
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
131 134
 				return new ParsedStatementForeach(
132 135
 						t.getPosition(),
133 136
 						whitespace,
@@ -146,7 +149,7 @@ public abstract class ParsedStatement {
146 149
 				ParsedExpression condition = ParsedExpression.parse(parser);
147 150
 				parser.required(T_SEMICOLON, "; expected");
148 151
 				
149
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
152
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
150 153
 				return new ParsedStatementDoWhile(t.position, whitespace, label, content, condition);
151 154
 			}
152 155
 			case K_WHILE: {
@@ -158,7 +161,7 @@ public abstract class ParsedStatement {
158 161
 				ParsedExpression condition = ParsedExpression.parse(parser);
159 162
 				ParsedStatement content = parse(parser);
160 163
 				
161
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
164
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
162 165
 				return new ParsedStatementWhile(t.position, whitespace, label, condition, content);
163 166
 			}
164 167
 			case K_LOCK: {
@@ -166,7 +169,7 @@ public abstract class ParsedStatement {
166 169
 				ParsedExpression object = ParsedExpression.parse(parser);
167 170
 				ParsedStatement content = parse(parser);
168 171
 				
169
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
172
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
170 173
 				return new ParsedStatementLock(t.position, whitespace, object, content);
171 174
 			}
172 175
 			case K_THROW: {
@@ -174,7 +177,7 @@ public abstract class ParsedStatement {
174 177
 				ParsedExpression value = ParsedExpression.parse(parser);
175 178
 				parser.required(T_SEMICOLON, "; expected");
176 179
 				
177
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
180
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
178 181
 				return new ParsedStatementThrow(t.position, whitespace, value);
179 182
 			}
180 183
 			case K_TRY: {
@@ -208,7 +211,7 @@ public abstract class ParsedStatement {
208 211
 				if (parser.optional(K_FINALLY) != null)
209 212
 					finallyClause = ParsedStatement.parse(parser);
210 213
 				
211
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
214
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
212 215
 				return new ParsedStatementTryCatch(t.position, whitespace, name, initializer, content, catchClauses, finallyClause);
213 216
 			}
214 217
 			case K_CONTINUE: {
@@ -219,7 +222,7 @@ public abstract class ParsedStatement {
219 222
 				
220 223
 				parser.required(T_SEMICOLON, "; expected");
221 224
 				
222
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
225
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
223 226
 				return new ParsedStatementContinue(t.position, whitespace, name);
224 227
 			}
225 228
 			case K_BREAK: {
@@ -230,7 +233,7 @@ public abstract class ParsedStatement {
230 233
 				
231 234
 				parser.required(T_SEMICOLON, "; expected");
232 235
 				
233
-				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
236
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
234 237
 				return new ParsedStatementBreak(t.position, whitespace, name);
235 238
 			}
236 239
 		}
@@ -238,7 +241,7 @@ public abstract class ParsedStatement {
238 241
 		CodePosition position = parser.peek().getPosition();
239 242
 		ParsedExpression expression = ParsedExpression.parse(parser);
240 243
 		parser.required(T_SEMICOLON, "; expected");
241
-		WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
244
+		WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws, isFirst);
242 245
 		
243 246
 		ParsedStatementExpression result = new ParsedStatementExpression(position, whitespace, expression);
244 247
 		return result;

Loading…
Отказ
Запис