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

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

kindlich преди 6 години
родител
ревизия
1a262f7c09
No known key found for this signature in database
променени са 25 файла, в които са добавени 450 реда и са изтрити 94 реда
  1. 56
    0
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/CommentFormatter.java
  2. 9
    0
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FileFormatter.java
  3. 89
    34
      CodeFormatter/src/main/java/org/openzen/zenscript/formatter/StatementFormatter.java
  4. 49
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/WhitespaceInfo.java
  5. 38
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/WhitespacePostComment.java
  6. 1
    1
      Parser/src/main/java/org/openzen/zenscript/lexer/TokenStream.java
  7. 47
    0
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenStream.java
  8. 8
    2
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java
  9. 61
    14
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatement.java
  10. 11
    4
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementBlock.java
  11. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementBreak.java
  12. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementContinue.java
  13. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementDoWhile.java
  14. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementExpression.java
  15. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementForeach.java
  16. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementIf.java
  17. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementLock.java
  18. 4
    4
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementNull.java
  19. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementReturn.java
  20. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementThrow.java
  21. 4
    2
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementTryCatch.java
  22. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementVar.java
  23. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementWhile.java
  24. 26
    0
      Shared/src/main/java/org/openzen/zenscript/shared/StringUtils.java
  25. 3
    0
      Shared/src/main/java/org/openzen/zenscript/shared/TagDictionary.java

+ 56
- 0
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/CommentFormatter.java Целия файл

@@ -0,0 +1,56 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.formatter;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public class CommentFormatter {
13
+	private CommentFormatter() {}
14
+	
15
+	public static String[] format(String[] comments) {
16
+		if (comments.length == 0)
17
+			return comments;
18
+		
19
+		boolean isInMultilineComment = false;
20
+		String[] result = new String[comments.length];
21
+		for (int i = 0; i < comments.length; i++) {
22
+			String comment = comments[i];
23
+			if (isInMultilineComment) {
24
+				if (!comment.startsWith("*"))
25
+					comment = "* " + comment;
26
+				comment = " " + comment;
27
+			}
28
+			
29
+			result[i] = comment;
30
+			
31
+			int index = 0;
32
+			while (true) {
33
+				if (!isInMultilineComment && comment.indexOf("//", index) > 0)
34
+					break;
35
+				
36
+				int newIndexOpen = comment.indexOf("/*", index);
37
+				if (newIndexOpen >= 0) {
38
+					isInMultilineComment = true;
39
+					index = newIndexOpen;
40
+				} else {
41
+					break;
42
+				}
43
+				
44
+				int newIndexClose = comment.indexOf("*/", newIndexOpen);
45
+				if (newIndexClose >= 0) {
46
+					isInMultilineComment = false;
47
+					index = newIndexClose;
48
+				} else {
49
+					break;
50
+				}
51
+			}
52
+		}
53
+		
54
+		return result;
55
+	}
56
+}

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

@@ -12,6 +12,7 @@ import java.util.List;
12 12
 import java.util.Map;
13 13
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
14 14
 import org.openzen.zenscript.codemodel.ScriptBlock;
15
+import org.openzen.zenscript.codemodel.WhitespacePostComment;
15 16
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
16 17
 import org.openzen.zenscript.codemodel.statement.Statement;
17 18
 
@@ -41,6 +42,14 @@ public class FileFormatter {
41 42
 		StringBuilder output = new StringBuilder();
42 43
 		importer.write(output);
43 44
 		output.append(scriptFormatter.toString().trim());
45
+		
46
+		WhitespacePostComment postComment = script.getTag(WhitespacePostComment.class);
47
+		if (postComment != null) {
48
+			for (String comment : CommentFormatter.format(postComment.comments)) {
49
+				output.append("\n").append(comment);
50
+			}
51
+		}
52
+		
44 53
 		return output.toString();
45 54
 	}
46 55
 	

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

@@ -5,6 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.formatter;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
9
+import org.openzen.zenscript.codemodel.WhitespacePostComment;
8 10
 import org.openzen.zenscript.codemodel.expression.Expression;
9 11
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
10 12
 import org.openzen.zenscript.codemodel.statement.BreakStatement;
@@ -51,43 +53,54 @@ public class StatementFormatter implements StatementVisitor<Void> {
51 53
 
52 54
 	@Override
53 55
 	public Void visitBlock(BlockStatement statement) {
54
-		beginBlock();
56
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
57
+		beginBlock(whitespace);
55 58
 		
56 59
 		String oldIndent = indent;
57 60
 		indent = oldIndent + settings.indent;
58 61
 		for (Statement subStatement : statement.statements) {
59 62
 			format(ParentStatementType.NONE, subStatement);
60 63
 		}
64
+		
65
+		WhitespacePostComment postComment = statement.getTag(WhitespacePostComment.class);
66
+		if (postComment != null) {
67
+			writePostComments(postComment.comments);
68
+		}
69
+		
61 70
 		indent = oldIndent;
62
-		endBlock();
71
+		
72
+		endBlock(whitespace);
63 73
 		return null;
64 74
 	}
65 75
 
66 76
 	@Override
67 77
 	public Void visitBreak(BreakStatement statement) {
68
-		beginSingleLine();
78
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
79
+		beginSingleLine(whitespace);
69 80
 		result.append("break");
70
-		if (statement.target != null)
81
+		if (statement.target.label != null)
71 82
 			result.append(' ').append(statement.target.label);
72 83
 		result.append(";");
73
-		endSingleLine();
84
+		endSingleLine(whitespace);
74 85
 		return null;
75 86
 	}
76 87
 
77 88
 	@Override
78 89
 	public Void visitContinue(ContinueStatement statement) {
79
-		beginSingleLine();
90
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
91
+		beginSingleLine(whitespace);
80 92
 		result.append("continue");
81
-		if (statement.target != null)
93
+		if (statement.target.label != null)
82 94
 			result.append(' ').append(statement.target.label);
83 95
 		result.append(";");
84
-		endSingleLine();
96
+		endSingleLine(whitespace);
85 97
 		return null;
86 98
 	}
87 99
 
88 100
 	@Override
89 101
 	public Void visitDoWhile(DoWhileStatement statement) {
90
-		beginSingleLine();
102
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
103
+		beginSingleLine(whitespace);
91 104
 		result.append("do");
92 105
 		if (statement.label != null) {
93 106
 			if (settings.spaceBeforeLabelColon)
@@ -101,30 +114,33 @@ public class StatementFormatter implements StatementVisitor<Void> {
101 114
 		result.append(" while ");
102 115
 		appendCondition(statement.condition);
103 116
 		result.append(";");
104
-		endSingleLine();
117
+		endSingleLine(whitespace);
105 118
 		return null;
106 119
 	}
107 120
 
108 121
 	@Override
109 122
 	public Void visitEmpty(EmptyStatement statement) {
110
-		beginSingleLine();
123
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
124
+		beginSingleLine(whitespace);
111 125
 		result.append(";\n");
112
-		endSingleLine();
126
+		endSingleLine(whitespace);
113 127
 		return null;
114 128
 	}
115 129
 
116 130
 	@Override
117 131
 	public Void visitExpression(ExpressionStatement statement) {
118
-		beginSingleLine();
132
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
133
+		beginSingleLine(whitespace);
119 134
 		result.append(statement.expression.accept(expressionFormatter).value)
120 135
 			  .append(";");
121
-		endSingleLine();
136
+		endSingleLine(whitespace);
122 137
 		return null;
123 138
 	}
124 139
 
125 140
 	@Override
126 141
 	public Void visitForeach(ForeachStatement statement) {
127
-		beginSingleLine();
142
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
143
+		beginSingleLine(whitespace);
128 144
 		result.append("for ");
129 145
 		for (int i = 0; i < statement.loopVariables.length; i++) {
130 146
 			if (i > 0)
@@ -135,14 +151,15 @@ public class StatementFormatter implements StatementVisitor<Void> {
135 151
 		result.append(" in ");
136 152
 		result.append(statement.list.accept(expressionFormatter).value);
137 153
 		format(ParentStatementType.LOOP, statement.content);
138
-		endSingleLine();
154
+		endSingleLine(whitespace);
139 155
 		return null;
140 156
 	}
141 157
 
142 158
 	@Override
143 159
 	public Void visitIf(IfStatement statement) {
160
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
144 161
 		ParentStatementType position = this.position;
145
-		beginSingleLine();
162
+		beginSingleLine(whitespace);
146 163
 		result.append("if ");
147 164
 		appendCondition(statement.condition);
148 165
 		format(statement.onElse == null ? ParentStatementType.IF : ParentStatementType.IF_WITH_ELSE, statement.onThen);
@@ -150,44 +167,48 @@ public class StatementFormatter implements StatementVisitor<Void> {
150 167
 			result.append("else");
151 168
 			format(ParentStatementType.ELSE, statement.onElse);
152 169
 		}
153
-		endSingleLine();
170
+		endSingleLine(whitespace);
154 171
 		return null;
155 172
 	}
156 173
 
157 174
 	@Override
158 175
 	public Void visitLock(LockStatement statement) {
159
-		beginSingleLine();
176
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
177
+		beginSingleLine(whitespace);
160 178
 		result.append("lock ");
161 179
 		result.append(statement.object.accept(expressionFormatter).value);
162 180
 		statement.content.accept(this);
163
-		endSingleLine();
181
+		endSingleLine(whitespace);
164 182
 		return null;
165 183
 	}
166 184
 
167 185
 	@Override
168 186
 	public Void visitReturn(ReturnStatement statement) {
169
-		beginSingleLine();
187
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
188
+		beginSingleLine(whitespace);
170 189
 		result.append("return");
171 190
 		if (statement.value != null) {
172 191
 			result.append(' ');
173 192
 			result.append(statement.value.accept(expressionFormatter).value);
174 193
 		}
175 194
 		result.append(";");
176
-		endSingleLine();
195
+		endSingleLine(whitespace);
177 196
 		return null;
178 197
 	}
179 198
 
180 199
 	@Override
181 200
 	public Void visitThrow(ThrowStatement statement) {
182
-		beginSingleLine();
201
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
202
+		beginSingleLine(whitespace);
183 203
 		result.append("throw ").append(statement.value.accept(expressionFormatter));
184
-		endSingleLine();
204
+		endSingleLine(whitespace);
185 205
 		return null;
186 206
 	}
187 207
 
188 208
 	@Override
189 209
 	public Void visitTryCatch(TryCatchStatement statement) {
190
-		beginSingleLine();
210
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
211
+		beginSingleLine(whitespace);
191 212
 		result.append("try");
192 213
 		if (statement.resource != null) {
193 214
 			result.append(' ').append(statement.resource.name);
@@ -213,13 +234,14 @@ public class StatementFormatter implements StatementVisitor<Void> {
213 234
 			
214 235
 			format(ParentStatementType.FINALLY, statement.finallyClause);
215 236
 		}
216
-		endSingleLine();
237
+		endSingleLine(whitespace);
217 238
 		return null;
218 239
 	}
219 240
 
220 241
 	@Override
221 242
 	public Void visitVar(VarStatement statement) {
222
-		beginSingleLine();
243
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
244
+		beginSingleLine(whitespace);
223 245
 		result.append(statement.isFinal ? "val " : "var ");
224 246
 		result.append(statement.name);
225 247
 		
@@ -232,13 +254,14 @@ public class StatementFormatter implements StatementVisitor<Void> {
232 254
 			result.append(statement.initializer.accept(expressionFormatter).value);
233 255
 		}
234 256
 		result.append(";");
235
-		endSingleLine();
257
+		endSingleLine(whitespace);
236 258
 		return null;
237 259
 	}
238 260
 
239 261
 	@Override
240 262
 	public Void visitWhile(WhileStatement statement) {
241
-		beginSingleLine();
263
+		WhitespaceInfo whitespace = statement.getTag(WhitespaceInfo.class);
264
+		beginSingleLine(whitespace);
242 265
 		result.append("while");
243 266
 		if (statement.label != null) {
244 267
 			if (settings.spaceBeforeLabelColon)
@@ -252,7 +275,7 @@ public class StatementFormatter implements StatementVisitor<Void> {
252 275
 		appendCondition(statement.condition);
253 276
 		
254 277
 		format(ParentStatementType.LOOP, statement.content);
255
-		endSingleLine();
278
+		endSingleLine(whitespace);
256 279
 		return null;
257 280
 	}
258 281
 	
@@ -271,11 +294,21 @@ public class StatementFormatter implements StatementVisitor<Void> {
271 294
 			result.append(')');
272 295
 	}
273 296
 	
274
-	private void beginBlock() {
297
+	private void beginBlock(WhitespaceInfo whitespace) {
275 298
 		result.append(settings.getBlockSeparator(indent, position));
299
+		
300
+		if (whitespace != null) {
301
+			if (whitespace.emptyLine) {
302
+				result.append("\n").append(indent);
303
+			}
304
+			writeComments(whitespace.commentsBefore);
305
+		}
276 306
 	}
277 307
 	
278
-	private void endBlock() {
308
+	private void endBlock(WhitespaceInfo whitespace) {
309
+		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
310
+			result.append(' ').append(whitespace.commentsAfter);
311
+		
279 312
 		result.append("\n").append(indent).append("}");
280 313
 		if (position == ParentStatementType.IF_WITH_ELSE) {
281 314
 			if (settings.elseBracketOnSameLine)
@@ -285,12 +318,34 @@ public class StatementFormatter implements StatementVisitor<Void> {
285 318
 		}
286 319
 	}
287 320
 	
288
-	private void beginSingleLine() {
321
+	private void beginSingleLine(WhitespaceInfo whitespace) {
289 322
 		result.append(settings.getSingleLineSeparator(indent, position));
323
+		
324
+		if (whitespace != null) {
325
+			if (whitespace.emptyLine) {
326
+				result.append("\n").append(indent);
327
+			}
328
+			writeComments(whitespace.commentsBefore);
329
+		}
290 330
 	}
291 331
 	
292
-	private void endSingleLine() {
332
+	private void endSingleLine(WhitespaceInfo whitespace) {
333
+		if (whitespace != null && !whitespace.commentsAfter.isEmpty())
334
+			result.append(' ').append(whitespace.commentsAfter);
335
+		
293 336
 		if (position == ParentStatementType.IF_WITH_ELSE)
294 337
 			result.append("\n").append(indent);
295 338
 	}
339
+	
340
+	private void writeComments(String[] comments) {
341
+		for (String comment : CommentFormatter.format(comments)) {
342
+			result.append(comment).append("\n").append(indent);
343
+		}
344
+	}
345
+	
346
+	private void writePostComments(String[] comments) {
347
+		for (String comment : CommentFormatter.format(comments)) {
348
+			result.append("\n").append(indent).append(comment);
349
+		}
350
+	}
296 351
 }

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

@@ -0,0 +1,49 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.codemodel;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import org.openzen.zenscript.shared.StringUtils;
11
+
12
+/**
13
+ *
14
+ * @author Hoofdgebruiker
15
+ */
16
+public class WhitespaceInfo {
17
+	public static WhitespaceInfo from(String whitespaceBefore, String lineAfter) {
18
+		int numNewLines = 0;
19
+		for (char c : whitespaceBefore.toCharArray())
20
+			if (c == '\n')
21
+				numNewLines++;
22
+		
23
+		List<String> split = StringUtils.split(whitespaceBefore, '\n');
24
+		List<String> commentsBefore = new ArrayList<>();
25
+		for (String splitLine : split) {
26
+			String trimmed = splitLine.trim();
27
+			if (trimmed.isEmpty())
28
+				continue;
29
+			
30
+			commentsBefore.add(trimmed);
31
+		}
32
+		
33
+		boolean emptyLine = numNewLines - commentsBefore.size() > 0;
34
+		return new WhitespaceInfo(
35
+				emptyLine,
36
+				commentsBefore.toArray(new String[commentsBefore.size()]),
37
+				lineAfter.trim());
38
+	}
39
+	
40
+	public boolean emptyLine;
41
+	public String[] commentsBefore;
42
+	public String commentsAfter;
43
+	
44
+	public WhitespaceInfo(boolean emptyLine, String[] commentsBefore, String commentsAfter) {
45
+		this.emptyLine = emptyLine;
46
+		this.commentsBefore = commentsBefore;
47
+		this.commentsAfter = commentsAfter;
48
+	}
49
+}

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

@@ -0,0 +1,38 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.codemodel;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import org.openzen.zenscript.shared.StringUtils;
11
+
12
+/**
13
+ *
14
+ * @author Hoofdgebruiker
15
+ */
16
+public class WhitespacePostComment {
17
+	public static WhitespacePostComment fromWhitespace(String whitespace) {
18
+		List<String> comments = new ArrayList<>();
19
+		for (String line : StringUtils.split(whitespace, '\n')) {
20
+			line = line.trim();
21
+			if (line.isEmpty())
22
+				continue;
23
+			
24
+			comments.add(line);
25
+		}
26
+		
27
+		if (comments.isEmpty())
28
+			return null;
29
+		
30
+		return new WhitespacePostComment(comments.toArray(new String[comments.size()]));
31
+	}
32
+	
33
+	public final String[] comments;
34
+	
35
+	public WhitespacePostComment(String[] comments) {
36
+		this.comments = comments;
37
+	}
38
+}

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

@@ -294,7 +294,7 @@ public abstract class TokenStream<T extends Token<TT>, TT extends TokenType> imp
294 294
 					line,
295 295
 					lineOffset);
296 296
 			
297
-            next = createToken(position, "", "", eof);
297
+            next = createToken(position, whitespace, "", eof);
298 298
             return;
299 299
         }
300 300
 		

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

@@ -9,6 +9,7 @@ import java.io.IOException;
9 9
 import java.io.Reader;
10 10
 import java.util.HashMap;
11 11
 import java.util.Map;
12
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
12 13
 import org.openzen.zenscript.shared.CompileException;
13 14
 import org.openzen.zenscript.shared.CompileExceptionCode;
14 15
 import static org.openzen.zenscript.lexer.ZSTokenType.*;
@@ -95,10 +96,56 @@ public class ZSTokenStream extends TokenStream<ZSToken, ZSTokenType> {
95 96
 		KEYWORDS.put("new", K_NEW);
96 97
 	}
97 98
 	
99
+	private String whitespaceBuffer = null;
100
+	
98 101
 	public ZSTokenStream(String filename, Reader reader) {
99 102
 		super(filename, reader, DFA, ZSTokenType.EOF);
100 103
 	}
101 104
 	
105
+	public String loadWhitespace() {
106
+		if (whitespaceBuffer == null)
107
+			whitespaceBuffer = peek().whitespaceBefore;
108
+		
109
+		return whitespaceBuffer;
110
+	}
111
+	
112
+	public void reloadWhitespace() {
113
+		whitespaceBuffer = peek().whitespaceBefore;
114
+	}
115
+	
116
+	public String grabWhitespace() {
117
+		String result = loadWhitespace();
118
+		whitespaceBuffer = null;
119
+		return result;
120
+	}
121
+	
122
+	public String grabWhitespaceLine() {
123
+		String whitespace = loadWhitespace();
124
+		if (whitespace.contains("\n")) {
125
+			int index = whitespace.indexOf('\n');
126
+			whitespaceBuffer = whitespace.substring(index + 1);
127
+			return whitespace.substring(0, index);
128
+		} else {
129
+			whitespaceBuffer = "";
130
+			return whitespace;
131
+		}
132
+	}
133
+	
134
+	public void skipWhitespaceNewline() {
135
+		loadWhitespace();
136
+		int index = whitespaceBuffer.indexOf('\n');
137
+		if (index >= 0)
138
+			whitespaceBuffer = whitespaceBuffer.substring(index + 1);
139
+	}
140
+	
141
+	public WhitespaceInfo collectWhitespaceInfoForBlock(String whitespace) {
142
+		return WhitespaceInfo.from(whitespace, "");
143
+	}
144
+	
145
+	public WhitespaceInfo collectWhitespaceInfo(String whitespace) {
146
+		return WhitespaceInfo.from(whitespace, grabWhitespaceLine());
147
+	}
148
+	
102 149
 	@Override
103 150
 	protected ZSToken createToken(CodePosition position, String whitespaceBefore, String value, ZSTokenType tokenType) {
104 151
 		if (tokenType == T_IDENTIFIER && KEYWORDS.containsKey(value))

+ 8
- 2
Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java Целия файл

@@ -18,10 +18,12 @@ import org.openzen.zenscript.codemodel.HighLevelDefinition;
18 18
 import org.openzen.zenscript.codemodel.Modifiers;
19 19
 import org.openzen.zenscript.codemodel.PackageDefinitions;
20 20
 import org.openzen.zenscript.codemodel.ScriptBlock;
21
+import org.openzen.zenscript.codemodel.WhitespacePostComment;
21 22
 import org.openzen.zenscript.codemodel.definition.ExpansionDefinition;
22 23
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
23 24
 import org.openzen.zenscript.codemodel.statement.Statement;
24 25
 import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
26
+import org.openzen.zenscript.lexer.ZSToken;
25 27
 import org.openzen.zenscript.shared.CodePosition;
26 28
 import org.openzen.zenscript.shared.CompileException;
27 29
 import org.openzen.zenscript.shared.CompileExceptionCode;
@@ -58,6 +60,7 @@ public class ParsedFile {
58 60
 		ParsedFile result = new ParsedFile(filename);
59 61
 		
60 62
 		ZSTokenStream tokens = new ZSTokenStream(filename, reader);
63
+		ZSToken eof = null;
61 64
 
62 65
 		while (true) {
63 66
 			CodePosition position = tokens.peek().position;
@@ -96,7 +99,7 @@ public class ParsedFile {
96 99
 
97 100
 			if (tokens.optional(K_IMPORT) != null) {
98 101
 				result.imports.add(ParsedImport.parse(position, tokens));
99
-			} else if (tokens.optional(EOF) != null) {
102
+			} else if ((eof = tokens.optional(EOF)) != null) {
100 103
 				break;
101 104
 			} else {
102 105
 				ParsedDefinition definition = ParsedDefinition.parse(pkg, position, modifiers, tokens, null);
@@ -110,6 +113,7 @@ public class ParsedFile {
110 113
 			}
111 114
 		}
112 115
 		
116
+		result.postComment = WhitespacePostComment.fromWhitespace(eof.whitespaceBefore);
113 117
 		return result;
114 118
 	}
115 119
 	
@@ -119,6 +123,7 @@ public class ParsedFile {
119 123
 	private final List<ParsedDefinition> definitions = new ArrayList<>();
120 124
 	private final List<ParsedStatement> statements = new ArrayList<>();
121 125
 	private final AccessScope access = new AccessScope();
126
+	private WhitespacePostComment postComment = null;
122 127
 	
123 128
 	public ParsedFile(String filename) {
124 129
 		this.filename = filename;
@@ -165,7 +170,7 @@ public class ParsedFile {
165 170
 			definition.compileCode(scope);
166 171
 		}
167 172
 		
168
-		if (!statements.isEmpty()) {
173
+		if (!statements.isEmpty() || postComment != null) {
169 174
 			StatementScope statementScope = new GlobalScriptScope(scope);
170 175
 			List<Statement> statements = new ArrayList<>();
171 176
 			for (ParsedStatement statement : this.statements) {
@@ -174,6 +179,7 @@ public class ParsedFile {
174 179
 			
175 180
 			ScriptBlock block = new ScriptBlock(statements);
176 181
 			block.setTag(SourceFile.class, new SourceFile(filename));
182
+			block.setTag(WhitespacePostComment.class, postComment);
177 183
 			scripts.add(block);
178 184
 		}
179 185
 	}

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

@@ -2,6 +2,8 @@ package org.openzen.zenscript.parser.statements;
2 2
 
3 3
 import java.util.ArrayList;
4 4
 import java.util.List;
5
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
6
+import org.openzen.zenscript.codemodel.WhitespacePostComment;
5 7
 import org.openzen.zenscript.codemodel.statement.Statement;
6 8
 import org.openzen.zenscript.lexer.ZSToken;
7 9
 import org.openzen.zenscript.lexer.ZSTokenStream;
@@ -45,15 +47,25 @@ public abstract class ParsedStatement {
45 47
 	}
46 48
 	
47 49
 	public static ParsedStatement parse(ZSTokenStream parser) {
50
+		String ws = parser.grabWhitespace();
48 51
 		ZSToken next = parser.peek();
49 52
 		switch (next.getType()) {
50 53
 			case T_AOPEN: {
51 54
 				ZSToken t = parser.next();
55
+				
56
+				parser.reloadWhitespace();
57
+				parser.skipWhitespaceNewline();
58
+				
52 59
 				ArrayList<ParsedStatement> statements = new ArrayList<>();
53
-				while (parser.optional(T_ACLOSE) == null) {
60
+				ZSToken last;
61
+				while ((last = parser.optional(T_ACLOSE)) == null) {
54 62
 					statements.add(parse(parser));
55 63
 				}
56
-				return new ParsedStatementBlock(t.getPosition(), statements);
64
+				
65
+				parser.reloadWhitespace();
66
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfoForBlock(ws);
67
+				WhitespacePostComment postComment = WhitespacePostComment.fromWhitespace(last.whitespaceBefore);
68
+				return new ParsedStatementBlock(t.getPosition(), whitespace, postComment, statements);
57 69
 			}
58 70
 			case K_RETURN: {
59 71
 				parser.next();
@@ -62,7 +74,9 @@ public abstract class ParsedStatement {
62 74
 					expression = ParsedExpression.parse(parser);
63 75
 				}
64 76
 				parser.required(T_SEMICOLON, "; expected");
65
-				return new ParsedStatementReturn(next.getPosition(), expression);
77
+				
78
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
79
+				return new ParsedStatementReturn(next.getPosition(), whitespace, expression);
66 80
 			}
67 81
 			case K_VAR:
68 82
 			case K_VAL: {
@@ -78,17 +92,24 @@ public abstract class ParsedStatement {
78 92
 					initializer = ParsedExpression.parse(parser);
79 93
 				}
80 94
 				parser.required(T_SEMICOLON, "; expected");
81
-				return new ParsedStatementVar(start.getPosition(), name, type, initializer, start.getType() == K_VAL);
95
+				
96
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
97
+				return new ParsedStatementVar(start.getPosition(), whitespace, name, type, initializer, start.getType() == K_VAL);
82 98
 			}
83 99
 			case K_IF: {
84 100
 				ZSToken t = parser.next();
85 101
 				ParsedExpression expression = ParsedExpression.parse(parser);
102
+				parser.skipWhitespaceNewline();
86 103
 				ParsedStatement onIf = parse(parser);
87 104
 				ParsedStatement onElse = null;
88 105
 				if (parser.optional(K_ELSE) != null) {
106
+					parser.reloadWhitespace();
107
+					parser.skipWhitespaceNewline();
89 108
 					onElse = parse(parser);
90 109
 				}
91
-				return new ParsedStatementIf(t.getPosition(), expression, onIf, onElse);
110
+				
111
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
112
+				return new ParsedStatementIf(t.getPosition(), whitespace, expression, onIf, onElse);
92 113
 			}
93 114
 			case K_FOR: {
94 115
 				ZSToken t = parser.next();
@@ -103,8 +124,11 @@ public abstract class ParsedStatement {
103 124
 				parser.required(K_IN, "in expected");
104 125
 				ParsedExpression source = ParsedExpression.parse(parser);
105 126
 				ParsedStatement content = parse(parser);
127
+				
128
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
106 129
 				return new ParsedStatementForeach(
107 130
 						t.getPosition(),
131
+						whitespace,
108 132
 						names.toArray(new String[names.size()]),
109 133
 						source,
110 134
 						content);
@@ -119,7 +143,9 @@ public abstract class ParsedStatement {
119 143
 				parser.required(K_WHILE, "while expected");
120 144
 				ParsedExpression condition = ParsedExpression.parse(parser);
121 145
 				parser.required(T_SEMICOLON, "; expected");
122
-				return new ParsedStatementDoWhile(t.position, label, content, condition);
146
+				
147
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
148
+				return new ParsedStatementDoWhile(t.position, whitespace, label, content, condition);
123 149
 			}
124 150
 			case K_WHILE: {
125 151
 				ZSToken t = parser.next();
@@ -129,19 +155,25 @@ public abstract class ParsedStatement {
129 155
 				
130 156
 				ParsedExpression condition = ParsedExpression.parse(parser);
131 157
 				ParsedStatement content = parse(parser);
132
-				return new ParsedStatementWhile(t.position, label, condition, content);
158
+				
159
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
160
+				return new ParsedStatementWhile(t.position, whitespace, label, condition, content);
133 161
 			}
134 162
 			case K_LOCK: {
135 163
 				ZSToken t = parser.next();
136 164
 				ParsedExpression object = ParsedExpression.parse(parser);
137 165
 				ParsedStatement content = parse(parser);
138
-				return new ParsedStatementLock(t.position, object, content);
166
+				
167
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
168
+				return new ParsedStatementLock(t.position, whitespace, object, content);
139 169
 			}
140 170
 			case K_THROW: {
141 171
 				ZSToken t = parser.next();
142 172
 				ParsedExpression value = ParsedExpression.parse(parser);
143 173
 				parser.required(T_SEMICOLON, "; expected");
144
-				return new ParsedStatementThrow(t.position, value);
174
+				
175
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
176
+				return new ParsedStatementThrow(t.position, whitespace, value);
145 177
 			}
146 178
 			case K_TRY: {
147 179
 				ZSToken t = parser.next();
@@ -174,7 +206,8 @@ public abstract class ParsedStatement {
174 206
 				if (parser.optional(K_FINALLY) != null)
175 207
 					finallyClause = ParsedStatement.parse(parser);
176 208
 				
177
-				return new ParsedStatementTryCatch(t.position, name, initializer, content, catchClauses, finallyClause);
209
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
210
+				return new ParsedStatementTryCatch(t.position, whitespace, name, initializer, content, catchClauses, finallyClause);
178 211
 			}
179 212
 			case K_CONTINUE: {
180 213
 				ZSToken t = parser.next();
@@ -183,7 +216,9 @@ public abstract class ParsedStatement {
183 216
 					name = parser.next().content;
184 217
 				
185 218
 				parser.required(T_SEMICOLON, "; expected");
186
-				return new ParsedStatementContinue(t.position, name);
219
+				
220
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
221
+				return new ParsedStatementContinue(t.position, whitespace, name);
187 222
 			}
188 223
 			case K_BREAK: {
189 224
 				ZSToken t = parser.next();
@@ -192,13 +227,18 @@ public abstract class ParsedStatement {
192 227
 					name = parser.next().content;
193 228
 				
194 229
 				parser.required(T_SEMICOLON, "; expected");
195
-				return new ParsedStatementBreak(t.position, name);
230
+				
231
+				WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
232
+				return new ParsedStatementBreak(t.position, whitespace, name);
196 233
 			}
197 234
 		}
198 235
 
199 236
 		CodePosition position = parser.peek().getPosition();
200
-		ParsedStatementExpression result = new ParsedStatementExpression(position, ParsedExpression.parse(parser));
237
+		ParsedExpression expression = ParsedExpression.parse(parser);
201 238
 		parser.required(T_SEMICOLON, "; expected");
239
+		WhitespaceInfo whitespace = parser.collectWhitespaceInfo(ws);
240
+		
241
+		ParsedStatementExpression result = new ParsedStatementExpression(position, whitespace, expression);
202 242
 		return result;
203 243
 	}
204 244
 	
@@ -213,10 +253,17 @@ public abstract class ParsedStatement {
213 253
 	}
214 254
 
215 255
 	public final CodePosition position;
256
+	public final WhitespaceInfo whitespace;
216 257
 
217
-	public ParsedStatement(CodePosition position) {
258
+	public ParsedStatement(CodePosition position, WhitespaceInfo whitespace) {
218 259
 		this.position = position;
260
+		this.whitespace = whitespace;
219 261
 	}
220 262
 
221 263
 	public abstract Statement compile(StatementScope scope);
264
+	
265
+	protected Statement result(Statement statement) {
266
+		statement.setTag(WhitespaceInfo.class, whitespace);
267
+		return statement;
268
+	}
222 269
 }

+ 11
- 4
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementBlock.java Целия файл

@@ -2,6 +2,8 @@ package org.openzen.zenscript.parser.statements;
2 2
 
3 3
 import java.util.ArrayList;
4 4
 import java.util.List;
5
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
6
+import org.openzen.zenscript.codemodel.WhitespacePostComment;
5 7
 import org.openzen.zenscript.codemodel.statement.BlockStatement;
6 8
 import org.openzen.zenscript.codemodel.statement.Statement;
7 9
 import org.openzen.zenscript.linker.BlockScope;
@@ -10,11 +12,13 @@ import org.openzen.zenscript.shared.CodePosition;
10 12
 
11 13
 public class ParsedStatementBlock extends ParsedStatement {
12 14
 	private final List<ParsedStatement> statements;
13
-
14
-	public ParsedStatementBlock(CodePosition position, List<ParsedStatement> statements) {
15
-		super(position);
15
+	private final WhitespacePostComment postComment;
16
+	
17
+	public ParsedStatementBlock(CodePosition position, WhitespaceInfo whitespace, WhitespacePostComment postComment, List<ParsedStatement> statements) {
18
+		super(position, whitespace);
16 19
 
17 20
 		this.statements = statements;
21
+		this.postComment = postComment;
18 22
 	}
19 23
 
20 24
 	@Override
@@ -24,6 +28,9 @@ public class ParsedStatementBlock extends ParsedStatement {
24 28
 		for (ParsedStatement statement : statements) {
25 29
 			compiled.add(statement.compile(blockScope));
26 30
 		}
27
-		return new BlockStatement(position, compiled);
31
+		BlockStatement block = new BlockStatement(position, compiled);
32
+		result(block);
33
+		block.setTag(WhitespacePostComment.class, postComment);
34
+		return block;
28 35
 	}
29 36
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementBreak.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.statements;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
8 9
 import org.openzen.zenscript.codemodel.statement.BreakStatement;
9 10
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
10 11
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -20,8 +21,8 @@ import org.openzen.zenscript.shared.CompileExceptionCode;
20 21
 public class ParsedStatementBreak extends ParsedStatement {
21 22
 	public final String name;
22 23
 	
23
-	public ParsedStatementBreak(CodePosition position, String name) {
24
-		super(position);
24
+	public ParsedStatementBreak(CodePosition position, WhitespaceInfo whitespace, String name) {
25
+		super(position, whitespace);
25 26
 		
26 27
 		this.name = name;
27 28
 	}
@@ -31,6 +32,6 @@ public class ParsedStatementBreak extends ParsedStatement {
31 32
 		LoopStatement target = scope.getLoop(name);
32 33
 		if (target == null)
33 34
 			throw new CompileException(position, CompileExceptionCode.BREAK_OUTSIDE_LOOP, name == null ? "Not in a loop" : "No such loop: " + name);
34
-		return new BreakStatement(position, target);
35
+		return result(new BreakStatement(position, target));
35 36
 	}
36 37
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementContinue.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.statements;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
8 9
 import org.openzen.zenscript.codemodel.statement.ContinueStatement;
9 10
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
10 11
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -20,8 +21,8 @@ import org.openzen.zenscript.shared.CompileExceptionCode;
20 21
 public class ParsedStatementContinue extends ParsedStatement {
21 22
 	public final String name;
22 23
 	
23
-	public ParsedStatementContinue(CodePosition position, String name) {
24
-		super(position);
24
+	public ParsedStatementContinue(CodePosition position, WhitespaceInfo whitespace, String name) {
25
+		super(position, whitespace);
25 26
 		
26 27
 		this.name = name;
27 28
 	}
@@ -31,6 +32,6 @@ public class ParsedStatementContinue extends ParsedStatement {
31 32
 		LoopStatement target = scope.getLoop(name);
32 33
 		if (target == null)
33 34
 			throw new CompileException(position, CompileExceptionCode.CONTINUE_OUTSIDE_LOOP, name == null ? "Not in a loop" : "No such loop: " + name);
34
-		return new ContinueStatement(position, target);
35
+		return result(new ContinueStatement(position, target));
35 36
 	}
36 37
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementDoWhile.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.statements;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
8 9
 import org.openzen.zenscript.codemodel.expression.Expression;
9 10
 import org.openzen.zenscript.codemodel.statement.DoWhileStatement;
10 11
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -24,8 +25,8 @@ public class ParsedStatementDoWhile extends ParsedStatement {
24 25
 	public final ParsedStatement content;
25 26
 	public final ParsedExpression condition;
26 27
 	
27
-	public ParsedStatementDoWhile(CodePosition position, String label, ParsedStatement content, ParsedExpression condition) {
28
-		super(position);
28
+	public ParsedStatementDoWhile(CodePosition position, WhitespaceInfo whitespace, String label, ParsedStatement content, ParsedExpression condition) {
29
+		super(position, whitespace);
29 30
 		
30 31
 		this.label = label;
31 32
 		this.content = content;
@@ -43,6 +44,6 @@ public class ParsedStatementDoWhile extends ParsedStatement {
43 44
 		DoWhileStatement result = new DoWhileStatement(position, label, condition);
44 45
 		LoopScope innerScope = new LoopScope(result, scope);
45 46
 		result.content = this.content.compile(innerScope);
46
-		return result;
47
+		return result(result);
47 48
 	}
48 49
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementExpression.java Целия файл

@@ -1,5 +1,6 @@
1 1
 package org.openzen.zenscript.parser.statements;
2 2
 
3
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
3 4
 import org.openzen.zenscript.codemodel.statement.ExpressionStatement;
4 5
 import org.openzen.zenscript.codemodel.statement.Statement;
5 6
 import org.openzen.zenscript.linker.ExpressionScope;
@@ -10,14 +11,14 @@ import org.openzen.zenscript.shared.CodePosition;
10 11
 public class ParsedStatementExpression extends ParsedStatement {
11 12
 	private final ParsedExpression expression;
12 13
 
13
-	public ParsedStatementExpression(CodePosition position, ParsedExpression expression) {
14
-		super(position);
14
+	public ParsedStatementExpression(CodePosition position, WhitespaceInfo whitespace, ParsedExpression expression) {
15
+		super(position, whitespace);
15 16
 
16 17
 		this.expression = expression;
17 18
 	}
18 19
 
19 20
 	@Override
20 21
 	public Statement compile(StatementScope scope) {
21
-		return new ExpressionStatement(position, this.expression.compile(new ExpressionScope(scope)).eval());
22
+		return result(new ExpressionStatement(position, this.expression.compile(new ExpressionScope(scope)).eval()));
22 23
 	}
23 24
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementForeach.java Целия файл

@@ -1,5 +1,6 @@
1 1
 package org.openzen.zenscript.parser.statements;
2 2
 
3
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
3 4
 import org.openzen.zenscript.codemodel.expression.Expression;
4 5
 import org.openzen.zenscript.codemodel.member.IIteratorMember;
5 6
 import org.openzen.zenscript.codemodel.statement.ForeachStatement;
@@ -19,8 +20,8 @@ public class ParsedStatementForeach extends ParsedStatement {
19 20
 	private final ParsedExpression list;
20 21
 	private final ParsedStatement body;
21 22
 
22
-	public ParsedStatementForeach(CodePosition position, String[] varnames, ParsedExpression list, ParsedStatement body) {
23
-		super(position);
23
+	public ParsedStatementForeach(CodePosition position, WhitespaceInfo whitespace, String[] varnames, ParsedExpression list, ParsedStatement body) {
24
+		super(position, whitespace);
24 25
 
25 26
 		this.varnames = varnames;
26 27
 		this.list = list;
@@ -43,6 +44,6 @@ public class ParsedStatementForeach extends ParsedStatement {
43 44
 		ForeachStatement statement = new ForeachStatement(position, variables, iterator, list);
44 45
 		ForeachScope innerScope = new ForeachScope(statement, scope);
45 46
 		statement.content = this.body.compile(innerScope);
46
-		return statement;
47
+		return result(statement);
47 48
 	}
48 49
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementIf.java Целия файл

@@ -1,5 +1,6 @@
1 1
 package org.openzen.zenscript.parser.statements;
2 2
 
3
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
3 4
 import org.openzen.zenscript.codemodel.expression.Expression;
4 5
 import org.openzen.zenscript.codemodel.statement.IfStatement;
5 6
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -14,8 +15,8 @@ public class ParsedStatementIf extends ParsedStatement {
14 15
 	private final ParsedStatement onThen;
15 16
 	private final ParsedStatement onElse;
16 17
 
17
-	public ParsedStatementIf(CodePosition position, ParsedExpression condition, ParsedStatement onThen, ParsedStatement onElse) {
18
-		super(position);
18
+	public ParsedStatementIf(CodePosition position, WhitespaceInfo whitespace, ParsedExpression condition, ParsedStatement onThen, ParsedStatement onElse) {
19
+		super(position, whitespace);
19 20
 
20 21
 		this.condition = condition;
21 22
 		this.onThen = onThen;
@@ -27,6 +28,6 @@ public class ParsedStatementIf extends ParsedStatement {
27 28
 		Expression condition = this.condition.compile(new ExpressionScope(scope, BasicTypeID.HINT_BOOL)).eval();
28 29
 		Statement onThen = this.onThen.compile(scope);
29 30
 		Statement onElse = this.onElse == null ? null : this.onElse.compile(scope);
30
-		return new IfStatement(position, condition, onThen, onElse);
31
+		return result(new IfStatement(position, condition, onThen, onElse));
31 32
 	}
32 33
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementLock.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.statements;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
8 9
 import org.openzen.zenscript.codemodel.expression.Expression;
9 10
 import org.openzen.zenscript.codemodel.statement.LockStatement;
10 11
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -21,8 +22,8 @@ public class ParsedStatementLock extends ParsedStatement {
21 22
 	public final ParsedExpression object;
22 23
 	public final ParsedStatement content;
23 24
 	
24
-	public ParsedStatementLock(CodePosition position, ParsedExpression object, ParsedStatement content) {
25
-		super(position);
25
+	public ParsedStatementLock(CodePosition position, WhitespaceInfo whitespace, ParsedExpression object, ParsedStatement content) {
26
+		super(position, whitespace);
26 27
 		
27 28
 		this.object = object;
28 29
 		this.content = content;
@@ -32,6 +33,6 @@ public class ParsedStatementLock extends ParsedStatement {
32 33
 	public Statement compile(StatementScope scope) {
33 34
 		Expression object = this.object.compile(new ExpressionScope(scope)).eval();
34 35
 		Statement content = this.content.compile(scope);
35
-		return new LockStatement(position, object, content);
36
+		return result(new LockStatement(position, object, content));
36 37
 	}
37 38
 }

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

@@ -6,10 +6,10 @@
6 6
 
7 7
 package org.openzen.zenscript.parser.statements;
8 8
 
9
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
9 10
 import org.openzen.zenscript.codemodel.statement.EmptyStatement;
10 11
 import org.openzen.zenscript.codemodel.statement.Statement;
11 12
 import org.openzen.zenscript.linker.StatementScope;
12
-import org.openzen.zenscript.parser.statements.ParsedStatement;
13 13
 import org.openzen.zenscript.shared.CodePosition;
14 14
 
15 15
 /**
@@ -17,12 +17,12 @@ import org.openzen.zenscript.shared.CodePosition;
17 17
  * @author Stanneke
18 18
  */
19 19
 public class ParsedStatementNull extends ParsedStatement {
20
-	public ParsedStatementNull(CodePosition position) {
21
-		super(position);
20
+	public ParsedStatementNull(CodePosition position, WhitespaceInfo whitespace) {
21
+		super(position, whitespace);
22 22
 	}
23 23
 
24 24
 	@Override
25 25
 	public Statement compile(StatementScope scope) {
26
-		return new EmptyStatement(position);
26
+		return result(new EmptyStatement(position));
27 27
 	}
28 28
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementReturn.java Целия файл

@@ -1,5 +1,6 @@
1 1
 package org.openzen.zenscript.parser.statements;
2 2
 
3
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
3 4
 import org.openzen.zenscript.codemodel.expression.Expression;
4 5
 import org.openzen.zenscript.codemodel.statement.ReturnStatement;
5 6
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -14,8 +15,8 @@ import org.openzen.zenscript.shared.CompileExceptionCode;
14 15
 public class ParsedStatementReturn extends ParsedStatement {
15 16
 	private final ParsedExpression expression;
16 17
 
17
-	public ParsedStatementReturn(CodePosition position, ParsedExpression expression) {
18
-		super(position);
18
+	public ParsedStatementReturn(CodePosition position, WhitespaceInfo whitespace, ParsedExpression expression) {
19
+		super(position, whitespace);
19 20
 		
20 21
 		this.expression = expression;
21 22
 	}
@@ -38,7 +39,7 @@ public class ParsedStatementReturn extends ParsedStatement {
38 39
 					.compile(new ExpressionScope(scope, scope.getFunctionHeader().returnType))
39 40
 					.eval()
40 41
 					.castImplicit(position, scope, scope.getFunctionHeader().returnType);
41
-			return new ReturnStatement(position, value);
42
+			return result(new ReturnStatement(position, value));
42 43
 		}
43 44
 	}
44 45
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementThrow.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.statements;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
8 9
 import org.openzen.zenscript.codemodel.statement.Statement;
9 10
 import org.openzen.zenscript.codemodel.statement.ThrowStatement;
10 11
 import org.openzen.zenscript.linker.ExpressionScope;
@@ -19,14 +20,14 @@ import org.openzen.zenscript.shared.CodePosition;
19 20
 public class ParsedStatementThrow extends ParsedStatement {
20 21
 	private final ParsedExpression expression;
21 22
 	
22
-	public ParsedStatementThrow(CodePosition position, ParsedExpression expression) {
23
-		super(position);
23
+	public ParsedStatementThrow(CodePosition position, WhitespaceInfo whitespace, ParsedExpression expression) {
24
+		super(position, whitespace);
24 25
 		
25 26
 		this.expression = expression;
26 27
 	}
27 28
 
28 29
 	@Override
29 30
 	public Statement compile(StatementScope scope) {
30
-		return new ThrowStatement(position, expression.compile(new ExpressionScope(scope)).eval());
31
+		return result(new ThrowStatement(position, expression.compile(new ExpressionScope(scope)).eval()));
31 32
 	}
32 33
 }

+ 4
- 2
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementTryCatch.java Целия файл

@@ -7,6 +7,7 @@ package org.openzen.zenscript.parser.statements;
7 7
 
8 8
 import java.util.ArrayList;
9 9
 import java.util.List;
10
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
10 11
 import org.openzen.zenscript.codemodel.expression.Expression;
11 12
 import org.openzen.zenscript.codemodel.statement.CatchClause;
12 13
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -30,12 +31,13 @@ public class ParsedStatementTryCatch extends ParsedStatement {
30 31
 	
31 32
 	public ParsedStatementTryCatch(
32 33
 			CodePosition position,
34
+			WhitespaceInfo whitespace,
33 35
 			String resourceName,
34 36
 			ParsedExpression resourceInitializer,
35 37
 			ParsedStatement statement,
36 38
 			List<ParsedCatchClause> catchClauses,
37 39
 			ParsedStatement finallyClause) {
38
-		super(position);
40
+		super(position, whitespace);
39 41
 		
40 42
 		this.resourceName = resourceName;
41 43
 		this.resourceInitializer = resourceInitializer;
@@ -57,6 +59,6 @@ public class ParsedStatementTryCatch extends ParsedStatement {
57 59
 		if (resourceName != null) {
58 60
 			resource = new VarStatement(position, resourceName, resourceInitializer.type, resourceInitializer, true);
59 61
 		}
60
-		return new TryCatchStatement(position, resource, statement, catches, finallyClause);
62
+		return result(new TryCatchStatement(position, resource, statement, catches, finallyClause));
61 63
 	}
62 64
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementVar.java Целия файл

@@ -6,6 +6,7 @@
6 6
 
7 7
 package org.openzen.zenscript.parser.statements;
8 8
 
9
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
9 10
 import org.openzen.zenscript.codemodel.expression.Expression;
10 11
 import org.openzen.zenscript.codemodel.statement.Statement;
11 12
 import org.openzen.zenscript.codemodel.statement.VarStatement;
@@ -27,8 +28,8 @@ public class ParsedStatementVar extends ParsedStatement {
27 28
 	private final ParsedExpression initializer;
28 29
 	private final boolean isFinal;
29 30
 
30
-	public ParsedStatementVar(CodePosition position, String name, IParsedType type, ParsedExpression initializer, boolean isFinal) {
31
-		super(position);
31
+	public ParsedStatementVar(CodePosition position, WhitespaceInfo whitespace, String name, IParsedType type, ParsedExpression initializer, boolean isFinal) {
32
+		super(position, whitespace);
32 33
 
33 34
 		this.name = name;
34 35
 		this.type = type;
@@ -49,6 +50,6 @@ public class ParsedStatementVar extends ParsedStatement {
49 50
 		}
50 51
 		VarStatement result = new VarStatement(position, name, type, initializer, isFinal);
51 52
 		scope.defineVariable(result);
52
-		return result;
53
+		return result(result);
53 54
 	}
54 55
 }

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementWhile.java Целия файл

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.statements;
7 7
 
8
+import org.openzen.zenscript.codemodel.WhitespaceInfo;
8 9
 import org.openzen.zenscript.codemodel.expression.Expression;
9 10
 import org.openzen.zenscript.codemodel.statement.Statement;
10 11
 import org.openzen.zenscript.codemodel.statement.WhileStatement;
@@ -24,8 +25,8 @@ public class ParsedStatementWhile extends ParsedStatement {
24 25
 	public final ParsedStatement content;
25 26
 	public final String label;
26 27
 	
27
-	public ParsedStatementWhile(CodePosition position, String label, ParsedExpression condition, ParsedStatement content) {
28
-		super(position);
28
+	public ParsedStatementWhile(CodePosition position, WhitespaceInfo whitespace, String label, ParsedExpression condition, ParsedStatement content) {
29
+		super(position, whitespace);
29 30
 		
30 31
 		this.condition = condition;
31 32
 		this.content = content;
@@ -42,6 +43,6 @@ public class ParsedStatementWhile extends ParsedStatement {
42 43
 		WhileStatement result = new WhileStatement(position, label, condition);
43 44
 		LoopScope innerScope = new LoopScope(result, scope);
44 45
 		result.content = this.content.compile(innerScope);
45
-		return result;
46
+		return result(result);
46 47
 	}
47 48
 }

+ 26
- 0
Shared/src/main/java/org/openzen/zenscript/shared/StringUtils.java Целия файл

@@ -7,8 +7,10 @@ package org.openzen.zenscript.shared;
7 7
 
8 8
 import java.io.IOException;
9 9
 import java.io.InputStream;
10
+import java.util.ArrayList;
10 11
 import java.util.Collection;
11 12
 import java.util.HashMap;
13
+import java.util.List;
12 14
 import java.util.Map;
13 15
 import java.util.Properties;
14 16
 import java.util.logging.Level;
@@ -45,6 +47,30 @@ public class StringUtils {
45 47
 			NAMED_CHARACTER_ENTITIES.put(entity.stringValue, entity);
46 48
 		}
47 49
 	}
50
+
51
+	/**
52
+	 * Splits a string in parts, given a specified delimiter.
53
+	 *
54
+	 * @param value string to be split
55
+	 * @param delimiter delimiter
56
+	 * @return split string
57
+	 */
58
+	public static List<String> split(String value, char delimiter)
59
+	{
60
+		if (value == null)
61
+			return null;
62
+
63
+		List<String> result = new ArrayList<>();
64
+		int start = 0;
65
+		for (int i = 0; i < value.length(); i++) {
66
+			if (value.charAt(i) == delimiter) {
67
+				result.add(value.substring(start, i));
68
+				start = i + 1;
69
+			}
70
+		}
71
+		result.add(value.substring(start));
72
+		return result;
73
+	}
48 74
 	
49 75
 	/**
50 76
 	 * Left pads (prefixes) a string with characters until it reaches the given string

+ 3
- 0
Shared/src/main/java/org/openzen/zenscript/shared/TagDictionary.java Целия файл

@@ -17,6 +17,9 @@ public class TagDictionary {
17 17
     private Map<Class<?>, Object> tags = Collections.EMPTY_MAP;
18 18
 
19 19
     public <T> void put(Class<T> cls, T tag) {
20
+		if (tag == null)
21
+			return;
22
+		
20 23
         if (tags == Collections.EMPTY_MAP) {
21 24
             tags = Collections.singletonMap(cls, tag);
22 25
         } else if (tags.size() == 1) {

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