Browse Source

- Continued work on the code formatter

- Static calls now remember the exact type they are called for
Stan Hebben 6 years ago
parent
commit
ba568c23b7
18 changed files with 313 additions and 188 deletions
  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 View File

5
  */
5
  */
6
 package org.openzen.zenscript.formatter;
6
 package org.openzen.zenscript.formatter;
7
 
7
 
8
+import java.util.List;
8
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
9
 import org.openzen.zenscript.codemodel.definition.AliasDefinition;
9
 import org.openzen.zenscript.codemodel.definition.ClassDefinition;
10
 import org.openzen.zenscript.codemodel.definition.ClassDefinition;
10
 import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
11
 import org.openzen.zenscript.codemodel.definition.DefinitionVisitor;
13
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
14
 import org.openzen.zenscript.codemodel.definition.FunctionDefinition;
14
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
15
 import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
15
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
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
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
19
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
17
 
20
 
18
 /**
21
 /**
48
 		} else {
51
 		} else {
49
 			output.append("\n")
52
 			output.append("\n")
50
 					.append(indent)
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
 		for (IDefinitionMember member : definition.members) {
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
 		output.append("}\n");
62
 		output.append("}\n");
62
 
65
 
63
 	@Override
66
 	@Override
64
 	public Void visitInterface(InterfaceDefinition definition) {
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
 		return null;
88
 		return null;
67
 	}
89
 	}
68
 
90
 
69
 	@Override
91
 	@Override
70
 	public Void visitEnum(EnumDefinition definition) {
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
 		return null;
132
 		return null;
72
 	}
133
 	}
73
 
134
 
96
 		return null;
157
 		return null;
97
 	}
158
 	}
98
 	
159
 	
160
+	@Override
99
 	public String toString() {
161
 	public String toString() {
100
 		return output.toString();
162
 		return output.toString();
101
 	}
163
 	}

+ 20
- 37
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.formatter;
6
 package org.openzen.zenscript.formatter;
7
 
7
 
8
+import org.openzen.zenscript.codemodel.OperatorType;
8
 import org.openzen.zenscript.codemodel.expression.AndAndExpression;
9
 import org.openzen.zenscript.codemodel.expression.AndAndExpression;
9
 import org.openzen.zenscript.codemodel.expression.ArrayExpression;
10
 import org.openzen.zenscript.codemodel.expression.ArrayExpression;
10
 import org.openzen.zenscript.codemodel.expression.BasicCompareExpression;
11
 import org.openzen.zenscript.codemodel.expression.BasicCompareExpression;
11
-import org.openzen.zenscript.codemodel.expression.CallArguments;
12
 import org.openzen.zenscript.codemodel.expression.CallExpression;
12
 import org.openzen.zenscript.codemodel.expression.CallExpression;
13
 import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
13
 import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
14
 import org.openzen.zenscript.codemodel.expression.CapturedClosureExpression;
14
 import org.openzen.zenscript.codemodel.expression.CapturedClosureExpression;
220
 				case CALL: {
220
 				case CALL: {
221
 					StringBuilder result = new StringBuilder();
221
 					StringBuilder result = new StringBuilder();
222
 					result.append(".");
222
 					result.append(".");
223
-					format(result, expression.arguments);
223
+					FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
224
 					return new ExpressionString(result.toString(), OperatorPriority.CALL);
224
 					return new ExpressionString(result.toString(), OperatorPriority.CALL);
225
 				}
225
 				}
226
 				case CAST: {
226
 				case CAST: {
237
 			result.append(expression.target.accept(this).value);
237
 			result.append(expression.target.accept(this).value);
238
 			result.append(".");
238
 			result.append(".");
239
 			result.append(expression.member.name);
239
 			result.append(expression.member.name);
240
-			format(result, expression.arguments);
240
+			FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
241
 			return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
241
 			return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
242
 		}
242
 		}
243
 	}
243
 	}
245
 	@Override
245
 	@Override
246
 	public ExpressionString visitCallStatic(CallStaticExpression expression) {
246
 	public ExpressionString visitCallStatic(CallStaticExpression expression) {
247
 		StringBuilder result = new StringBuilder();
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
 	@Override
265
 	@Override
410
 	public ExpressionString visitConstructorThisCall(ConstructorThisCallExpression expression) {
393
 	public ExpressionString visitConstructorThisCall(ConstructorThisCallExpression expression) {
411
 		StringBuilder result = new StringBuilder();
394
 		StringBuilder result = new StringBuilder();
412
 		result.append("this");
395
 		result.append("this");
413
-		format(result, expression.arguments);
396
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
414
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
397
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
415
 	}
398
 	}
416
 
399
 
418
 	public ExpressionString visitConstructorSuperCall(ConstructorSuperCallExpression expression) {
401
 	public ExpressionString visitConstructorSuperCall(ConstructorSuperCallExpression expression) {
419
 		StringBuilder result = new StringBuilder();
402
 		StringBuilder result = new StringBuilder();
420
 		result.append("super");
403
 		result.append("super");
421
-		format(result, expression.arguments);
404
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
422
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
405
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
423
 	}
406
 	}
424
 
407
 
483
 	public ExpressionString visitGlobalCall(GlobalCallExpression expression) {
466
 	public ExpressionString visitGlobalCall(GlobalCallExpression expression) {
484
 		StringBuilder result = new StringBuilder();
467
 		StringBuilder result = new StringBuilder();
485
 		result.append(expression.name);
468
 		result.append(expression.name);
486
-		format(result, expression.arguments);
469
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
487
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
470
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
488
 	}
471
 	}
489
 
472
 
530
 		StringBuilder result = new StringBuilder();
513
 		StringBuilder result = new StringBuilder();
531
 		result.append("new ");
514
 		result.append("new ");
532
 		result.append(expression.type.accept(typeFormatter));
515
 		result.append(expression.type.accept(typeFormatter));
533
-		format(result, expression.arguments);
516
+		FormattingUtils.formatCall(result, typeFormatter, this, expression.arguments);
534
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
517
 		return new ExpressionString(result.toString(), OperatorPriority.PRIMARY);
535
 	}
518
 	}
536
 
519
 

+ 19
- 7
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FileFormatter.java View File

41
 			definitionFormatters.add(definitionFormatter);
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
 		for (Statement statement : script.statements) {
46
 		for (Statement statement : script.statements) {
46
 			statement.accept(scriptFormatter);
47
 			statement.accept(scriptFormatter);
47
 		}
48
 		}
49
 		StringBuilder output = new StringBuilder();
50
 		StringBuilder output = new StringBuilder();
50
 		importer.write(output);
51
 		importer.write(output);
51
 		
52
 		
53
+		boolean first = true;
52
 		for (DefinitionFormatter definition : definitionFormatters) {
54
 		for (DefinitionFormatter definition : definitionFormatters) {
55
+			if (first)
56
+				first = false;
57
+			else
58
+				output.append("\n");
59
+			
53
 			output.append(definition.toString());
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 View File

8
 import org.openzen.zenscript.codemodel.FunctionHeader;
8
 import org.openzen.zenscript.codemodel.FunctionHeader;
9
 import org.openzen.zenscript.codemodel.FunctionParameter;
9
 import org.openzen.zenscript.codemodel.FunctionParameter;
10
 import org.openzen.zenscript.codemodel.Modifiers;
10
 import org.openzen.zenscript.codemodel.Modifiers;
11
+import org.openzen.zenscript.codemodel.expression.CallArguments;
12
+import org.openzen.zenscript.codemodel.expression.Expression;
11
 import org.openzen.zenscript.codemodel.generic.GenericParameterBound;
13
 import org.openzen.zenscript.codemodel.generic.GenericParameterBound;
12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
14
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
15
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
27
 import org.openzen.zenscript.codemodel.statement.VarStatement;
29
 import org.openzen.zenscript.codemodel.statement.VarStatement;
28
 import org.openzen.zenscript.codemodel.statement.WhileStatement;
30
 import org.openzen.zenscript.codemodel.statement.WhileStatement;
29
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
31
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
32
+import org.openzen.zenscript.codemodel.type.ITypeID;
30
 
33
 
31
 /**
34
 /**
32
  *
35
  *
113
 	
116
 	
114
 	public static void formatBody(StringBuilder output, FormattingSettings settings, String indent, TypeFormatter typeFormatter, Statement body) {
117
 	public static void formatBody(StringBuilder output, FormattingSettings settings, String indent, TypeFormatter typeFormatter, Statement body) {
115
 		body.accept(new BodyFormatter(output, settings, indent, typeFormatter));
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
 	private static class BodyFormatter implements StatementVisitor<Void> {
149
 	private static class BodyFormatter implements StatementVisitor<Void> {
128
 			this.indent = indent;
159
 			this.indent = indent;
129
 			this.typeFormatter = typeFormatter;
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
 		@Override
165
 		@Override
153
 
184
 
154
 		@Override
185
 		@Override
155
 		public Void visitEmpty(EmptyStatement statement) {
186
 		public Void visitEmpty(EmptyStatement statement) {
156
-			output.append(";\n");
187
+			output.append(";");
157
 			return null;
188
 			return null;
158
 		}
189
 		}
159
 
190
 

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

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

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

33
  */
33
  */
34
 public class StatementFormatter implements StatementVisitor<Void> {
34
 public class StatementFormatter implements StatementVisitor<Void> {
35
 	private final FormattingSettings settings;
35
 	private final FormattingSettings settings;
36
-	private final StringBuilder result;
36
+	private final StringBuilder output;
37
 	private final ExpressionFormatter expressionFormatter;
37
 	private final ExpressionFormatter expressionFormatter;
38
 	
38
 	
39
 	private String indent;
39
 	private String indent;
40
 	private ParentStatementType position = ParentStatementType.NONE;
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
 		this.indent = indent;
44
 		this.indent = indent;
44
 		this.settings = settings;
45
 		this.settings = settings;
45
-		result = new StringBuilder();
46
 		this.expressionFormatter = expressionFormatter;
46
 		this.expressionFormatter = expressionFormatter;
47
 	}
47
 	}
48
 	
48
 	
49
 	@Override
49
 	@Override
50
 	public String toString() {
50
 	public String toString() {
51
-		return result.toString();
51
+		return output.toString();
52
 	}
52
 	}
53
 
53
 
54
 	@Override
54
 	@Override
77
 	public Void visitBreak(BreakStatement statement) {
77
 	public Void visitBreak(BreakStatement statement) {
78
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
78
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
79
 		beginSingleLine(whitespace);
79
 		beginSingleLine(whitespace);
80
-		result.append("break");
80
+		output.append("break");
81
 		if (statement.target.label != null)
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
 		endSingleLine(whitespace);
84
 		endSingleLine(whitespace);
85
 		return null;
85
 		return null;
86
 	}
86
 	}
89
 	public Void visitContinue(ContinueStatement statement) {
89
 	public Void visitContinue(ContinueStatement statement) {
90
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
90
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
91
 		beginSingleLine(whitespace);
91
 		beginSingleLine(whitespace);
92
-		result.append("continue");
92
+		output.append("continue");
93
 		if (statement.target.label != null)
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
 		endSingleLine(whitespace);
96
 		endSingleLine(whitespace);
97
 		return null;
97
 		return null;
98
 	}
98
 	}
101
 	public Void visitDoWhile(DoWhileStatement statement) {
101
 	public Void visitDoWhile(DoWhileStatement statement) {
102
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
102
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
103
 		beginSingleLine(whitespace);
103
 		beginSingleLine(whitespace);
104
-		result.append("do");
104
+		output.append("do");
105
 		if (statement.label != null) {
105
 		if (statement.label != null) {
106
 			if (settings.spaceBeforeLabelColon)
106
 			if (settings.spaceBeforeLabelColon)
107
-				result.append(' ');
108
-			result.append(':');
107
+				output.append(' ');
108
+			output.append(':');
109
 			if (settings.spaceAfterLabelColon)
109
 			if (settings.spaceAfterLabelColon)
110
-				result.append(' ');
111
-			result.append(statement.label);
110
+				output.append(' ');
111
+			output.append(statement.label);
112
 		}
112
 		}
113
 		format(ParentStatementType.LOOP, statement.content);
113
 		format(ParentStatementType.LOOP, statement.content);
114
-		result.append(" while ");
114
+		output.append(" while ");
115
 		appendCondition(statement.condition);
115
 		appendCondition(statement.condition);
116
-		result.append(";");
116
+		output.append(";");
117
 		endSingleLine(whitespace);
117
 		endSingleLine(whitespace);
118
 		return null;
118
 		return null;
119
 	}
119
 	}
122
 	public Void visitEmpty(EmptyStatement statement) {
122
 	public Void visitEmpty(EmptyStatement statement) {
123
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
123
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
124
 		beginSingleLine(whitespace);
124
 		beginSingleLine(whitespace);
125
-		result.append(";\n");
125
+		output.append(";\n");
126
 		endSingleLine(whitespace);
126
 		endSingleLine(whitespace);
127
 		return null;
127
 		return null;
128
 	}
128
 	}
131
 	public Void visitExpression(ExpressionStatement statement) {
131
 	public Void visitExpression(ExpressionStatement statement) {
132
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
132
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
133
 		beginSingleLine(whitespace);
133
 		beginSingleLine(whitespace);
134
-		result.append(statement.expression.accept(expressionFormatter).value)
134
+		output.append(statement.expression.accept(expressionFormatter).value)
135
 			  .append(";");
135
 			  .append(";");
136
 		endSingleLine(whitespace);
136
 		endSingleLine(whitespace);
137
 		return null;
137
 		return null;
141
 	public Void visitForeach(ForeachStatement statement) {
141
 	public Void visitForeach(ForeachStatement statement) {
142
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
142
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
143
 		beginSingleLine(whitespace);
143
 		beginSingleLine(whitespace);
144
-		result.append("for ");
144
+		output.append("for ");
145
 		for (int i = 0; i < statement.loopVariables.length; i++) {
145
 		for (int i = 0; i < statement.loopVariables.length; i++) {
146
 			if (i > 0)
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
 		format(ParentStatementType.LOOP, statement.content);
153
 		format(ParentStatementType.LOOP, statement.content);
154
 		endSingleLine(whitespace);
154
 		endSingleLine(whitespace);
155
 		return null;
155
 		return null;
160
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
160
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
161
 		ParentStatementType position = this.position;
161
 		ParentStatementType position = this.position;
162
 		beginSingleLine(whitespace);
162
 		beginSingleLine(whitespace);
163
-		result.append("if ");
163
+		output.append("if ");
164
 		appendCondition(statement.condition);
164
 		appendCondition(statement.condition);
165
 		format(statement.onElse == null ? ParentStatementType.IF : ParentStatementType.IF_WITH_ELSE, statement.onThen);
165
 		format(statement.onElse == null ? ParentStatementType.IF : ParentStatementType.IF_WITH_ELSE, statement.onThen);
166
 		if (statement.onElse != null) {
166
 		if (statement.onElse != null) {
167
-			result.append("else");
167
+			output.append("else");
168
 			format(ParentStatementType.ELSE, statement.onElse);
168
 			format(ParentStatementType.ELSE, statement.onElse);
169
 		}
169
 		}
170
 		endSingleLine(whitespace);
170
 		endSingleLine(whitespace);
175
 	public Void visitLock(LockStatement statement) {
175
 	public Void visitLock(LockStatement statement) {
176
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
176
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
177
 		beginSingleLine(whitespace);
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
 		statement.content.accept(this);
180
 		statement.content.accept(this);
181
 		endSingleLine(whitespace);
181
 		endSingleLine(whitespace);
182
 		return null;
182
 		return null;
186
 	public Void visitReturn(ReturnStatement statement) {
186
 	public Void visitReturn(ReturnStatement statement) {
187
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
187
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
188
 		beginSingleLine(whitespace);
188
 		beginSingleLine(whitespace);
189
-		result.append("return");
189
+		output.append("return");
190
 		if (statement.value != null) {
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
 		endSingleLine(whitespace);
195
 		endSingleLine(whitespace);
196
 		return null;
196
 		return null;
197
 	}
197
 	}
200
 	public Void visitThrow(ThrowStatement statement) {
200
 	public Void visitThrow(ThrowStatement statement) {
201
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
201
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
202
 		beginSingleLine(whitespace);
202
 		beginSingleLine(whitespace);
203
-		result.append("throw ").append(statement.value.accept(expressionFormatter));
203
+		output.append("throw ").append(statement.value.accept(expressionFormatter));
204
 		endSingleLine(whitespace);
204
 		endSingleLine(whitespace);
205
 		return null;
205
 		return null;
206
 	}
206
 	}
209
 	public Void visitTryCatch(TryCatchStatement statement) {
209
 	public Void visitTryCatch(TryCatchStatement statement) {
210
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
210
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
211
 		beginSingleLine(whitespace);
211
 		beginSingleLine(whitespace);
212
-		result.append("try");
212
+		output.append("try");
213
 		if (statement.resource != null) {
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
 		format(ParentStatementType.TRY, statement.content);
219
 		format(ParentStatementType.TRY, statement.content);
220
 		
220
 		
221
 		for (CatchClause catchClause : statement.catchClauses) {
221
 		for (CatchClause catchClause : statement.catchClauses) {
222
-			result.append(indent).append("catch ");
222
+			output.append(indent).append("catch ");
223
 			if (catchClause.exceptionName != null)
223
 			if (catchClause.exceptionName != null)
224
-				result.append(catchClause.exceptionName);
224
+				output.append(catchClause.exceptionName);
225
 			if (catchClause.exceptionType != BasicTypeID.ANY) {
225
 			if (catchClause.exceptionType != BasicTypeID.ANY) {
226
-				result.append(" as ");
226
+				output.append(" as ");
227
 				catchClause.exceptionType.accept(expressionFormatter.typeFormatter);
227
 				catchClause.exceptionType.accept(expressionFormatter.typeFormatter);
228
 			}
228
 			}
229
 			
229
 			
230
 			format(ParentStatementType.CATCH, catchClause.content);
230
 			format(ParentStatementType.CATCH, catchClause.content);
231
 		}
231
 		}
232
 		if (statement.finallyClause != null) {
232
 		if (statement.finallyClause != null) {
233
-			result.append(indent).append("finally ");
233
+			output.append(indent).append("finally ");
234
 			
234
 			
235
 			format(ParentStatementType.FINALLY, statement.finallyClause);
235
 			format(ParentStatementType.FINALLY, statement.finallyClause);
236
 		}
236
 		}
242
 	public Void visitVar(VarStatement statement) {
242
 	public Void visitVar(VarStatement statement) {
243
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
243
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
244
 		beginSingleLine(whitespace);
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
 		if (statement.initializer == null || statement.initializer.type != statement.type) {
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
 		if (statement.initializer != null) {
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
 		endSingleLine(whitespace);
257
 		endSingleLine(whitespace);
258
 		return null;
258
 		return null;
259
 	}
259
 	}
262
 	public Void visitWhile(WhileStatement statement) {
262
 	public Void visitWhile(WhileStatement statement) {
263
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
263
 		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
264
 		beginSingleLine(whitespace);
264
 		beginSingleLine(whitespace);
265
-		result.append("while");
265
+		output.append("while");
266
 		if (statement.label != null) {
266
 		if (statement.label != null) {
267
 			if (settings.spaceBeforeLabelColon)
267
 			if (settings.spaceBeforeLabelColon)
268
-				result.append(' ');
269
-			result.append(':');
268
+				output.append(' ');
269
+			output.append(':');
270
 			if (settings.spaceAfterLabelColon)
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
 		appendCondition(statement.condition);
275
 		appendCondition(statement.condition);
276
 		
276
 		
277
 		format(ParentStatementType.LOOP, statement.content);
277
 		format(ParentStatementType.LOOP, statement.content);
288
 	
288
 	
289
 	private void appendCondition(Expression condition) {
289
 	private void appendCondition(Expression condition) {
290
 		if (settings.bracketsAroundConditions)
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
 		if (settings.bracketsAroundConditions)
293
 		if (settings.bracketsAroundConditions)
294
-			result.append(')');
294
+			output.append(')');
295
 	}
295
 	}
296
 	
296
 	
297
 	private void beginBlock(WhitespaceInfo whitespace) {
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
 			writeComments(whitespace.commentsBefore);
306
 			writeComments(whitespace.commentsBefore);
305
-		}
306
 	}
307
 	}
307
 	
308
 	
308
 	private void endBlock(WhitespaceInfo whitespace) {
309
 	private void endBlock(WhitespaceInfo whitespace) {
309
 		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
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
 		if (position == ParentStatementType.IF_WITH_ELSE) {
314
 		if (position == ParentStatementType.IF_WITH_ELSE) {
314
 			if (settings.elseBracketOnSameLine)
315
 			if (settings.elseBracketOnSameLine)
315
-				result.append(" ");
316
+				output.append(" ");
316
 			else
317
 			else
317
-				result.append("\n").append(indent);
318
+				output.append("\n").append(indent);
318
 		}
319
 		}
319
 	}
320
 	}
320
 	
321
 	
321
 	private void beginSingleLine(WhitespaceInfo whitespace) {
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
 		if (whitespace != null) {
326
 		if (whitespace != null) {
325
 			if (whitespace.emptyLine) {
327
 			if (whitespace.emptyLine) {
326
-				result.append("\n").append(indent);
328
+				output.append("\n").append(indent);
327
 			}
329
 			}
328
 			writeComments(whitespace.commentsBefore);
330
 			writeComments(whitespace.commentsBefore);
329
 		}
331
 		}
331
 	
333
 	
332
 	private void endSingleLine(WhitespaceInfo whitespace) {
334
 	private void endSingleLine(WhitespaceInfo whitespace) {
333
 		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
335
 		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
334
-			result.append(' ').append(whitespace.commentsAfter);
336
+			output.append(' ').append(whitespace.commentsAfter);
335
 		
337
 		
336
 		if (position == ParentStatementType.IF_WITH_ELSE)
338
 		if (position == ParentStatementType.IF_WITH_ELSE)
337
-			result.append("\n").append(indent);
339
+			output.append("\n").append(indent);
338
 	}
340
 	}
339
 	
341
 	
340
 	private void writeComments(String[] comments) {
342
 	private void writeComments(String[] comments) {
341
 		for (String comment : CommentFormatter.format(comments)) {
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
 	private void writePostComments(String[] comments) {
348
 	private void writePostComments(String[] comments) {
347
 		for (String comment : CommentFormatter.format(comments)) {
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 View File

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

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

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

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

56
 	}
56
 	}
57
 
57
 
58
 	@Override
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
 		throw new UnsupportedOperationException("Cannot be called statically");
60
 		throw new UnsupportedOperationException("Cannot be called statically");
61
 	}
61
 	}
62
 
62
 
63
 	@Override
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
 		throw new UnsupportedOperationException("Cannot be called statically");
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 View File

5
  */
5
  */
6
 package org.openzen.zenscript.codemodel.member;
6
 package org.openzen.zenscript.codemodel.member;
7
 
7
 
8
-import java.util.List;
9
 import org.openzen.zenscript.codemodel.CompareType;
8
 import org.openzen.zenscript.codemodel.CompareType;
10
 import org.openzen.zenscript.codemodel.FunctionHeader;
9
 import org.openzen.zenscript.codemodel.FunctionHeader;
11
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
10
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
15
 import org.openzen.zenscript.codemodel.expression.Expression;
14
 import org.openzen.zenscript.codemodel.expression.Expression;
16
 import org.openzen.zenscript.codemodel.expression.GenericCompareExpression;
15
 import org.openzen.zenscript.codemodel.expression.GenericCompareExpression;
17
 import org.openzen.zenscript.codemodel.statement.Statement;
16
 import org.openzen.zenscript.codemodel.statement.Statement;
17
+import org.openzen.zenscript.codemodel.type.ITypeID;
18
 import org.openzen.zenscript.shared.CodePosition;
18
 import org.openzen.zenscript.shared.CodePosition;
19
 
19
 
20
 /**
20
 /**
57
 	}
57
 	}
58
 	
58
 	
59
 	@Override
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
 	@Override
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 View File

9
 import org.openzen.zenscript.codemodel.FunctionHeader;
9
 import org.openzen.zenscript.codemodel.FunctionHeader;
10
 import org.openzen.zenscript.codemodel.expression.CallArguments;
10
 import org.openzen.zenscript.codemodel.expression.CallArguments;
11
 import org.openzen.zenscript.codemodel.expression.Expression;
11
 import org.openzen.zenscript.codemodel.expression.Expression;
12
+import org.openzen.zenscript.codemodel.type.ITypeID;
12
 import org.openzen.zenscript.shared.CodePosition;
13
 import org.openzen.zenscript.shared.CodePosition;
13
 
14
 
14
 /**
15
 /**
24
 	
25
 	
25
 	public Expression callWithComparator(CodePosition position, CompareType operator, Expression target, FunctionHeader instancedHeader, CallArguments arguments);
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 View File

58
 	}
58
 	}
59
 
59
 
60
 	@Override
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
 		throw new UnsupportedOperationException("Can't call a comparator");
62
 		throw new UnsupportedOperationException("Can't call a comparator");
63
 	}
63
 	}
64
 
64
 
65
 	@Override
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
 		throw new UnsupportedOperationException("Can't call a comparator statically");
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 View File

23
  * @author Hoofdgebruiker
23
  * @author Hoofdgebruiker
24
  */
24
  */
25
 public class PartialStaticMemberGroupExpression implements IPartialExpression {
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
 		DefinitionMemberGroup group = new DefinitionMemberGroup();
27
 		DefinitionMemberGroup group = new DefinitionMemberGroup();
28
 		group.addMethod(method, TypeMemberPriority.SPECIFIED);
28
 		group.addMethod(method, TypeMemberPriority.SPECIFIED);
29
-		return new PartialStaticMemberGroupExpression(position, group);
29
+		return new PartialStaticMemberGroupExpression(position, target, group);
30
 	}
30
 	}
31
 	
31
 	
32
 	private final CodePosition position;
32
 	private final CodePosition position;
33
+	private final ITypeID target;
33
 	private final DefinitionMemberGroup group;
34
 	private final DefinitionMemberGroup group;
34
 	
35
 	
35
-	public PartialStaticMemberGroupExpression(CodePosition position, DefinitionMemberGroup group) {
36
+	public PartialStaticMemberGroupExpression(CodePosition position, ITypeID target, DefinitionMemberGroup group) {
36
 		this.position = position;
37
 		this.position = position;
37
 		this.group = group;
38
 		this.group = group;
39
+		this.target = target;
38
 	}
40
 	}
39
 	
41
 	
40
 	@Override
42
 	@Override
62
 
64
 
63
 	@Override
65
 	@Override
64
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
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
 	@Override
70
 	@Override

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

58
 
58
 
59
 	@Override
59
 	@Override
60
 	public Expression call(CodePosition position, TypeScope scope, List<ITypeID> hints, CallArguments arguments) {
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 View File

244
 		return method.callWithComparator(position, compareType, target, instancedHeader, arguments);
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
 		ICallableMember method = selectMethod(position, scope, arguments, false, true);
248
 		ICallableMember method = selectMethod(position, scope, arguments, false, true);
249
 		FunctionHeader instancedHeader = method.getHeader().withGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
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
 	public Expression callStaticWithComparator(
253
 	public Expression callStaticWithComparator(
254
 			CodePosition position,
254
 			CodePosition position,
255
+			ITypeID target, 
255
 			TypeScope scope,
256
 			TypeScope scope,
256
 			CallArguments arguments,
257
 			CallArguments arguments,
257
 			CompareType compareType) {
258
 			CompareType compareType) {
258
 		ICallableMember method = selectMethod(position, scope, arguments, false, true);
259
 		ICallableMember method = selectMethod(position, scope, arguments, false, true);
259
 		FunctionHeader instancedHeader = method.getHeader().withGenericArguments(scope.getTypeRegistry(), arguments.typeArguments);
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
 	public ICallableMember selectMethod(CodePosition position, TypeScope scope, CallArguments arguments, boolean allowNonStatic, boolean allowStatic) {
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 View File

358
 	
358
 	
359
 	public IPartialExpression getStaticMemberExpression(CodePosition position, GenericName name) {
359
 	public IPartialExpression getStaticMemberExpression(CodePosition position, GenericName name) {
360
 		if (members.containsKey(name.name))
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
 		if (innerTypes.containsKey(name.name))
362
 		if (innerTypes.containsKey(name.name))
363
 			return new PartialTypeExpression(position, innerTypes.get(name.name).instance(cache.getRegistry(), name.arguments));
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 View File

139
 	}
139
 	}
140
 	
140
 	
141
 	public WhitespaceInfo collectWhitespaceInfoForBlock(String whitespace) {
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
 	@Override
149
 	@Override

+ 42
- 39
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatement.java View File

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

Loading…
Cancel
Save