Browse Source

- Moved token handling out of the code editor

- Fixed some bugs in the code editor
Stan Hebben 6 years ago
parent
commit
c05bc0d7b1

+ 61
- 236
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java View File

6
 package org.openzen.zenscript.ide.ui.view.editor;
6
 package org.openzen.zenscript.ide.ui.view.editor;
7
 
7
 
8
 import java.io.IOException;
8
 import java.io.IOException;
9
-import java.util.ArrayList;
10
-import java.util.Iterator;
11
-import java.util.List;
12
 import java.util.Timer;
9
 import java.util.Timer;
13
 import java.util.TimerTask;
10
 import java.util.TimerTask;
14
 import org.openzen.drawablegui.DCanvas;
11
 import org.openzen.drawablegui.DCanvas;
24
 import org.openzen.drawablegui.DMouseEvent;
21
 import org.openzen.drawablegui.DMouseEvent;
25
 import org.openzen.drawablegui.DRectangle;
22
 import org.openzen.drawablegui.DRectangle;
26
 import org.openzen.drawablegui.DTransform2D;
23
 import org.openzen.drawablegui.DTransform2D;
24
+import org.openzen.drawablegui.listeners.ListenerHandle;
27
 import org.openzen.drawablegui.live.LiveObject;
25
 import org.openzen.drawablegui.live.LiveObject;
28
 import org.openzen.drawablegui.live.SimpleLiveObject;
26
 import org.openzen.drawablegui.live.SimpleLiveObject;
29
 import org.openzen.zenscript.ide.host.IDESourceFile;
27
 import org.openzen.zenscript.ide.host.IDESourceFile;
43
 	private final LiveObject<DDimensionPreferences> dimensionPreferences = new SimpleLiveObject<>(new DDimensionPreferences(0, 0));
41
 	private final LiveObject<DDimensionPreferences> dimensionPreferences = new SimpleLiveObject<>(new DDimensionPreferences(0, 0));
44
 	private final String tab = "    ";
42
 	private final String tab = "    ";
45
 	private final IDESourceFile sourceFile;
43
 	private final IDESourceFile sourceFile;
44
+	private final TokenModel tokens;
45
+	private final ListenerHandle<TokenModel.Listener> tokenListener;
46
 	
46
 	
47
 	private DRectangle bounds;
47
 	private DRectangle bounds;
48
 	private DDrawingContext context;
48
 	private DDrawingContext context;
50
 	private int textLineHeight;
50
 	private int textLineHeight;
51
 	private int fullLineHeight;
51
 	private int fullLineHeight;
52
 	private int selectionLineHeight;
52
 	private int selectionLineHeight;
53
-	private final List<Line> lines = new ArrayList<>();
54
 	
53
 	
55
 	private int lineBarWidth;
54
 	private int lineBarWidth;
56
 	private CursorPosition cursorStart = null;
55
 	private CursorPosition cursorStart = null;
65
 	
64
 	
66
 	public SourceEditor(IDESourceFile sourceFile) {
65
 	public SourceEditor(IDESourceFile sourceFile) {
67
 		this.sourceFile = sourceFile;
66
 		this.sourceFile = sourceFile;
67
+		tokens = new TokenModel(sourceFile.getName(), tab.length());
68
+		tokenListener = tokens.addListener(new TokenListener());
68
 		
69
 		
69
 		blink.scheduleAtFixedRate(new TimerTask() {
70
 		blink.scheduleAtFixedRate(new TimerTask() {
70
 			@Override
71
 			@Override
74
 		}, 300, 300);
75
 		}, 300, 300);
75
 		
76
 		
76
 		try {
77
 		try {
77
-			parse();
78
+			TokenParser<ZSToken, ZSTokenType> parser = ZSTokenParser.createRaw(sourceFile.getName(), new ReaderCharReader(sourceFile.read()), tab.length());
79
+			tokens.set(parser);
78
 		} catch (IOException ex) {
80
 		} catch (IOException ex) {
79
 			ex.printStackTrace();
81
 			ex.printStackTrace();
80
 		}
82
 		}
88
 		fullLineHeight = textLineHeight + fontMetrics.getLeading() + style.extraLineSpacing;
90
 		fullLineHeight = textLineHeight + fontMetrics.getLeading() + style.extraLineSpacing;
89
 		selectionLineHeight = textLineHeight + style.selectionPaddingTop + style.selectionPaddingBottom;
91
 		selectionLineHeight = textLineHeight + style.selectionPaddingTop + style.selectionPaddingBottom;
90
 		
92
 		
91
-		dimensionPreferences.setValue(new DDimensionPreferences(0, fullLineHeight * lines.size()));
93
+		dimensionPreferences.setValue(new DDimensionPreferences(0, fullLineHeight * tokens.getLineCount()));
92
 	}
94
 	}
93
 
95
 
94
 	@Override
96
 	@Override
111
 		DIRectangle canvasBounds = canvas.getBounds();
113
 		DIRectangle canvasBounds = canvas.getBounds();
112
 		canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 0xFFFFFFFF);
114
 		canvas.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height, 0xFFFFFFFF);
113
 		
115
 		
114
-		lineBarWidth = Math.max(50, fontMetrics.getWidth(Integer.toString(lines.size()))) + 5;
116
+		lineBarWidth = Math.max(50, fontMetrics.getWidth(Integer.toString(tokens.getLineCount()))) + 5;
115
 		canvas.fillRectangle(bounds.x, bounds.y, lineBarWidth, bounds.height, 0xFFE9E8E2);
117
 		canvas.fillRectangle(bounds.x, bounds.y, lineBarWidth, bounds.height, 0xFFE9E8E2);
116
 		canvas.strokePath(tracer -> {
118
 		canvas.strokePath(tracer -> {
117
 			tracer.moveTo(bounds.x + lineBarWidth, bounds.y);
119
 			tracer.moveTo(bounds.x + lineBarWidth, bounds.y);
148
 		
150
 		
149
 		int y = bounds.y + style.selectionPaddingTop;
151
 		int y = bounds.y + style.selectionPaddingTop;
150
 		int lineIndex = 1;
152
 		int lineIndex = 1;
151
-		for (Line line : lines) {
153
+		for (TokenLine line : tokens.getLines()) {
152
 			if (y + textLineHeight  >= canvasBounds.y && y < canvasBounds.y + canvasBounds.height) {
154
 			if (y + textLineHeight  >= canvasBounds.y && y < canvasBounds.y + canvasBounds.height) {
153
 				String lineNumber = Integer.toString(lineIndex);
155
 				String lineNumber = Integer.toString(lineIndex);
154
 				int lineNumberX = x - 15 - (int)canvas.measureTextLength(font, lineNumber);
156
 				int lineNumberX = x - 15 - (int)canvas.measureTextLength(font, lineNumber);
155
 				canvas.drawText(font, 0xFFA0A0A0, lineNumberX, y + fontMetrics.getAscent(), lineNumber);
157
 				canvas.drawText(font, 0xFFA0A0A0, lineNumberX, y + fontMetrics.getAscent(), lineNumber);
156
 
158
 
157
 				int lineX = x;
159
 				int lineX = x;
158
-				for (ZSToken token : line.tokens) {
160
+				for (ZSToken token : line.getTokens()) {
159
 					String content = getDisplayContent(token);
161
 					String content = getDisplayContent(token);
160
 					canvas.drawText(font, TokenClass.get(token.type).color, lineX, y + fontMetrics.getAscent(), content);
162
 					canvas.drawText(font, TokenClass.get(token.type).color, lineX, y + fontMetrics.getAscent(), content);
161
 					lineX += canvas.measureTextLength(font, content);
163
 					lineX += canvas.measureTextLength(font, content);
248
 					int line = cursorEnd.line - 1;
250
 					int line = cursorEnd.line - 1;
249
 					CursorPosition position = new CursorPosition(
251
 					CursorPosition position = new CursorPosition(
250
 							line,
252
 							line,
251
-							Math.min(lines.get(line).length, cursorEnd.offset));
253
+							Math.min(tokens.getLineLength(line), cursorEnd.offset));
252
 					setCursor(shift ? cursorStart : position, position);
254
 					setCursor(shift ? cursorStart : position, position);
253
 				}
255
 				}
254
 				break;
256
 				break;
255
 			case DOWN:
257
 			case DOWN:
256
-				if (cursorEnd == null || cursorEnd.line >= lines.size() - 1)
258
+				if (cursorEnd == null || cursorEnd.line >= tokens.getLineCount() - 1)
257
 					return;
259
 					return;
258
 				
260
 				
259
 				{
261
 				{
260
 					int line = cursorEnd.line + 1;
262
 					int line = cursorEnd.line + 1;
261
 					CursorPosition position = new CursorPosition(
263
 					CursorPosition position = new CursorPosition(
262
 							line,
264
 							line,
263
-							Math.min(lines.get(line).length, cursorEnd.offset));
265
+							Math.min(tokens.getLineLength(line), cursorEnd.offset));
264
 					setCursor(shift ? cursorStart : position, position);
266
 					setCursor(shift ? cursorStart : position, position);
265
 				}
267
 				}
266
 				break;
268
 				break;
272
 					CursorPosition position;
274
 					CursorPosition position;
273
 					if (cursorEnd.offset == 0) {
275
 					if (cursorEnd.offset == 0) {
274
 						int line = cursorEnd.line - 1;
276
 						int line = cursorEnd.line - 1;
275
-						position = new CursorPosition(line, lines.get(line).length);
277
+						position = new CursorPosition(line, tokens.getLineLength(line));
276
 					} else {
278
 					} else {
277
 						position = new CursorPosition(cursorEnd.line, cursorEnd.offset - 1);
279
 						position = new CursorPosition(cursorEnd.line, cursorEnd.offset - 1);
278
 					}
280
 					}
280
 				}
282
 				}
281
 				break;
283
 				break;
282
 			case RIGHT:
284
 			case RIGHT:
283
-				if (cursorEnd == null || (cursorEnd.offset == lines.get(cursorEnd.line).length && cursorEnd.line >= lines.size() - 1))
285
+				if (cursorEnd == null || (cursorEnd.offset == tokens.getLineLength(cursorEnd.line) && cursorEnd.line >= tokens.getLineCount() - 1))
284
 					return;
286
 					return;
285
 				
287
 				
286
 				{
288
 				{
287
 					CursorPosition position;
289
 					CursorPosition position;
288
-					if (cursorEnd.offset == lines.get(cursorEnd.line).length) {
290
+					if (cursorEnd.offset == tokens.getLineLength(cursorEnd.line)) {
289
 						position = new CursorPosition(cursorEnd.line + 1, 0);
291
 						position = new CursorPosition(cursorEnd.line + 1, 0);
290
 					} else {
292
 					} else {
291
 						position = new CursorPosition(cursorEnd.line, cursorEnd.offset + 1);
293
 						position = new CursorPosition(cursorEnd.line, cursorEnd.offset + 1);
303
 				newline();
305
 				newline();
304
 				break;
306
 				break;
305
 			case TAB:
307
 			case TAB:
306
-				type(tab);
308
+				type("\t");
307
 				break;
309
 				break;
308
 			default:
310
 			default:
309
 				if (e.character == DKeyEvent.CHAR_UNDEFINED)
311
 				if (e.character == DKeyEvent.CHAR_UNDEFINED)
326
 	}
328
 	}
327
 	
329
 	
328
 	private void save() {
330
 	private void save() {
329
-		String content = contentToString();
331
+		String content = tokens.toString();
330
 		sourceFile.update(content);
332
 		sourceFile.update(content);
331
 	}
333
 	}
332
 	
334
 	
333
-	private String contentToString() {
334
-		StringBuilder result = new StringBuilder();
335
-		for (int i = 0; i < lines.size(); i++) {
336
-			if (i > 0)
337
-				result.append("\n");
338
-			
339
-			Line line = lines.get(i);
340
-			for (ZSToken token : line.tokens) {
341
-				result.append(token.content);
342
-			}
343
-		}
344
-		return result.toString();
345
-	}
346
-	
347
 	private void delete() {
335
 	private void delete() {
348
-		Line line = lines.get(cursorEnd.line);
349
-		if (cursorEnd.offset == line.length) {
336
+		TokenLine line = tokens.getLine(cursorEnd.line);
337
+		if (cursorEnd.offset == line.length()) {
350
 			// merge 2 lines
338
 			// merge 2 lines
351
-			if (cursorEnd.line == lines.size() - 1)
339
+			if (cursorEnd.line == tokens.getLineCount() - 1)
352
 				return;
340
 				return;
353
 			
341
 			
354
-			line.merge(cursorEnd.line, lines.get(cursorEnd.line + 1));
355
-			lines.remove(cursorEnd.line + 1);
356
-			onLinesUpdated();
342
+			tokens.deleteNewline(cursorEnd.line);
357
 			return;
343
 			return;
358
 		}
344
 		}
359
 		
345
 		
360
-		line.delete(cursorEnd.line, cursorEnd.offset);
346
+		tokens.deleteCharacter(cursorEnd.line, cursorEnd.offset);
361
 		repaintLine(cursorEnd.line);
347
 		repaintLine(cursorEnd.line);
362
 	}
348
 	}
363
 	
349
 	
366
 			if (cursorEnd.line == 0)
352
 			if (cursorEnd.line == 0)
367
 				return;
353
 				return;
368
 			
354
 			
369
-			int length = lines.get(cursorEnd.line - 1).length;
370
-			lines.get(cursorEnd.line - 1).merge(cursorEnd.line - 1, lines.get(cursorEnd.line));
371
-			lines.remove(cursorEnd.line);
372
-			onLinesUpdated();
355
+			int length = tokens.getLineLength(cursorEnd.line - 1);
356
+			tokens.deleteNewline(cursorEnd.line - 1);
373
 			
357
 			
374
 			CursorPosition position = new CursorPosition(cursorEnd.line - 1, length);
358
 			CursorPosition position = new CursorPosition(cursorEnd.line - 1, length);
375
 			setCursor(position, position);
359
 			setCursor(position, position);
376
 			return;
360
 			return;
377
 		}
361
 		}
378
 		
362
 		
379
-		lines.get(cursorEnd.line).delete(cursorEnd.line, cursorEnd.offset - 1);
363
+		tokens.deleteCharacter(cursorEnd.line, cursorEnd.offset - 1);
380
 		CursorPosition position = new CursorPosition(cursorEnd.line, cursorEnd.offset - 1);
364
 		CursorPosition position = new CursorPosition(cursorEnd.line, cursorEnd.offset - 1);
381
 		setCursor(position, position);
365
 		setCursor(position, position);
382
-		repaintLine(cursorEnd.line);
383
 	}
366
 	}
384
 	
367
 	
385
 	private void type(String value) {
368
 	private void type(String value) {
386
-		lines.get(cursorEnd.line).insert(cursorEnd.line, cursorEnd.offset, value);
369
+		tokens.insert(cursorEnd.line, cursorEnd.offset, value);
387
 		CursorPosition position = new CursorPosition(cursorEnd.line, cursorEnd.offset + value.length());
370
 		CursorPosition position = new CursorPosition(cursorEnd.line, cursorEnd.offset + value.length());
388
 		setCursor(position, position);
371
 		setCursor(position, position);
389
-		repaintLine(cursorEnd.line);
390
 	}
372
 	}
391
 	
373
 	
392
 	private void newline() {
374
 	private void newline() {
393
-		lines.get(cursorEnd.line).split(cursorEnd.line, cursorEnd.offset);
394
-		onLinesUpdated();
395
-		
396
-		CursorPosition position = new CursorPosition(cursorEnd.line + 1, 0);
375
+		String indent = tokens.getLine(cursorEnd.line).getIndent();
376
+		tokens.insert(cursorEnd.line, cursorEnd.offset, "\n" + indent);
377
+		CursorPosition position = new CursorPosition(cursorEnd.line + 1, indent.length());
397
 		setCursor(position, position);
378
 		setCursor(position, position);
398
 	}
379
 	}
399
 	
380
 	
400
 	private TokenPosition getTokenAt(CursorPosition position) {
381
 	private TokenPosition getTokenAt(CursorPosition position) {
401
-		Line line = lines.get(position.line);
382
+		TokenLine line = tokens.getLine(position.line);
402
 		int offset = 0;
383
 		int offset = 0;
403
-		for (ZSToken token : line.tokens) {
384
+		for (ZSToken token : line.getTokens()) {
404
 			if (offset + token.content.length() > position.offset)
385
 			if (offset + token.content.length() > position.offset)
405
 				return new TokenPosition(token, position.offset - offset);
386
 				return new TokenPosition(token, position.offset - offset);
406
 			offset += token.content.length();
387
 			offset += token.content.length();
407
 		}
388
 		}
408
 		
389
 		
409
-		return new TokenPosition(line.tokens.get(line.tokens.size() - 1), position.offset - offset);
390
+		return new TokenPosition(line.getLastToken(), position.offset - offset);
410
 	}
391
 	}
411
 	
392
 	
412
 	private class TokenPosition {
393
 	private class TokenPosition {
433
 	}
414
 	}
434
 	
415
 	
435
 	private void repaintLine(int line) {
416
 	private void repaintLine(int line) {
417
+		if (bounds == null)
418
+			return;
419
+		
436
 		context.repaint(bounds.x, lineToY(line), bounds.width, selectionLineHeight);
420
 		context.repaint(bounds.x, lineToY(line), bounds.width, selectionLineHeight);
437
 	}
421
 	}
438
 	
422
 	
455
 		
439
 		
456
 		if (line < 0)
440
 		if (line < 0)
457
 			line = 0;
441
 			line = 0;
458
-		if (line >= lines.size())
459
-			line = lines.size() - 1;
442
+		if (line >= tokens.getLineCount())
443
+			line = tokens.getLineCount() - 1;
460
 		
444
 		
461
 		return new CursorPosition(line, offset);
445
 		return new CursorPosition(line, offset);
462
 	}
446
 	}
463
 	
447
 	
464
 	private int xToOffset(int lineIndex, int x) {
448
 	private int xToOffset(int lineIndex, int x) {
465
-		if (lineIndex < 0 || lineIndex >= lines.size())
449
+		if (lineIndex < 0 || lineIndex >= tokens.getLineCount())
466
 			return 0;
450
 			return 0;
467
 		
451
 		
468
-		Line line = lines.get(lineIndex);
452
+		TokenLine line = tokens.getLine(lineIndex);
469
 		int lineX = bounds.x + lineBarWidth + 10;
453
 		int lineX = bounds.x + lineBarWidth + 10;
470
 		int offset = 0;
454
 		int offset = 0;
471
-		for (ZSToken token : line.tokens) {
455
+		for (ZSToken token : line.getTokens()) {
472
 			String content = getDisplayContent(token);
456
 			String content = getDisplayContent(token);
473
 			int tokenWidth = fontMetrics.getWidth(content);
457
 			int tokenWidth = fontMetrics.getWidth(content);
474
 			if (lineX + tokenWidth > x) {
458
 			if (lineX + tokenWidth > x) {
490
 	
474
 	
491
 	private int getStringIndexForPixels(String str, int pixels) {
475
 	private int getStringIndexForPixels(String str, int pixels) {
492
 		int previousX = 0;
476
 		int previousX = 0;
493
-		for (int i = 1; i < str.length(); i++) {
477
+		for (int i = 1; i <= str.length(); i++) {
494
 			int currentX = fontMetrics.getWidth(str, 0, i);
478
 			int currentX = fontMetrics.getWidth(str, 0, i);
495
 			if (currentX >= pixels)
479
 			if (currentX >= pixels)
496
 				return (pixels - previousX < currentX - pixels) ? i - 1 : i;
480
 				return (pixels - previousX < currentX - pixels) ? i - 1 : i;
510
 	}
494
 	}
511
 	
495
 	
512
 	private int offsetToX(int line, int offset) {
496
 	private int offsetToX(int line, int offset) {
513
-		if (line >= lines.size())
497
+		if (line >= tokens.getLineCount())
514
 			return 0;
498
 			return 0;
515
 		
499
 		
516
 		int tokensOffset = 0;
500
 		int tokensOffset = 0;
517
 		int x = bounds.x + lineBarWidth + 10;
501
 		int x = bounds.x + lineBarWidth + 10;
518
-		Line lineData = lines.get(line);
519
-		for (ZSToken token : lineData.tokens) {
502
+		TokenLine lineData = tokens.getLine(line);
503
+		for (ZSToken token : lineData.getTokens()) {
520
 			String content = getDisplayContent(token);
504
 			String content = getDisplayContent(token);
521
 			if (tokensOffset + token.content.length() >= offset) {
505
 			if (tokensOffset + token.content.length() >= offset) {
522
 				if (token.type == ZSTokenType.T_WHITESPACE_TAB)
506
 				if (token.type == ZSTokenType.T_WHITESPACE_TAB)
535
 		return token.type == ZSTokenType.T_WHITESPACE_TAB ? tab : token.content;
519
 		return token.type == ZSTokenType.T_WHITESPACE_TAB ? tab : token.content;
536
 	}
520
 	}
537
 	
521
 	
538
-	private void parse() throws IOException {
539
-		lines.clear();
540
-		lines.add(new Line());
541
-		
542
-		TokenParser<ZSToken, ZSTokenType> parser = ZSTokenParser.createRaw(sourceFile.getName(), new ReaderCharReader(sourceFile.read()), tab.length());
543
-		insertTokens(0, 0, parser);
544
-	}
545
-	
546
 	private void onLinesUpdated() {
522
 	private void onLinesUpdated() {
547
-		dimensionPreferences.setValue(new DDimensionPreferences(0, fullLineHeight * lines.size()));
523
+		dimensionPreferences.setValue(new DDimensionPreferences(0, fullLineHeight * tokens.getLineCount()));
548
 		
524
 		
549
 		if (bounds != null)
525
 		if (bounds != null)
550
 			context.repaint(bounds.x, bounds.y, bounds.width, bounds.height);
526
 			context.repaint(bounds.x, bounds.y, bounds.width, bounds.height);
551
 	}
527
 	}
552
 	
528
 	
553
-	public class Line {
554
-		public final List<ZSToken> tokens = new ArrayList<>();
555
-		private int length;
556
-		
557
-		private void calculateLength() {
558
-			length = 0;
559
-			for (ZSToken token : tokens)
560
-				length += token.content.length();
561
-		}
562
-		
563
-		public void merge(int lineIndex, Line other) {
564
-			if (tokens.isEmpty()) {
565
-				tokens.addAll(other.tokens);
566
-				length = other.length;
567
-				return;
568
-			}
569
-			
570
-			int fromToken = tokens.size() - 1;
571
-			int toToken = other.tokens.size() > 0 ? fromToken + 2 : fromToken + 1;
572
-			tokens.addAll(other.tokens);
573
-			length += other.length;
574
-			reparse(lineIndex, fromToken, lineIndex, toToken);
575
-		}
576
-		
577
-		public Line split(int lineIndex, int offset) {
578
-			if (offset < 0)
579
-				throw new IllegalArgumentException("offset must be >= 0");
580
-			
581
-			int tokenOffset = 0;
582
-			for (int i = 0; i < tokens.size(); i++) {
583
-				ZSToken token = tokens.get(i);
584
-				if (tokenOffset + token.content.length() > offset) {
585
-					ZSToken broken = token;
586
-					Line newLine = new Line();
587
-					if (offset - tokenOffset != token.content.length() && offset - tokenOffset != 0) {
588
-						ZSToken.Pair split = token.split(offset - tokenOffset);
589
-						broken = split.first;
590
-						newLine.tokens.add(split.second);
591
-					}
592
-					
593
-					tokens.set(i, broken);
594
-					for (int j = i + 1; j < tokens.size(); j++)
595
-						newLine.tokens.add(tokens.get(j));
596
-					for (int j = tokens.size() - 1; j > i; j--)
597
-						tokens.remove(j);
598
-					
599
-					lines.add(lineIndex + 1, newLine);
600
-					reparse(lineIndex, i, lineIndex + 1, 1);
601
-					return newLine;
602
-				}
603
-				tokenOffset += token.content.length();
604
-			}
605
-			
606
-			Line result = new Line();
607
-			lines.add(result);
608
-			return result;
609
-		}
610
-		
611
-		public void delete(int lineIndex, int offset) {
612
-			int tokenOffset = 0;
613
-			for (int i = 0; i < tokens.size(); i++) {
614
-				ZSToken token = tokens.get(i);
615
-				if (tokenOffset + token.content.length() > offset) {
616
-					if (token.content.length() == 1) {
617
-						tokens.remove(i);
618
-					} else {
619
-						token = token.delete(offset - tokenOffset, 1);
620
-						tokens.set(i, token);
621
-					}
622
-					length--;
623
-					
624
-					reparse(lineIndex, i, lineIndex, i + 1);
625
-					return;
626
-				}
627
-				tokenOffset += token.content.length();
628
-			}
629
-		}
630
-		
631
-		public void insert(int lineIndex, int offset, String value) {
632
-			int tokenOffset = 0;
633
-			if (tokens.isEmpty()) {
634
-				tokens.add(new ZSToken(ZSTokenType.INVALID, value));
635
-				reparse(lineIndex, 0, lineIndex, 1);
636
-				return;
637
-			}
638
-			
639
-			for (int i = 0; i < tokens.size(); i++) {
640
-				ZSToken token = tokens.get(i);
641
-				if (tokenOffset + token.content.length() > offset) {
642
-					token = token.insert(offset - tokenOffset, value);
643
-					tokens.set(i, token);
644
-					length += value.length();
645
-					reparse(lineIndex, i, lineIndex, i + 1);
646
-					return;
647
-				}
648
-				tokenOffset += token.content.length();
649
-			}
650
-			
651
-			ZSToken token = tokens.get(tokens.size() - 1);
652
-			token = new ZSToken(token.type, token.content + value);
653
-			tokens.set(tokens.size() - 1, token);
654
-			length += value.length();
655
-			reparse(lineIndex, tokens.size() - 1, lineIndex, tokens.size());
656
-		}
657
-	}
658
-	
659
-	private void reparse(int fromLine, int fromToken, int toLine, int toToken) {
660
-		TokenReparser reparser = new TokenReparser(sourceFile.getName(), lines, fromLine, fromToken, toLine, toToken, tab.length());
661
-		List<ZSToken> tokens = reparser.reparse();
662
-		replaceTokens(fromLine, fromToken, reparser.getLine(), reparser.getToken(), tokens);
663
-	}
664
-	
665
-	private void replaceTokens(int fromLine, int fromToken, int toLine, int toToken, List<ZSToken> tokens) {
666
-		removeTokens(fromLine, fromToken, toLine, toToken);
667
-		insertTokens(fromLine, fromToken, tokens.iterator());
668
-	}
669
-	
670
-	private void removeTokens(int fromLine, int fromToken, int toLine, int toToken) {
671
-		if (toLine > fromLine) {
672
-			Line fromLineObject = lines.get(fromLine);
673
-			for (int i = fromLineObject.tokens.size() - 1; i >= fromToken; i--)
674
-				fromLineObject.tokens.remove(i);
675
-			
676
-			Line toLineObject = lines.get(fromLine);
677
-			for (int i = toToken - 1; i >= 0; i--)
678
-				toLineObject.tokens.remove(i);
679
-			
680
-			fromLineObject.merge(fromLine, lines.remove(toLine));
681
-			for (int i = toLine - 1; i > fromLine; i--)
682
-				lines.remove(i);
683
-			
529
+	private class TokenListener implements TokenModel.Listener {
530
+
531
+		@Override
532
+		public void onLineInserted(int index) {
684
 			onLinesUpdated();
533
 			onLinesUpdated();
685
-		} else {
686
-			Line line = lines.get(fromLine);
687
-			for (int i = toToken - 1; i >= fromToken; i--)
688
-				line.tokens.remove(i);
689
 		}
534
 		}
690
-	}
691
-	
692
-	private void insertTokens(int line, int tokenIndex, Iterator<ZSToken> tokens) {
693
-		boolean linesUpdated = false;
694
-		Line currentLine = lines.get(line);
695
-		while (tokens.hasNext()) {
696
-			ZSToken token = tokens.next();
697
-			if (token.type == ZSTokenType.T_WHITESPACE_NEWLINE) {
698
-				currentLine.calculateLength();
699
-				
700
-				Line newLine = new Line();
701
-				if (tokenIndex < currentLine.tokens.size()) {
702
-					for (int i = tokenIndex; i < currentLine.tokens.size(); i++) {
703
-						newLine.tokens.add(currentLine.tokens.remove(tokenIndex));
704
-					}
705
-				}
706
-				currentLine = newLine;
707
-				tokenIndex = 0;
708
-				lines.add(++line, currentLine);
709
-				linesUpdated = true;
710
-			} else if (token.type != ZSTokenType.T_WHITESPACE_CARRIAGE_RETURN) {
711
-				currentLine.tokens.add(tokenIndex++, token);
712
-			}
535
+
536
+		@Override
537
+		public void onLineChanged(int index) {
538
+			repaintLine(index);
713
 		}
539
 		}
714
-		
715
-		currentLine.calculateLength();
716
-		
717
-		if (linesUpdated) {
540
+
541
+		@Override
542
+		public void onLineDeleted(int index) {
718
 			onLinesUpdated();
543
 			onLinesUpdated();
719
-		} else {
720
-			// Could be further optimized to only repaint the modified characters
721
-			repaintLine(line);
722
 		}
544
 		}
723
 	}
545
 	}
724
 	
546
 	
740
 		
562
 		
741
 		public static TokenClass get(ZSTokenType type) {
563
 		public static TokenClass get(ZSTokenType type) {
742
 			switch (type) {
564
 			switch (type) {
565
+				case T_COMMENT_SCRIPT:
566
+				case T_COMMENT_SINGLELINE:
567
+				case T_COMMENT_MULTILINE:
743
 				case T_WHITESPACE_CARRIAGE_RETURN:
568
 				case T_WHITESPACE_CARRIAGE_RETURN:
744
 				case T_WHITESPACE_NEWLINE:
569
 				case T_WHITESPACE_NEWLINE:
745
 				case T_WHITESPACE_SPACE:
570
 				case T_WHITESPACE_SPACE:

+ 89
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenLine.java View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.view.editor;
7
+
8
+import java.util.ArrayList;
9
+import java.util.Collections;
10
+import java.util.List;
11
+import org.openzen.zenscript.lexer.ZSToken;
12
+import org.openzen.zenscript.lexer.ZSTokenType;
13
+
14
+/**
15
+ *
16
+ * @author Hoofdgebruiker
17
+ */
18
+public final class TokenLine {
19
+	private final List<ZSToken> tokens = new ArrayList<>();
20
+	private int length = 0;
21
+	
22
+	public List<ZSToken> getTokens() {
23
+		return Collections.unmodifiableList(tokens);
24
+	}
25
+	
26
+	public boolean isEmpty() {
27
+		return tokens.isEmpty();
28
+	}
29
+	
30
+	public int getTokenCount() {
31
+		return tokens.size();
32
+	}
33
+
34
+	public int length() {
35
+		return length;
36
+	}
37
+	
38
+	public ZSToken getToken(int index) {
39
+		return tokens.get(index);
40
+	}
41
+	
42
+	public ZSToken getLastToken() {
43
+		return tokens.get(tokens.size() - 1);
44
+	}
45
+	
46
+	public String getIndent() {
47
+		StringBuilder indent = new StringBuilder();
48
+		for (int i = 0; i < tokens.size(); i++) {
49
+			ZSToken token = tokens.get(i);
50
+			if (token.type != ZSTokenType.T_WHITESPACE_SPACE && token.type != ZSTokenType.T_WHITESPACE_TAB)
51
+				break;
52
+			
53
+			indent.append(token.content);
54
+		}
55
+		return indent.toString();
56
+	}
57
+
58
+	public void add(ZSToken token) {
59
+		tokens.add(token);
60
+		length += token.content.length();
61
+	}
62
+
63
+	public void addAll(Iterable<ZSToken> tokens) {
64
+		for (ZSToken token : tokens) {
65
+			add(token);
66
+		}
67
+	}
68
+
69
+	public void insert(int index, ZSToken token) {
70
+		tokens.add(index, token);
71
+		length += token.content.length();
72
+	}
73
+
74
+	public void replace(int index, ZSToken token) {
75
+		ZSToken old = tokens.set(index, token);
76
+		length += token.content.length() - old.content.length();
77
+	}
78
+
79
+	public ZSToken remove(int index) {
80
+		ZSToken result = tokens.remove(index);
81
+		length -= result.content.length();
82
+		return result;
83
+	}
84
+	
85
+	public void removeRange(int from, int to) {
86
+		for (int i = to - 1; i >= from; i--)
87
+			remove(i);
88
+	}
89
+}

+ 241
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.ide.ui.view.editor;
7
+
8
+import java.util.ArrayList;
9
+import java.util.Collections;
10
+import java.util.HashSet;
11
+import java.util.Iterator;
12
+import java.util.List;
13
+import java.util.Set;
14
+import org.openzen.drawablegui.listeners.ListenerHandle;
15
+import org.openzen.drawablegui.listeners.ListenerList;
16
+import org.openzen.zenscript.lexer.ZSToken;
17
+import org.openzen.zenscript.lexer.ZSTokenType;
18
+
19
+/**
20
+ *
21
+ * @author Hoofdgebruiker
22
+ */
23
+public class TokenModel {
24
+	private final ListenerList<Listener> listeners = new ListenerList<>();
25
+	
26
+	private final String filename;
27
+	private final int spacesPerTab;
28
+	private final List<TokenLine> lines = new ArrayList<>();
29
+	
30
+	public TokenModel(String filename, int spacesPerTab) {
31
+		this.filename = filename;
32
+		this.spacesPerTab = spacesPerTab;
33
+	}
34
+	
35
+	public ListenerHandle<Listener> addListener(Listener listener) {
36
+		return listeners.add(listener);
37
+	}
38
+	
39
+	public int getLineCount() {
40
+		return lines.size();
41
+	}
42
+	
43
+	public TokenLine getLine(int line) {
44
+		return lines.get(line);
45
+	}
46
+	
47
+	public List<TokenLine> getLines() {
48
+		return Collections.unmodifiableList(lines);
49
+	}
50
+	
51
+	public int getLineLength(int line) {
52
+		return lines.get(line).length();
53
+	}
54
+	
55
+	public void set(Iterator<ZSToken> tokens) {
56
+		lines.clear();
57
+		lines.add(new TokenLine());
58
+		
59
+		insertTokens(0, 0, tokens);
60
+	}
61
+	
62
+	public void deleteNewline(int lineIndex) {
63
+		TokenLine line = getLine(lineIndex);
64
+		merge(line, lineIndex, getLine(lineIndex + 1));
65
+		lines.remove(lineIndex + 1);
66
+		
67
+		listeners.accept(listener -> listener.onLineDeleted(lineIndex + 1));
68
+	}
69
+	
70
+	public void deleteCharacter(int lineIndex, int offset) {
71
+		TokenLine line = getLine(lineIndex);
72
+		int tokenOffset = 0;
73
+		for (int i = 0; i < line.getTokenCount(); i++) {
74
+			ZSToken token = line.getToken(i);
75
+			if (tokenOffset + token.content.length() > offset) {
76
+				if (token.content.length() == 1) {
77
+					line.remove(i);
78
+					i--; // make sure previous token is reparsed too
79
+				} else {
80
+					token = token.delete(offset - tokenOffset, 1);
81
+					line.replace(i, token);
82
+				}
83
+
84
+				reparse(lineIndex, i, lineIndex, i + 1);
85
+				return;
86
+			}
87
+			tokenOffset += token.content.length();
88
+		}
89
+	}
90
+	
91
+	public void insert(int lineIndex, int offset, String value) {
92
+		TokenLine line = lines.get(lineIndex);
93
+		int tokenOffset = 0;
94
+		if (line.isEmpty()) {
95
+			line.add(new ZSToken(ZSTokenType.INVALID, value));
96
+			reparse(lineIndex, 0, lineIndex, 1);
97
+			return;
98
+		}
99
+
100
+		for (int i = 0; i < line.getTokenCount(); i++) {
101
+			ZSToken token = line.getToken(i);
102
+			if (tokenOffset + token.content.length() > offset) {
103
+				token = token.insert(offset - tokenOffset, value);
104
+				line.replace(i, token);
105
+				reparse(lineIndex, i, lineIndex, i + 1);
106
+				return;
107
+			}
108
+			tokenOffset += token.content.length();
109
+		}
110
+
111
+		ZSToken token = line.getLastToken();
112
+		token = new ZSToken(token.type, token.content + value);
113
+		line.replace(line.getTokenCount() - 1, token);
114
+		reparse(lineIndex, line.getTokenCount() - 1, lineIndex, line.getTokenCount());
115
+	}
116
+	
117
+	private void reparse(int fromLine, int fromToken, int toLine, int toToken) {
118
+		TokenReparser reparser = new TokenReparser(filename, lines, fromLine, fromToken, toLine, toToken, spacesPerTab);
119
+		List<ZSToken> tokens = reparser.reparse();
120
+		replaceTokens(fromLine, fromToken, reparser.getLine(), reparser.getToken(), tokens);
121
+	}
122
+	
123
+	private void replaceTokens(int fromLine, int fromToken, int toLine, int toToken, List<ZSToken> tokens) {
124
+		removeTokens(fromLine, fromToken, toLine, toToken);
125
+		insertTokens(fromLine, fromToken, tokens.iterator());
126
+	}
127
+	
128
+	private void removeTokens(int fromLine, int fromToken, int toLine, int toToken) {
129
+		if (toLine > fromLine) {
130
+			TokenLine fromLineObject = lines.get(fromLine);
131
+			fromLineObject.removeRange(fromToken, fromLineObject.getTokenCount());
132
+			
133
+			listeners.accept(listener -> listener.onLineChanged(fromLine));
134
+			
135
+			TokenLine toLineObject = lines.get(toLine);
136
+			for (int i = toToken - 1; i >= 0; i--)
137
+				toLineObject.remove(i);
138
+			
139
+			listeners.accept(listener -> listener.onLineChanged(toLine));
140
+			
141
+			merge(lines.get(fromLine), fromLine, lines.remove(toLine));
142
+			for (int i = toLine - 1; i > fromLine; i--) {
143
+				lines.remove(i);
144
+				
145
+				int ix = i;
146
+				listeners.accept(listener -> listener.onLineDeleted(ix));
147
+			}
148
+		} else {
149
+			TokenLine line = lines.get(fromLine);
150
+			for (int i = toToken - 1; i >= fromToken; i--)
151
+				line.remove(i);
152
+			
153
+			listeners.accept(listener -> listener.onLineChanged(fromLine));
154
+		}
155
+	}
156
+	
157
+	private void insertTokens(int line, int tokenIndex, Iterator<ZSToken> tokens) {
158
+		TokenLine currentLine = lines.get(line);
159
+		Set<Integer> insertedLines = new HashSet<>();
160
+		Set<Integer> modifiedLines = new HashSet<>();
161
+		while (tokens.hasNext()) {
162
+			ZSToken token = tokens.next();
163
+			if (token.type.multiline && token.content.indexOf('\n') >= 0) {
164
+				TokenLine newLine = new TokenLine();
165
+				if (tokenIndex < currentLine.getTokenCount()) {
166
+					for (int i = currentLine.getTokenCount() - 1; i >= tokenIndex; i--) {
167
+						newLine.insert(0, currentLine.remove(i));
168
+					}
169
+				}
170
+				
171
+				tokenIndex = 0;
172
+				if (!token.content.equals("\n")) {
173
+					String[] parts = token.content.split("\r?\n");
174
+					if (!parts[0].isEmpty())
175
+						currentLine.add(new ZSToken(token.type, parts[0]));
176
+					if (!parts[parts.length - 1].isEmpty()) {
177
+						newLine.insert(0, new ZSToken(token.type, parts[parts.length - 1]));
178
+						tokenIndex++;
179
+					}
180
+					
181
+					for (int i = 1; i < parts.length - 1; i++) {
182
+						TokenLine intermediate = new TokenLine();
183
+						if (!parts[i].isEmpty())
184
+							intermediate.add(new ZSToken(token.type, parts[i]));
185
+						lines.add(++line, intermediate);
186
+					}
187
+				}
188
+				
189
+				currentLine = newLine;
190
+				lines.add(++line, currentLine);
191
+				insertedLines.add(line);
192
+			} else if (token.type != ZSTokenType.T_WHITESPACE_CARRIAGE_RETURN) {
193
+				currentLine.insert(tokenIndex++, token);
194
+				modifiedLines.add(line);
195
+			}
196
+		}
197
+		
198
+		listeners.accept(listener -> {
199
+			for (Integer inserted : insertedLines)
200
+				listener.onLineInserted(inserted);
201
+			for (Integer modified : modifiedLines)
202
+				if (!insertedLines.contains(modified))
203
+					listener.onLineChanged(modified);
204
+		});
205
+	}
206
+	
207
+	@Override
208
+	public String toString() {
209
+		StringBuilder result = new StringBuilder();
210
+		for (int i = 0; i < lines.size(); i++) {
211
+			if (i > 0)
212
+				result.append("\n");
213
+			
214
+			TokenLine line = lines.get(i);
215
+			for (ZSToken token : line.getTokens()) {
216
+				result.append(token.content);
217
+			}
218
+		}
219
+		return result.toString();
220
+	}
221
+		
222
+	private void merge(TokenLine line, int lineIndex, TokenLine other) {
223
+		if (line.isEmpty()) {
224
+			line.addAll(other.getTokens());
225
+			return;
226
+		}
227
+
228
+		int fromToken = line.getTokenCount() - 1;
229
+		int toToken = !other.isEmpty() ? fromToken + 2 : fromToken + 1;
230
+		line.addAll(other.getTokens());
231
+		reparse(lineIndex, fromToken, lineIndex, toToken);
232
+	}
233
+	
234
+	public interface Listener {
235
+		void onLineInserted(int index);
236
+		
237
+		void onLineChanged(int index);
238
+		
239
+		void onLineDeleted(int index);
240
+	}
241
+}

+ 7
- 7
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenReparser.java View File

19
  * @author Hoofdgebruiker
19
  * @author Hoofdgebruiker
20
  */
20
  */
21
 public class TokenReparser {
21
 public class TokenReparser {
22
-	private final List<SourceEditor.Line> lines;
22
+	private final List<TokenLine> lines;
23
 	private final String filename;
23
 	private final String filename;
24
 	private final int toLine;
24
 	private final int toLine;
25
 	private final int toToken;
25
 	private final int toToken;
28
 	private int lineIndex;
28
 	private int lineIndex;
29
 	private int token;
29
 	private int token;
30
 	
30
 	
31
-	public TokenReparser(String filename, List<SourceEditor.Line> lines, int fromLine, int fromToken, int toLine, int toToken, int spacesPerTab) {
31
+	public TokenReparser(String filename, List<TokenLine> lines, int fromLine, int fromToken, int toLine, int toToken, int spacesPerTab) {
32
 		if (fromToken < 0 || toToken < 0)
32
 		if (fromToken < 0 || toToken < 0)
33
 			throw new IllegalArgumentException("fromToken or toToken cannot be < 0");
33
 			throw new IllegalArgumentException("fromToken or toToken cannot be < 0");
34
 		
34
 		
52
 	}
52
 	}
53
 	
53
 	
54
 	private String get() {
54
 	private String get() {
55
-		SourceEditor.Line line = lines.get(lineIndex);
56
-		if (token == line.tokens.size())
55
+		TokenLine line = lines.get(lineIndex);
56
+		if (token == line.getTokenCount())
57
 			return "\n"; // special "newline" token for transitions to next line
57
 			return "\n"; // special "newline" token for transitions to next line
58
 		
58
 		
59
-		return line.tokens.get(token).content;
59
+		return line.getToken(token).content;
60
 	}
60
 	}
61
 	
61
 	
62
 	private boolean advance() {
62
 	private boolean advance() {
63
-		if (lineIndex == lines.size() - 1 && token == lines.get(lineIndex).tokens.size())
63
+		if (lineIndex == lines.size() - 1 && token == lines.get(lineIndex).getTokenCount())
64
 			return false;
64
 			return false;
65
 		
65
 		
66
 		token++;
66
 		token++;
67
-		if (token > lines.get(lineIndex).tokens.size()) {
67
+		if (token > lines.get(lineIndex).getTokenCount()) {
68
 			lineIndex++;
68
 			lineIndex++;
69
 			token = 0;
69
 			token = 0;
70
 		}
70
 		}

+ 2
- 1
Parser/src/main/java/org/openzen/zenscript/lexer/ZSToken.java View File

43
 		return content;
43
 		return content;
44
 	}
44
 	}
45
 	
45
 	
46
+	@Override
46
 	public String toString() {
47
 	public String toString() {
47
 		return type + ":" + content;
48
 		return type + ":" + content;
48
 	}
49
 	}
50
 	public ZSToken delete(int offset, int characters) {
51
 	public ZSToken delete(int offset, int characters) {
51
 		return new ZSToken(
52
 		return new ZSToken(
52
 				ZSTokenType.INVALID,
53
 				ZSTokenType.INVALID,
53
-				content.substring(0, offset) + content.substring(offset));
54
+				content.substring(0, offset) + content.substring(offset + 1));
54
 	}
55
 	}
55
 	
56
 	
56
 	public Pair deleteAndSplit(int offset, int characters) {
57
 	public Pair deleteAndSplit(int offset, int characters) {

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

12
 public enum ZSTokenType implements TokenType {
12
 public enum ZSTokenType implements TokenType {
13
 	T_COMMENT_SCRIPT("#[^\n]*[\n\\e]", true),
13
 	T_COMMENT_SCRIPT("#[^\n]*[\n\\e]", true),
14
 	T_COMMENT_SINGLELINE("//[^\n]*[\n\\e]", true),
14
 	T_COMMENT_SINGLELINE("//[^\n]*[\n\\e]", true),
15
-	T_COMMENT_MULTILINE("/\\*([^\\*]|(\\*+([^\\*/])))*\\*+/", true),
15
+	T_COMMENT_MULTILINE("/\\*([^\\*]|(\\*+([^\\*/])))*\\*+/", true, true),
16
 	T_WHITESPACE_SPACE(true, " ", " "),
16
 	T_WHITESPACE_SPACE(true, " ", " "),
17
 	T_WHITESPACE_TAB(true, "\t", "\t"),
17
 	T_WHITESPACE_TAB(true, "\t", "\t"),
18
-	T_WHITESPACE_NEWLINE(true, "\n", "\n"),
18
+	T_WHITESPACE_NEWLINE(true, "\n", "\n", true),
19
 	T_WHITESPACE_CARRIAGE_RETURN(true, "\r", "\r"),
19
 	T_WHITESPACE_CARRIAGE_RETURN(true, "\r", "\r"),
20
 	T_IDENTIFIER("[a-zA-Z_][a-zA-Z_0-9]*"),
20
 	T_IDENTIFIER("[a-zA-Z_][a-zA-Z_0-9]*"),
21
 	T_FLOAT("\\-?(0|[1-9][0-9]*)\\.[0-9]+([eE][\\+\\-]?[0-9]+)?"),
21
 	T_FLOAT("\\-?(0|[1-9][0-9]*)\\.[0-9]+([eE][\\+\\-]?[0-9]+)?"),
161
 	
161
 	
162
 	public final ZSToken flyweight;
162
 	public final ZSToken flyweight;
163
 	public final boolean isKeyword;
163
 	public final boolean isKeyword;
164
+	public final boolean multiline;
164
 	
165
 	
165
 	private ZSTokenType() {
166
 	private ZSTokenType() {
166
 		this.regexp = null;
167
 		this.regexp = null;
167
 		this.whitespace = false;
168
 		this.whitespace = false;
168
 		this.isKeyword = false;
169
 		this.isKeyword = false;
169
 		this.flyweight = null;
170
 		this.flyweight = null;
171
+		this.multiline = false;
170
 	}
172
 	}
171
 	
173
 	
172
 	private ZSTokenType(String regexp) {
174
 	private ZSTokenType(String regexp) {
174
 		this.whitespace = false;
176
 		this.whitespace = false;
175
 		this.isKeyword = false;
177
 		this.isKeyword = false;
176
 		this.flyweight = null;
178
 		this.flyweight = null;
179
+		this.multiline = false;
177
 	}
180
 	}
178
 	
181
 	
179
 	private ZSTokenType(String regexp, boolean whitespace) {
182
 	private ZSTokenType(String regexp, boolean whitespace) {
181
 		this.whitespace = whitespace;
184
 		this.whitespace = whitespace;
182
 		this.isKeyword = false;
185
 		this.isKeyword = false;
183
 		this.flyweight = null;
186
 		this.flyweight = null;
187
+		this.multiline = false;
188
+	}
189
+	
190
+	private ZSTokenType(String regexp, boolean whitespace, boolean multiline) {
191
+		this.regexp = regexp;
192
+		this.whitespace = whitespace;
193
+		this.isKeyword = false;
194
+		this.flyweight = null;
195
+		this.multiline = multiline;
184
 	}
196
 	}
185
 	
197
 	
186
 	private ZSTokenType(String regexp, String content) {
198
 	private ZSTokenType(String regexp, String content) {
188
 		this.whitespace = false;
200
 		this.whitespace = false;
189
 		this.isKeyword = false;
201
 		this.isKeyword = false;
190
 		this.flyweight = new ZSToken(this, content, content);
202
 		this.flyweight = new ZSToken(this, content, content);
203
+		this.multiline = false;
191
 	}
204
 	}
192
 	
205
 	
193
 	private ZSTokenType(boolean isWhitespace, String regexp, String content) {
206
 	private ZSTokenType(boolean isWhitespace, String regexp, String content) {
195
 		this.whitespace = isWhitespace;
208
 		this.whitespace = isWhitespace;
196
 		this.isKeyword = false;
209
 		this.isKeyword = false;
197
 		this.flyweight = new ZSToken(this, content, content);
210
 		this.flyweight = new ZSToken(this, content, content);
211
+		this.multiline = false;
212
+	}
213
+	
214
+	private ZSTokenType(boolean isWhitespace, String regexp, String content, boolean multiline) {
215
+		this.regexp = regexp;
216
+		this.whitespace = isWhitespace;
217
+		this.isKeyword = false;
218
+		this.flyweight = new ZSToken(this, content, content);
219
+		this.multiline = multiline;
198
 	}
220
 	}
199
 	
221
 	
200
 	private ZSTokenType(boolean isKeyword, String content) {
222
 	private ZSTokenType(boolean isKeyword, String content) {
202
 		this.whitespace = false;
224
 		this.whitespace = false;
203
 		this.isKeyword = isKeyword;
225
 		this.isKeyword = isKeyword;
204
 		this.flyweight = new ZSToken(this, content, content);
226
 		this.flyweight = new ZSToken(this, content, content);
227
+		this.multiline = false;
205
 	}
228
 	}
206
 
229
 
207
 	@Override
230
 	@Override

Loading…
Cancel
Save