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

- CodePosition now stores source file references rather than source file names, allowing easier matching

- Starting work on error recording and display
- Fixed compilation of modules with dependencies
- Added a couple improvements to code typing for matching brackets
- Fixed java source compilation of abstract classes and methods
Stan Hebben преди 6 години
родител
ревизия
0ff6adff2e
променени са 41 файла, в които са добавени 501 реда и са изтрити 153 реда
  1. 4
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/DefinitionMember.java
  2. 2
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java
  3. 0
    22
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceFile.java
  4. 3
    1
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourcePackage.java
  5. 25
    0
      IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeError.java
  6. 41
    0
      IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeSpace.java
  7. 6
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDEModule.java
  8. 2
    3
      IDE/src/main/java/org/openzen/zenscript/ide/host/IDESourceFile.java
  9. 10
    0
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalModule.java
  10. 3
    2
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalPackage.java
  11. 12
    13
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalSourceFile.java
  12. 5
    5
      IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java
  13. 48
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/PathGenerator.java
  14. 39
    24
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java
  15. 6
    4
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java
  16. 5
    4
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenRelexer.java
  17. 47
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/WavyLine.java
  18. 1
    1
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java
  19. 2
    0
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/BaseMemberCompiler.java
  20. 2
    2
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaDefinitionVisitor.java
  21. 2
    2
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceCompiler.java
  22. 0
    1
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceTypeVisitor.java
  23. 24
    1
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareDefinitionVisitor.java
  24. 11
    3
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareExpansionMethodVisitor.java
  25. 20
    0
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/tags/JavaSourceImplementation.java
  26. 6
    5
      Parser/src/main/java/org/openzen/zenscript/lexer/CountingCharReader.java
  27. 7
    6
      Parser/src/main/java/org/openzen/zenscript/lexer/TokenParser.java
  28. 7
    6
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenParser.java
  29. 14
    17
      Parser/src/main/java/org/openzen/zenscript/parser/ParsedFile.java
  30. 7
    5
      Shared/src/main/java/org/openzen/zencode/shared/CodePosition.java
  31. 42
    0
      Shared/src/main/java/org/openzen/zencode/shared/FileSourceFile.java
  32. 34
    0
      Shared/src/main/java/org/openzen/zencode/shared/LiteralSourceFile.java
  33. 6
    9
      Shared/src/main/java/org/openzen/zencode/shared/SourceFile.java
  34. 31
    0
      Shared/src/main/java/org/openzen/zencode/shared/VirtualSourceFile.java
  35. 11
    0
      Shared/src/main/java/stdlib/Arrays.java
  36. 2
    2
      Shared/src/main/java/stdlib/Assoc.java
  37. 4
    4
      Shared/src/main/java/stdlib/Result.java
  38. 4
    2
      Shared/src/main/java/zsynthetic/Function10.java
  39. 2
    2
      Shared/src/main/java/zsynthetic/Function7.java
  40. 2
    4
      Shared/src/main/java/zsynthetic/Function8.java
  41. 2
    2
      Shared/src/main/java/zsynthetic/Function9.java

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

@@ -43,4 +43,8 @@ public abstract class DefinitionMember extends Taggable implements IDefinitionMe
43 43
 	public boolean isExtern() {
44 44
 		return Modifiers.isExtern(modifiers);
45 45
 	}
46
+	
47
+	public boolean isPrivate() {
48
+		return Modifiers.isPrivate(modifiers);
49
+	}
46 50
 }

+ 2
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java Целия файл

@@ -14,6 +14,7 @@ import java.util.function.Consumer;
14 14
 import org.json.JSONArray;
15 15
 import org.json.JSONObject;
16 16
 import org.openzen.zencode.shared.CompileException;
17
+import org.openzen.zencode.shared.FileSourceFile;
17 18
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
18 19
 import org.openzen.zenscript.compiler.CompilationUnit;
19 20
 import org.openzen.zenscript.constructor.ConstructorException;
@@ -112,7 +113,7 @@ public class DirectoryModuleReference implements ModuleReference {
112 113
 			if (file.isDirectory()) {
113 114
 				pkg.addPackage(loadPackage(file.getName(), file));
114 115
 			} else if (file.isFile() && file.getName().toLowerCase().endsWith(".zs")) {
115
-				pkg.addFile(new SourceFile(file.getName(), file));
116
+				pkg.addFile(new FileSourceFile(file.getName(), file));
116 117
 			}
117 118
 		}
118 119
 		

+ 0
- 22
Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourceFile.java Целия файл

@@ -1,22 +0,0 @@
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.constructor.module;
7
-
8
-import java.io.File;
9
-
10
-/**
11
- *
12
- * @author Hoofdgebruiker
13
- */
14
-public class SourceFile {
15
-	public final String name;
16
-	public final File file;
17
-	
18
-	public SourceFile(String name, File file) {
19
-		this.name = name;
20
-		this.file = file;
21
-	}
22
-}

+ 3
- 1
Constructor/src/main/java/org/openzen/zenscript/constructor/module/SourcePackage.java Целия файл

@@ -8,6 +8,8 @@ package org.openzen.zenscript.constructor.module;
8 8
 import java.io.File;
9 9
 import java.util.HashMap;
10 10
 import java.util.Map;
11
+import org.openzen.zencode.shared.FileSourceFile;
12
+import org.openzen.zencode.shared.SourceFile;
11 13
 
12 14
 /**
13 15
  *
@@ -29,6 +31,6 @@ public class SourcePackage {
29 31
 	}
30 32
 	
31 33
 	public void addFile(SourceFile file) {
32
-		sourceFiles.put(file.name, file);
34
+		sourceFiles.put(file.getFilename(), file);
33 35
 	}
34 36
 }

+ 25
- 0
IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeError.java Целия файл

@@ -0,0 +1,25 @@
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.codemodel;
7
+
8
+import org.openzen.zencode.shared.CodePosition;
9
+import org.openzen.zenscript.ide.host.IDESourceFile;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class IDECodeError {
16
+	public final IDESourceFile file;
17
+	public final CodePosition position;
18
+	public final String message;
19
+	
20
+	public IDECodeError(IDESourceFile file, CodePosition position, String message) {
21
+		this.file = file;
22
+		this.position = position;
23
+		this.message = message;
24
+	}
25
+}

+ 41
- 0
IDE/src/main/java/org/openzen/zenscript/ide/codemodel/IDECodeSpace.java Целия файл

@@ -5,8 +5,29 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.codemodel;
7 7
 
8
+import java.io.File;
9
+import java.util.ArrayList;
10
+import java.util.Collections;
11
+import java.util.HashMap;
12
+import java.util.HashSet;
13
+import java.util.List;
14
+import java.util.Map;
15
+import java.util.Set;
16
+import java.util.function.Consumer;
17
+import org.openzen.zenscript.compiler.CompilationUnit;
18
+import org.openzen.zenscript.compiler.SemanticModule;
19
+import org.openzen.zenscript.compiler.ZenCodeCompiler;
20
+import org.openzen.zenscript.constructor.Library;
21
+import org.openzen.zenscript.constructor.ModuleLoader;
22
+import org.openzen.zenscript.constructor.module.DirectoryModuleReference;
23
+import org.openzen.zenscript.constructor.module.ModuleReference;
8 24
 import org.openzen.zenscript.ide.host.DevelopmentHost;
25
+import org.openzen.zenscript.ide.host.IDEModule;
9 26
 import org.openzen.zenscript.ide.host.IDESourceFile;
27
+import org.openzen.zenscript.ide.ui.view.output.ErrorOutputSpan;
28
+import org.openzen.zenscript.ide.ui.view.output.OutputLine;
29
+import org.openzen.zenscript.validator.ValidationLogEntry;
30
+import stdlib.Strings;
10 31
 
11 32
 /**
12 33
  *
@@ -14,12 +35,32 @@ import org.openzen.zenscript.ide.host.IDESourceFile;
14 35
  */
15 36
 public class IDECodeSpace {
16 37
 	private final DevelopmentHost host;
38
+	private final Map<IDESourceFile, List<IDECodeError>> sourceFileErrors = new HashMap<>();
17 39
 	
18 40
 	public IDECodeSpace(DevelopmentHost host) {
19 41
 		this.host = host;
42
+		
43
+		ModuleLoader loader = new ModuleLoader(new CompilationUnit(), exception -> {
44
+			
45
+		});
46
+		for (IDEModule module : host.getModules()) {
47
+			module.prebuild(loader, this::addError);
48
+		}
20 49
 	}
21 50
 	
22 51
 	public void onSaved(IDESourceFile file) {
23 52
 		
24 53
 	}
54
+	
55
+	public List<IDECodeError> getErrors(IDESourceFile file) {
56
+		return sourceFileErrors.getOrDefault(file, Collections.emptyList());
57
+	}
58
+	
59
+	private void addError(IDECodeError error) {
60
+		if (error.file == null)
61
+			return;
62
+		if (!sourceFileErrors.containsKey(error.file))
63
+			sourceFileErrors.put(error.file, new ArrayList<>());
64
+		sourceFileErrors.get(error.file).add(error);
65
+	}
25 66
 }

+ 6
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/IDEModule.java Целия файл

@@ -5,6 +5,10 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.host;
7 7
 
8
+import java.util.function.Consumer;
9
+import org.openzen.zenscript.constructor.ModuleLoader;
10
+import org.openzen.zenscript.ide.codemodel.IDECodeError;
11
+
8 12
 /**
9 13
  *
10 14
  * @author Hoofdgebruiker
@@ -13,4 +17,6 @@ public interface IDEModule {
13 17
 	public String getName();
14 18
 	
15 19
 	public IDEPackage getRootPackage();
20
+	
21
+	void prebuild(ModuleLoader loader, Consumer<IDECodeError> errors);
16 22
 }

+ 2
- 3
IDE/src/main/java/org/openzen/zenscript/ide/host/IDESourceFile.java Целия файл

@@ -5,9 +5,8 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.host;
7 7
 
8
-import java.io.IOException;
9
-import java.io.Reader;
10 8
 import org.openzen.drawablegui.live.LiveString;
9
+import org.openzen.zencode.shared.SourceFile;
11 10
 
12 11
 /**
13 12
  *
@@ -16,7 +15,7 @@ import org.openzen.drawablegui.live.LiveString;
16 15
 public interface IDESourceFile {
17 16
 	public LiveString getName();
18 17
 	
19
-	public Reader read() throws IOException;
18
+	public SourceFile getFile();
20 19
 	
21 20
 	public void update(String content);
22 21
 }

+ 10
- 0
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalModule.java Целия файл

@@ -5,7 +5,11 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.host.local;
7 7
 
8
+import java.util.function.Consumer;
9
+import org.openzen.zenscript.compiler.SemanticModule;
10
+import org.openzen.zenscript.constructor.ModuleLoader;
8 11
 import org.openzen.zenscript.constructor.module.ModuleReference;
12
+import org.openzen.zenscript.ide.codemodel.IDECodeError;
9 13
 import org.openzen.zenscript.ide.host.IDEModule;
10 14
 import org.openzen.zenscript.ide.host.IDEPackage;
11 15
 
@@ -31,4 +35,10 @@ public class LocalModule implements IDEModule {
31 35
 	public IDEPackage getRootPackage() {
32 36
 		return rootPackage;
33 37
 	}
38
+	
39
+	@Override
40
+	public void prebuild(ModuleLoader loader, Consumer<IDECodeError> errors) {
41
+		SemanticModule module = loader.getModule(this.module.getName());
42
+		module.validate(entry -> errors.accept(new IDECodeError(null, entry.position, entry.message)));
43
+	}
34 44
 }

+ 3
- 2
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalPackage.java Целия файл

@@ -12,7 +12,8 @@ import org.openzen.drawablegui.live.LiveArrayList;
12 12
 import org.openzen.drawablegui.live.LiveList;
13 13
 import org.openzen.drawablegui.live.MutableLiveList;
14 14
 import org.openzen.drawablegui.live.SortedLiveList;
15
-import org.openzen.zenscript.constructor.module.SourceFile;
15
+import org.openzen.zencode.shared.FileSourceFile;
16
+import org.openzen.zencode.shared.SourceFile;
16 17
 import org.openzen.zenscript.constructor.module.SourcePackage;
17 18
 import org.openzen.zenscript.ide.host.IDEPackage;
18 19
 import org.openzen.zenscript.ide.host.IDESourceFile;
@@ -87,7 +88,7 @@ public class LocalPackage implements IDEPackage {
87 88
 			ex.printStackTrace(); // TODO
88 89
 		}
89 90
 		
90
-		SourceFile sourceFile = new SourceFile(name, file);
91
+		FileSourceFile sourceFile = new FileSourceFile(name, file);
91 92
 		IDESourceFile localSourceFile = new LocalSourceFile(sourceFile);
92 93
 		this.pkg.sourceFiles.put(name, sourceFile);
93 94
 		sourceFiles.add(localSourceFile);

+ 12
- 13
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalSourceFile.java Целия файл

@@ -5,20 +5,17 @@
5 5
  */
6 6
 package org.openzen.zenscript.ide.host.local;
7 7
 
8
-import java.io.BufferedInputStream;
9 8
 import java.io.BufferedOutputStream;
10
-import java.io.FileInputStream;
11 9
 import java.io.FileOutputStream;
12 10
 import java.io.IOException;
13
-import java.io.InputStreamReader;
14 11
 import java.io.OutputStreamWriter;
15
-import java.io.Reader;
16 12
 import java.io.Writer;
17 13
 import java.nio.charset.StandardCharsets;
18 14
 import org.openzen.drawablegui.live.LiveString;
19 15
 import org.openzen.drawablegui.live.MutableLiveString;
20 16
 import org.openzen.drawablegui.live.SimpleLiveString;
21
-import org.openzen.zenscript.constructor.module.SourceFile;
17
+import org.openzen.zencode.shared.FileSourceFile;
18
+import org.openzen.zencode.shared.SourceFile;
22 19
 import org.openzen.zenscript.ide.host.IDESourceFile;
23 20
 
24 21
 /**
@@ -31,7 +28,7 @@ public class LocalSourceFile implements IDESourceFile {
31 28
 	
32 29
 	public LocalSourceFile(SourceFile file) {
33 30
 		this.file = file;
34
-		this.name = new SimpleLiveString(file.name);
31
+		this.name = new SimpleLiveString(file.getFilename());
35 32
 	}
36 33
 
37 34
 	@Override
@@ -40,18 +37,20 @@ public class LocalSourceFile implements IDESourceFile {
40 37
 	}
41 38
 
42 39
 	@Override
43
-	public Reader read() throws IOException {
44
-		return new InputStreamReader(
45
-				new BufferedInputStream(new FileInputStream(file.file)),
46
-				StandardCharsets.UTF_8);
40
+	public SourceFile getFile() {
41
+		return file;
47 42
 	}
48 43
 
49 44
 	@Override
50 45
 	public void update(String content) {
51 46
 		try {
52
-			Writer writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file.file)), StandardCharsets.UTF_8);
53
-			writer.write(content);
54
-			writer.close();
47
+			if (file instanceof FileSourceFile) {
48
+				Writer writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(((FileSourceFile)file).file)), StandardCharsets.UTF_8);
49
+				writer.write(content);
50
+				writer.close();
51
+			} else {
52
+				throw new UnsupportedOperationException("Cannot write to a non-file source file!");
53
+			}
55 54
 		} catch (IOException ex) {
56 55
 			ex.printStackTrace();
57 56
 		}

+ 5
- 5
IDE/src/main/java/org/openzen/zenscript/ide/host/local/LocalTarget.java Целия файл

@@ -133,16 +133,16 @@ public class LocalTarget implements IDETarget {
133 133
 				continue;
134 134
 			
135 135
 			SemanticModule dependencyModule = loader.getModule(dependency);
136
-			module = module.normalize();
137
-			module.validate(logger);
138
-			if (!module.isValid())
136
+			dependencyModule = dependencyModule.normalize();
137
+			dependencyModule.validate(logger);
138
+			if (!dependencyModule.isValid())
139 139
 				return false;
140 140
 			
141 141
 			if (!compileDependencies(loader, compiler, compiledModules, dependencyModule, logger))
142 142
 				return false;
143 143
 			
144
-			module.compile(compiler);
145
-			compiledModules.add(module.name);
144
+			dependencyModule.compile(compiler);
145
+			compiledModules.add(dependencyModule.name);
146 146
 		}
147 147
 		
148 148
 		return true;

+ 48
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/PathGenerator.java Целия файл

@@ -0,0 +1,48 @@
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 org.openzen.drawablegui.DPath;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class PathGenerator {
15
+	private PathGenerator() {}
16
+	
17
+	public static class CubicBezierCurve {
18
+		public final float p1x;
19
+		public final float p1y;
20
+		public final float p2x;
21
+		public final float p2y;
22
+		public final float p3x;
23
+		public final float p3y;
24
+		public final float p4x;
25
+		public final float p4y;
26
+		
27
+		public CubicBezierCurve(float p1x, float p1y, float p2x, float p2y, float p3x, float p3y, float p4x, float p4y) {
28
+			this.p1x = p1x;
29
+			this.p1y = p1y;
30
+			this.p2x = p2x;
31
+			this.p2y = p2y;
32
+			this.p3x = p3x;
33
+			this.p3y = p3y;
34
+			this.p4x = p4x;
35
+			this.p4y = p4y;
36
+		}
37
+		
38
+		public void cut(float t0, float t1) {
39
+			// https://stackoverflow.com/questions/11703283/cubic-bezier-curve-segment
40
+			// P'1 = u0u0u0 P1 + (t0u0u0 + u0t0u0 + u0u0t0) P2 + (t0t0u0 + u0t0t0 + t0u0t0) P3 + t0t0t0 P4
41
+			// P'2 = u0u0u1 P1 + (t0u0u1 + u0t0u1 + u0u0t1) P2 + (t0t0u1 + u0t0t1 + t0u0t1) P3 + t0t0t1 P4
42
+			// P'3 = u0u1u1 P1 + (t0u1u1 + u0t1u1 + u0u1t1) P2 + (t0t1u1 + u0t1t1 + t0u1t1) P3 + t0t1t1 P4
43
+			// P'4 = u1u1u1 P1 + (t1u1u1 + u1t1u1 + u1u1t1) P2 + (t1t1u1 + u1t1t1 + t1u1t1) P3 + t1t1t1 P4
44
+			// u0 = 1 − t0 and u1 = 1 − t1
45
+			
46
+		}
47
+	}
48
+}

+ 39
- 24
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java Целия файл

@@ -6,6 +6,7 @@
6 6
 package org.openzen.zenscript.ide.ui.view.editor;
7 7
 
8 8
 import java.io.IOException;
9
+import java.io.Reader;
9 10
 import java.util.ArrayList;
10 11
 import java.util.List;
11 12
 import org.openzen.drawablegui.DComponent;
@@ -29,6 +30,7 @@ import org.openzen.zenscript.lexer.ZSToken;
29 30
 import org.openzen.zenscript.lexer.ZSTokenParser;
30 31
 import org.openzen.zenscript.lexer.ZSTokenType;
31 32
 import org.openzen.drawablegui.DUIContext;
33
+import org.openzen.drawablegui.Destructible;
32 34
 import org.openzen.drawablegui.draw.DDrawSurface;
33 35
 import org.openzen.drawablegui.draw.DDrawnRectangle;
34 36
 import org.openzen.drawablegui.draw.DDrawnShape;
@@ -95,23 +97,27 @@ public class SourceEditor implements DComponent {
95 97
 	private final List<DDrawnText> lineNumbers = new ArrayList<>();
96 98
 	private final List<List<DDrawnText>> drawnTokens = new ArrayList<>();
97 99
 	
100
+	//private DDrawnShape test;
101
+	
98 102
 	public SourceEditor(DStyleClass styleClass, IDEWindow window, IDESourceFile sourceFile) {
99 103
 		this.styleClass = styleClass;
100 104
 		this.window = window;
101 105
 		this.sourceFile = sourceFile;
102 106
 		
103
-		tokens = new TokenModel(sourceFile.getName().getValue(), tab.length());
107
+		tokens = new TokenModel(sourceFile.getFile(), tab.length());
104 108
 		tokenListener = tokens.addListener(new TokenListener());
105 109
 		
106 110
 		editToolbar.controls.add(() -> new IconButtonControl(DStyleClass.EMPTY, ShadedSaveIcon.PURPLE, SaveIcon.GREY, unchanged, new ImmutableLiveString("Save file"), e -> save()));
107 111
 		updated = new InverseLiveBool(unchanged);
108 112
 		
109 113
 		try {
114
+			Reader reader = sourceFile.getFile().open();
110 115
 			TokenParser<ZSToken, ZSTokenType> parser = ZSTokenParser.createRaw(
111
-					sourceFile.getName().getValue(),
112
-					new ReaderCharReader(sourceFile.read()),
116
+					sourceFile.getFile(),
117
+					new ReaderCharReader(reader),
113 118
 					tab.length());
114 119
 			tokens.set(parser);
120
+			reader.close();
115 121
 		} catch (IOException ex) {
116 122
 			ex.printStackTrace();
117 123
 		}
@@ -188,6 +194,11 @@ public class SourceEditor implements DComponent {
188 194
 			cursor = null;
189 195
 		}
190 196
 		
197
+		/*if (test != null) {
198
+			test.close();
199
+			test = null;
200
+		}*/
201
+		
191 202
 		if (blinkTimer != null)
192 203
 			blinkTimer.close();
193 204
 		
@@ -251,6 +262,8 @@ public class SourceEditor implements DComponent {
251 262
 					bounds.y + style.selectionPaddingTop + i * fullLineHeight + fontMetrics.getAscent());
252 263
 		}
253 264
 		
265
+		//test = surface.strokePath(z + 4, new WavyLine(bounds.x + 50, bounds.y + 50, 100, surface.getContext().dp(2), surface.getContext().dp(3)), DTransform2D.IDENTITY, IDEStyling.ERROR_RED, surface.getScale());
266
+		
254 267
 		layoutLines(0);
255 268
 	}
256 269
 	
@@ -287,6 +300,10 @@ public class SourceEditor implements DComponent {
287 300
 		}
288 301
 	}
289 302
 	
303
+	private void setCursor(SourcePosition position) {
304
+		setCursor(position, position);
305
+	}
306
+	
290 307
 	private void setCursor(SourcePosition start, SourcePosition end) {
291 308
 		cursorStart = start;
292 309
 		cursorEnd = end;
@@ -563,20 +580,24 @@ public class SourceEditor implements DComponent {
563 580
 		if (value.equals("{")) {
564 581
 			String indent = tokens.getLine(cursorEnd.line).getIndent();
565 582
 			tokens.insert(cursorEnd, "{\n" + indent + "\t\n" + indent + "}");
566
-			
567
-			SourcePosition position = new SourcePosition(tokens, cursorEnd.line + 1, indent.length() + 1);
568
-			setCursor(position, position);
569
-		} else if (value.equals(";")) {
570
-			String indent = tokens.getLine(cursorEnd.line).getIndent();
571
-			tokens.insert(cursorEnd, ";\n" + indent);
572
-			
573
-			SourcePosition position = new SourcePosition(tokens, cursorEnd.line + 1, indent.length());
574
-			setCursor(position, position);
583
+			setCursor(new SourcePosition(tokens, cursorEnd.line + 1, indent.length() + 1));
584
+		} else if (value.equals("\"")) {
585
+			if (!tokens.extract(cursorEnd, cursorEnd.advance(1)).equals("\""))
586
+				tokens.insert(cursorEnd, "\"\"");
587
+			setCursor(cursorEnd.advance(1));
588
+		} else if (value.equals("(")) {
589
+			tokens.insert(cursorEnd, "()");
590
+			setCursor(cursorEnd.advance(1));
591
+		} else if (value.equals(")") && tokens.extract(cursorEnd, cursorEnd.advance(1)).equals(")")){
592
+			setCursor(cursorEnd.advance(1));
593
+		} else if (value.equals("[")) {
594
+			tokens.insert(cursorEnd, "[]");
595
+			setCursor(cursorEnd.advance(1));
596
+		} else if (value.equals("]") && tokens.extract(cursorEnd, cursorEnd.advance(1)).equals("]")) {
597
+			setCursor(cursorEnd.advance(1));
575 598
 		} else {
576 599
 			tokens.insert(cursorEnd, value);
577
-			
578
-			SourcePosition position = new SourcePosition(tokens, cursorEnd.line, cursorEnd.offset + value.length());
579
-			setCursor(position, position);
600
+			setCursor(cursorEnd.advance(value.length()));
580 601
 		}
581 602
 		
582 603
 		unchanged.setValue(false);
@@ -734,9 +755,8 @@ public class SourceEditor implements DComponent {
734 755
 		@Override
735 756
 		public void onLineChanged(int index) {
736 757
 			if (bounds != null) {
737
-				removeLineTokens(drawnTokens.get(index));
738
-				drawnTokens.get(index).clear();
739
-				drawnTokens.get(index).addAll(lineToTokens(tokens.getLine(index)));
758
+				Destructible.close(drawnTokens.get(index));
759
+				drawnTokens.set(index, lineToTokens(tokens.getLine(index)));
740 760
 				layoutLine(index);
741 761
 			}
742 762
 		}
@@ -750,15 +770,10 @@ public class SourceEditor implements DComponent {
750 770
 			
751 771
 			if (bounds != null) {
752 772
 				lineNumbers.remove(lineNumbers.size() - 1).close();
753
-				removeLineTokens(drawnTokens.remove(index));
773
+				Destructible.close(drawnTokens.remove(index));
754 774
 				layoutLines(index);
755 775
 			}
756 776
 		}
757
-		
758
-		private void removeLineTokens(List<DDrawnText> tokens) {
759
-			for (DDrawnText token : tokens)
760
-				token.close();
761
-		}
762 777
 	}
763 778
 	
764 779
 	private enum TokenClass {

+ 6
- 4
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java Целия файл

@@ -13,6 +13,7 @@ import java.util.List;
13 13
 import java.util.Set;
14 14
 import org.openzen.drawablegui.listeners.ListenerHandle;
15 15
 import org.openzen.drawablegui.listeners.ListenerList;
16
+import org.openzen.zencode.shared.SourceFile;
16 17
 import org.openzen.zenscript.lexer.ZSToken;
17 18
 import org.openzen.zenscript.lexer.ZSTokenType;
18 19
 
@@ -23,13 +24,13 @@ import org.openzen.zenscript.lexer.ZSTokenType;
23 24
 public class TokenModel {
24 25
 	private final ListenerList<Listener> listeners = new ListenerList<>();
25 26
 	
26
-	private final String filename;
27
+	private final SourceFile file;
27 28
 	private final int spacesPerTab;
28 29
 	private final List<TokenLine> lines = new ArrayList<>();
29 30
 	private long version = 0;
30 31
 	
31
-	public TokenModel(String filename, int spacesPerTab) {
32
-		this.filename = filename;
32
+	public TokenModel(SourceFile file, int spacesPerTab) {
33
+		this.file = file;
33 34
 		this.spacesPerTab = spacesPerTab;
34 35
 	}
35 36
 	
@@ -210,7 +211,7 @@ public class TokenModel {
210 211
 	}
211 212
 	
212 213
 	private void relex(int fromLine, int fromToken, int toLine, int toToken) {
213
-		TokenRelexer reparser = new TokenRelexer(filename, lines, fromLine, fromToken, toLine, toToken, spacesPerTab);
214
+		TokenRelexer reparser = new TokenRelexer(file, lines, fromLine, fromToken, toLine, toToken, spacesPerTab);
214 215
 		List<ZSToken> tokens = reparser.relex();
215 216
 		replaceTokens(fromLine, fromToken, reparser.getLine(), reparser.getToken(), tokens);
216 217
 	}
@@ -257,6 +258,7 @@ public class TokenModel {
257 258
 		TokenLine currentLine = lines.get(line);
258 259
 		Set<Integer> insertedLines = new HashSet<>();
259 260
 		Set<Integer> modifiedLines = new HashSet<>();
261
+		modifiedLines.add(line);
260 262
 		while (tokens.hasNext()) {
261 263
 			ZSToken token = tokens.next();
262 264
 			if (token.type.multiline && token.content.indexOf('\n') >= 0) {

+ 5
- 4
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenRelexer.java Целия файл

@@ -8,6 +8,7 @@ package org.openzen.zenscript.ide.ui.view.editor;
8 8
 import java.io.IOException;
9 9
 import java.util.ArrayList;
10 10
 import java.util.List;
11
+import org.openzen.zencode.shared.SourceFile;
11 12
 import org.openzen.zenscript.lexer.CharReader;
12 13
 import org.openzen.zenscript.lexer.TokenParser;
13 14
 import org.openzen.zenscript.lexer.ZSToken;
@@ -20,7 +21,7 @@ import org.openzen.zenscript.lexer.ZSTokenType;
20 21
  */
21 22
 public class TokenRelexer {
22 23
 	private final List<TokenLine> lines;
23
-	private final String filename;
24
+	private final SourceFile file;
24 25
 	private final int toLine;
25 26
 	private final int toToken;
26 27
 	private final int spacesPerTab;
@@ -28,12 +29,12 @@ public class TokenRelexer {
28 29
 	private int lineIndex;
29 30
 	private int token;
30 31
 	
31
-	public TokenRelexer(String filename, List<TokenLine> lines, int fromLine, int fromToken, int toLine, int toToken, int spacesPerTab) {
32
+	public TokenRelexer(SourceFile file, List<TokenLine> lines, int fromLine, int fromToken, int toLine, int toToken, int spacesPerTab) {
32 33
 		if (fromToken < 0 || toToken < 0)
33 34
 			throw new IllegalArgumentException("fromToken or toToken cannot be < 0");
34 35
 		
35 36
 		this.lines = lines;
36
-		this.filename = filename;
37
+		this.file = file;
37 38
 		this.toLine = toLine;
38 39
 		this.toToken = toToken;
39 40
 		
@@ -44,7 +45,7 @@ public class TokenRelexer {
44 45
 	
45 46
 	public List<ZSToken> relex() {
46 47
 		RelexCharReader reader = new RelexCharReader();
47
-		TokenParser<ZSToken, ZSTokenType> reparser = ZSTokenParser.createRaw(filename, reader, spacesPerTab);
48
+		TokenParser<ZSToken, ZSTokenType> reparser = ZSTokenParser.createRaw(file, reader, spacesPerTab);
48 49
 		List<ZSToken> result = new ArrayList<>();
49 50
 		while ((lineIndex < toLine || token < toToken || !reader.isAtTokenBoundary()) && reparser.hasNext())
50 51
 			result.add(reparser.next());

+ 47
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/WavyLine.java Целия файл

@@ -0,0 +1,47 @@
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 org.openzen.drawablegui.DPath;
9
+import org.openzen.drawablegui.DPathTracer;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class WavyLine implements DPath {
16
+	private final int x;
17
+	private final int y;
18
+	private final int width;
19
+	private final int height;
20
+	private final float stride;
21
+	
22
+	public WavyLine(int x, int y, int width, int height, float stride) {
23
+		this.x = x;
24
+		this.y = y;
25
+		this.width = width;
26
+		this.height = height;
27
+		this.stride = stride;
28
+	}
29
+	
30
+	@Override
31
+	public void trace(DPathTracer tracer) {
32
+		tracer.moveTo(x, y);
33
+		for (int i = 0; i < (width / stride); i++) {
34
+			if ((i % 2) == 0) {
35
+				tracer.bezierCubic(
36
+						x + (i + 0.5f) * stride, y,
37
+						x + (i + 0.5f) * stride, y + height,
38
+						x + (i + 1) * stride, y + height);
39
+			} else {
40
+				tracer.bezierCubic(
41
+						x + (i + 0.5f) * stride, y + height,
42
+						x + (i + 0.5f) * stride, y,
43
+						x + (i + 1) * stride, y);
44
+			}
45
+		}
46
+	}
47
+}

+ 1
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java Целия файл

@@ -56,7 +56,7 @@ public class JavaCompiler implements ZenCodeCompiler {
56 56
 	@Override
57 57
 	public void addScriptBlock(ScriptBlock script) {
58 58
 		final SourceFile sourceFile = script.getTag(SourceFile.class);
59
-		final String className = getClassName(sourceFile == null ? null : sourceFile.filename);
59
+		final String className = getClassName(sourceFile == null ? null : sourceFile.getFilename());
60 60
 		JavaScriptFile scriptFile = getScriptFile(className);
61 61
 		
62 62
 		String methodName = scriptFile.scriptMethods.isEmpty() ? "run" : "run" + scriptFile.scriptMethods.size();

+ 2
- 0
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/BaseMemberCompiler.java Целия файл

@@ -75,6 +75,8 @@ public abstract class BaseMemberCompiler implements MemberVisitor<Void> {
75 75
 			output.append("protected ");
76 76
 		if (Modifiers.isPrivate(modifiers))
77 77
 			output.append("private ");
78
+		if (Modifiers.isAbstract(modifiers))
79
+			output.append("abstract ");
78 80
 		if (Modifiers.isStatic(modifiers))
79 81
 			output.append("static ");
80 82
 		if (Modifiers.isFinal(modifiers))

+ 2
- 2
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaDefinitionVisitor.java Целия файл

@@ -86,7 +86,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<Void> {
86 86
 		}
87 87
 		
88 88
 		if (mergedImplementations.size() > 0) {
89
-			output.append("implements ");
89
+			output.append(" implements ");
90 90
 			for (int i = 0; i < mergedImplementations.size(); i++) {
91 91
 				if (i > 0)
92 92
 					output.append(", ");
@@ -289,7 +289,7 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<Void> {
289 289
 			output.append("static ");
290 290
 		if (Modifiers.isAbstract(modifiers))
291 291
 			output.append("abstract ");
292
-		if (!Modifiers.isVirtual(modifiers))
292
+		if (!Modifiers.isVirtual(modifiers) && !Modifiers.isAbstract(modifiers))
293 293
 			output.append("final ");
294 294
 	}
295 295
 	

+ 2
- 2
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceCompiler.java Целия файл

@@ -93,8 +93,8 @@ public class JavaSourceCompiler implements ZenCodeCompiler {
93 93
 	private String getFilename(HighLevelDefinition definition) {
94 94
 		SourceFile source = definition.getTag(SourceFile.class);
95 95
 		if (source != null) {
96
-			int slash = Math.max(source.filename.lastIndexOf('/'), source.filename.lastIndexOf('\\'));
97
-			String filename = source.filename.substring(slash < 0 ? 0 : slash + 1);
96
+			int slash = Math.max(source.getFilename().lastIndexOf('/'), source.getFilename().lastIndexOf('\\'));
97
+			String filename = source.getFilename().substring(slash < 0 ? 0 : slash + 1);
98 98
 			filename = filename.substring(0, filename.lastIndexOf('.'));
99 99
 			return filename;
100 100
 		} else {

+ 0
- 1
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceTypeVisitor.java Целия файл

@@ -21,7 +21,6 @@ import org.openzen.zenscript.codemodel.type.IteratorTypeID;
21 21
 import org.openzen.zenscript.codemodel.type.OptionalTypeID;
22 22
 import org.openzen.zenscript.codemodel.type.RangeTypeID;
23 23
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
24
-import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
25 24
 
26 25
 /**
27 26
  *

+ 24
- 1
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareDefinitionVisitor.java Целия файл

@@ -22,7 +22,6 @@ import org.openzen.zenscript.codemodel.expression.CallExpression;
22 22
 import org.openzen.zenscript.codemodel.expression.CastExpression;
23 23
 import org.openzen.zenscript.codemodel.expression.Expression;
24 24
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
25
-import org.openzen.zenscript.codemodel.type.ArrayTypeID;
26 25
 import org.openzen.zenscript.formattershared.ExpressionString;
27 26
 import org.openzen.zenscript.javasource.JavaOperator;
28 27
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
@@ -168,6 +167,30 @@ public class JavaSourcePrepareDefinitionVisitor implements DefinitionVisitor<Jav
168 167
 			cls.addConstructor("constructorWithCause", "");
169 168
 			nativeClasses.put("stdlib::Exception", cls);
170 169
 		}
170
+		
171
+		{
172
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.io", "IOException"));
173
+			cls.addConstructor("constructor", "");
174
+			nativeClasses.put("io::IOException", cls);
175
+		}
176
+		
177
+		{
178
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.io", "Reader"));
179
+			cls.addInstanceMethod("destruct", "close");
180
+			cls.addInstanceMethod("readCharacter", "read");
181
+			cls.addInstanceMethod("readArray", "read");
182
+			cls.addInstanceMethod("readArraySlice", "read");
183
+			nativeClasses.put("io::Reader", cls);
184
+		}
185
+		
186
+		{
187
+			JavaNativeClass cls = new JavaNativeClass(new JavaSourceClass("java.io", "StringReader"));
188
+			cls.addInstanceMethod("constructor", "");
189
+			cls.addInstanceMethod("destructor", "close");
190
+			cls.addInstanceMethod("readCharacter", "read");
191
+			cls.addInstanceMethod("readSlice", "read");
192
+			nativeClasses.put("io::StringReader", cls);
193
+		}
171 194
 	}
172 195
 	
173 196
 	private final String filename;

+ 11
- 3
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/prepare/JavaSourcePrepareExpansionMethodVisitor.java Целия файл

@@ -17,6 +17,7 @@ import org.openzen.zenscript.codemodel.member.DefinitionMember;
17 17
 import org.openzen.zenscript.codemodel.member.DestructorMember;
18 18
 import org.openzen.zenscript.codemodel.member.FieldMember;
19 19
 import org.openzen.zenscript.codemodel.member.GetterMember;
20
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
20 21
 import org.openzen.zenscript.codemodel.member.ImplementationMember;
21 22
 import org.openzen.zenscript.codemodel.member.InnerDefinitionMember;
22 23
 import org.openzen.zenscript.codemodel.member.MemberVisitor;
@@ -27,6 +28,7 @@ import org.openzen.zenscript.codemodel.member.StaticInitializerMember;
27 28
 import org.openzen.zenscript.javasource.JavaSourceTypeNameVisitor;
28 29
 import org.openzen.zenscript.javasource.tags.JavaSourceClass;
29 30
 import org.openzen.zenscript.javasource.tags.JavaSourceField;
31
+import org.openzen.zenscript.javasource.tags.JavaSourceImplementation;
30 32
 import org.openzen.zenscript.javasource.tags.JavaSourceMethod;
31 33
 
32 34
 /**
@@ -54,7 +56,8 @@ public class JavaSourcePrepareExpansionMethodVisitor implements MemberVisitor<Vo
54 56
 	public Void visitField(FieldMember member) {
55 57
 		// TODO: expansion fields
56 58
 		member.setTag(JavaSourceField.class, new JavaSourceField(cls, member.name));
57
-		cls.empty = false;
59
+		if (member.hasAutoGetter() || member.hasAutoSetter())
60
+			cls.empty = false;
58 61
 		return null;
59 62
 	}
60 63
 
@@ -66,7 +69,8 @@ public class JavaSourcePrepareExpansionMethodVisitor implements MemberVisitor<Vo
66 69
 
67 70
 	@Override
68 71
 	public Void visitDestructor(DestructorMember member) {
69
-		throw new UnsupportedOperationException("Destructors not allowed on expansions");
72
+		visitFunctional(member, "");
73
+		return null;
70 74
 	}
71 75
 
72 76
 	@Override
@@ -114,7 +118,11 @@ public class JavaSourcePrepareExpansionMethodVisitor implements MemberVisitor<Vo
114 118
 	@Override
115 119
 	public Void visitImplementation(ImplementationMember member) {
116 120
 		// TODO: implementation merge check
117
-		cls.empty = false;
121
+		//cls.empty = false; -> TODO: 
122
+		member.setTag(JavaSourceImplementation.class, new JavaSourceImplementation(false));
123
+		for (IDefinitionMember implementedMember : member.members)
124
+			implementedMember.accept(this);
125
+		
118 126
 		return null;
119 127
 	}
120 128
 

+ 20
- 0
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/tags/JavaSourceImplementation.java Целия файл

@@ -0,0 +1,20 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.javasource.tags;
7
+
8
+/**
9
+ *
10
+ * @author Hoofdgebruiker
11
+ */
12
+public class JavaSourceImplementation {
13
+	public boolean inline = true;
14
+	
15
+	public JavaSourceImplementation() {}
16
+	
17
+	public JavaSourceImplementation(boolean inline) {
18
+		this.inline = inline;
19
+	}
20
+}

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

@@ -2,6 +2,7 @@ package org.openzen.zenscript.lexer;
2 2
 
3 3
 import java.io.IOException;
4 4
 import org.openzen.zencode.shared.CodePosition;
5
+import org.openzen.zencode.shared.SourceFile;
5 6
 
6 7
 /*
7 8
  * To change this license header, choose License Headers in Project Properties.
@@ -15,16 +16,16 @@ import org.openzen.zencode.shared.CodePosition;
15 16
  */
16 17
 public class CountingCharReader implements CharReader {
17 18
 	private final CharReader reader;
18
-	private final String filename;
19
+	private final SourceFile file;
19 20
 	private final int tabSize;
20 21
 	
21 22
 	private int line;
22 23
 	private int lineOffset;
23
-
24
-	public CountingCharReader(CharReader reader, String filename, int tabSize)
24
+	
25
+	public CountingCharReader(CharReader reader, SourceFile file, int tabSize)
25 26
 	{
26 27
 		this.reader = reader;
27
-		this.filename = filename;
28
+		this.file = file;
28 29
 		this.tabSize = tabSize;
29 30
 		
30 31
 		line = 1;
@@ -32,7 +33,7 @@ public class CountingCharReader implements CharReader {
32 33
 	}
33 34
 	
34 35
 	public CodePosition getPosition() {
35
-		return new CodePosition(filename, line, lineOffset, line, lineOffset);
36
+		return new CodePosition(file, line, lineOffset, line, lineOffset);
36 37
 	}
37 38
 
38 39
 	@Override

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

@@ -6,6 +6,7 @@ import java.util.Iterator;
6 6
 import org.openzen.zencode.shared.CodePosition;
7 7
 import org.openzen.zencode.shared.CompileException;
8 8
 import org.openzen.zencode.shared.CompileExceptionCode;
9
+import org.openzen.zencode.shared.SourceFile;
9 10
 
10 11
 /**
11 12
  * Represents a token stream. A token stream reads characters from a reader and
@@ -28,13 +29,13 @@ public class TokenParser<T extends Token<TT>, TT extends TokenType> implements I
28 29
     /**
29 30
      * Creates a token stream using the specified reader and DFA.
30 31
      *
31
-	 * @param filename filename
32
+	 * @param file filename
32 33
      * @param reader reader to read characters from
33 34
      * @param dfa DFA to tokenize the stream
34 35
 	 * @param eof end of file token type
35 36
      */
36 37
     public TokenParser(
37
-			String filename,
38
+			SourceFile file,
38 39
 			CharReader reader, 
39 40
 			CompiledDFA<TT> dfa,
40 41
 			TT eof,
@@ -44,7 +45,7 @@ public class TokenParser<T extends Token<TT>, TT extends TokenType> implements I
44 45
 		if (eof.isWhitespace()) // important for the advance() method
45 46
 			throw new IllegalArgumentException("EOF cannot be whitespace");
46 47
 		
47
-        this.reader = new CountingCharReader(reader, filename, 4);
48
+        this.reader = new CountingCharReader(reader, file, 4);
48 49
         this.dfa = dfa;
49 50
 		this.eof = eof;
50 51
 		this.invalid = invalid;
@@ -54,14 +55,14 @@ public class TokenParser<T extends Token<TT>, TT extends TokenType> implements I
54 55
     /**
55 56
      * Creates a token stream which reads data from the specified string.
56 57
      *
57
-	 * @param filename filename
58
+	 * @param file filename
58 59
      * @param data data to read
59 60
      * @param dfa DFA to tokenize the stream
60 61
 	 * @param eof end of file token type
61 62
      */
62
-    public TokenParser(String filename, String data, CompiledDFA<TT> dfa, TT eof, TT invalid, TokenFactory<T, TT> factory)
63
+    public TokenParser(SourceFile file, String data, CompiledDFA<TT> dfa, TT eof, TT invalid, TokenFactory<T, TT> factory)
63 64
 	{
64
-        this(filename, new StringCharReader(data), dfa, eof, invalid, factory);
65
+        this(file, new StringCharReader(data), dfa, eof, invalid, factory);
65 66
     }
66 67
 	
67 68
 	@Override

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

@@ -7,6 +7,7 @@ package org.openzen.zenscript.lexer;
7 7
 
8 8
 import java.io.IOException;
9 9
 import java.io.Reader;
10
+import org.openzen.zencode.shared.SourceFile;
10 11
 import org.openzen.zenscript.codemodel.WhitespaceInfo;
11 12
 
12 13
 /**
@@ -16,9 +17,9 @@ import org.openzen.zenscript.codemodel.WhitespaceInfo;
16 17
 public class ZSTokenParser extends LLParserTokenStream<ZSTokenType, ZSToken> {
17 18
 	private static final CompiledDFA DFA = CompiledDFA.createLexerDFA(ZSTokenType.values(), ZSTokenType.class);
18 19
 	
19
-	public static TokenParser<ZSToken, ZSTokenType> createRaw(String filename, CharReader reader, int spacesPerTab) {
20
+	public static TokenParser<ZSToken, ZSTokenType> createRaw(SourceFile file, CharReader reader, int spacesPerTab) {
20 21
 		return new TokenParser<>(
21
-				filename,
22
+				file,
22 23
 				reader,
23 24
 				DFA,
24 25
 				ZSTokenType.EOF,
@@ -26,16 +27,16 @@ public class ZSTokenParser extends LLParserTokenStream<ZSTokenType, ZSToken> {
26 27
 				new ZSTokenFactory(spacesPerTab));
27 28
 	}
28 29
 	
29
-	public static ZSTokenParser create(String filename, Reader reader, int spacesPerTab) throws IOException {
30
-		return new ZSTokenParser(createRaw(filename, new ReaderCharReader(reader), spacesPerTab));
30
+	public static ZSTokenParser create(SourceFile file, int spacesPerTab) throws IOException {
31
+		return new ZSTokenParser(createRaw(file, new ReaderCharReader(file.open()), spacesPerTab));
31 32
 	}
32 33
 	
33 34
 	public ZSTokenParser(TokenStream<ZSTokenType, ZSToken> parser) {
34 35
 		super(parser);
35 36
 	}
36 37
 	
37
-	public String getFilename() {
38
-		return getPosition().filename;
38
+	public SourceFile getFile() {
39
+		return getPosition().file;
39 40
 	}
40 41
 	
41 42
 	public WhitespaceInfo collectWhitespaceInfo(String whitespace, boolean skipLineBefore) {

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

@@ -8,14 +8,14 @@ package org.openzen.zenscript.parser;
8 8
 import java.io.File;
9 9
 import java.io.FileReader;
10 10
 import java.io.IOException;
11
-import java.io.Reader;
12
-import java.io.StringReader;
13 11
 import java.util.ArrayList;
14 12
 import java.util.List;
15 13
 import java.util.Map;
16 14
 import org.openzen.zencode.shared.CodePosition;
17 15
 import org.openzen.zencode.shared.CompileException;
18 16
 import org.openzen.zencode.shared.CompileExceptionCode;
17
+import org.openzen.zencode.shared.FileSourceFile;
18
+import org.openzen.zencode.shared.LiteralSourceFile;
19 19
 import org.openzen.zencode.shared.SourceFile;
20 20
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
21 21
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
@@ -42,27 +42,24 @@ import org.openzen.zenscript.parser.statements.ParsedStatement;
42 42
  */
43 43
 public class ParsedFile {
44 44
 	public static ParsedFile parse(ZSPackage pkg, File file) throws IOException {
45
-		String filename = file.toString();
46
-		try (FileReader reader = new FileReader(file)) {
47
-			return parse(pkg, filename, reader);
48
-		}
45
+		return parse(pkg, new FileSourceFile(file.getName(), file));
49 46
 	}
50 47
 	
51 48
 	public static ParsedFile parse(ZSPackage pkg, String filename, String content) {
52
-		try (StringReader reader = new StringReader(content)) {
53
-			return parse(pkg, filename, reader);
49
+		try {
50
+			return parse(pkg, new LiteralSourceFile(filename, content));
54 51
 		} catch (IOException ex) {
55
-			throw new AssertionError(); // supposed to never happen in a StringReader
52
+			throw new AssertionError(); // shouldn't happen
56 53
 		}
57 54
 	}
58 55
 	
59
-	public static ParsedFile parse(ZSPackage pkg, String filename, Reader reader) throws IOException {
60
-		ZSTokenParser tokens = ZSTokenParser.create(filename, reader, 4);
56
+	public static ParsedFile parse(ZSPackage pkg, SourceFile file) throws IOException {
57
+		ZSTokenParser tokens = ZSTokenParser.create(file, 4);
61 58
 		return parse(pkg, tokens);
62 59
 	}
63 60
 	
64 61
 	public static ParsedFile parse(ZSPackage pkg, ZSTokenParser tokens) {
65
-		ParsedFile result = new ParsedFile(tokens.getFilename());
62
+		ParsedFile result = new ParsedFile(tokens.getFile());
66 63
 		ZSToken eof = null;
67 64
 
68 65
 		while (true) {
@@ -124,15 +121,15 @@ public class ParsedFile {
124 121
 		return result;
125 122
 	}
126 123
 	
127
-	public final String filename;
124
+	public final SourceFile file;
128 125
 	
129 126
 	private final List<ParsedImport> imports = new ArrayList<>();
130 127
 	private final List<ParsedDefinition> definitions = new ArrayList<>();
131 128
 	private final List<ParsedStatement> statements = new ArrayList<>();
132 129
 	private WhitespacePostComment postComment = null;
133 130
 	
134
-	public ParsedFile(String filename) {
135
-		this.filename = filename;
131
+	public ParsedFile(SourceFile file) {
132
+		this.file = file;
136 133
 	}
137 134
 	
138 135
 	public boolean hasErrors() {
@@ -145,7 +142,7 @@ public class ParsedFile {
145 142
 	
146 143
 	public void listDefinitions(PackageDefinitions definitions) {
147 144
 		for (ParsedDefinition definition : this.definitions) {
148
-			definition.getCompiled().setTag(SourceFile.class, new SourceFile(filename));
145
+			definition.getCompiled().setTag(SourceFile.class, file);
149 146
 			definitions.add(definition.getCompiled());
150 147
 			definition.linkInnerTypes();
151 148
 		}
@@ -204,7 +201,7 @@ public class ParsedFile {
204 201
 			}
205 202
 			
206 203
 			ScriptBlock block = new ScriptBlock(statements);
207
-			block.setTag(SourceFile.class, new SourceFile(filename));
204
+			block.setTag(SourceFile.class, file);
208 205
 			block.setTag(WhitespacePostComment.class, postComment);
209 206
 			scripts.add(block);
210 207
 		}

+ 7
- 5
Shared/src/main/java/org/openzen/zencode/shared/CodePosition.java Целия файл

@@ -3,16 +3,18 @@ package org.openzen.zencode.shared;
3 3
 import org.openzen.zencode.shared.CodePosition;
4 4
 
5 5
 public final class CodePosition {
6
-	public static final CodePosition BUILTIN = new CodePosition("builtin", 0, 0, 0, 0);
7
-	public static final CodePosition NATIVE = new CodePosition("native", 0, 0, 0, 0);
6
+	public static final CodePosition BUILTIN = new CodePosition(new VirtualSourceFile("builtin"), 0, 0, 0, 0);
7
+	public static final CodePosition NATIVE = new CodePosition(new VirtualSourceFile("native"), 0, 0, 0, 0);
8 8
 	public final String filename;
9
+	public final SourceFile file;
9 10
 	public final int fromLine;
10 11
 	public final int fromLineOffset;
11 12
 	public final int toLine;
12 13
 	public final int toLineOffset;
13 14
 	
14
-	public CodePosition(String filename, int fromLine, int fromLineOffset, int toLine, int toLineOffset) {
15
-	    this.filename = filename;
15
+	public CodePosition(SourceFile file, int fromLine, int fromLineOffset, int toLine, int toLineOffset) {
16
+		this.file = file;
17
+	    this.filename = file.getFilename();
16 18
 	    this.fromLine = fromLine;
17 19
 	    this.fromLineOffset = fromLineOffset;
18 20
 	    this.toLine = toLine;
@@ -30,7 +32,7 @@ public final class CodePosition {
30 32
 	public CodePosition until(CodePosition to) {
31 33
 	    if (!filename.equals(to.filename))
32 34
 	        throw new AssertionError("From and to positions must be in the same file!");
33
-	    return new CodePosition(filename, fromLine, fromLineOffset, to.toLine, to.toLineOffset);
35
+	    return new CodePosition(file, fromLine, fromLineOffset, to.toLine, to.toLineOffset);
34 36
 	}
35 37
 	
36 38
 	public String toString() {

+ 42
- 0
Shared/src/main/java/org/openzen/zencode/shared/FileSourceFile.java Целия файл

@@ -0,0 +1,42 @@
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.zencode.shared;
7
+
8
+import java.io.BufferedInputStream;
9
+import java.io.BufferedReader;
10
+import java.io.File;
11
+import java.io.FileInputStream;
12
+import java.io.FileReader;
13
+import java.io.IOException;
14
+import java.io.InputStreamReader;
15
+import java.io.Reader;
16
+import java.nio.charset.StandardCharsets;
17
+
18
+/**
19
+ *
20
+ * @author Hoofdgebruiker
21
+ */
22
+public class FileSourceFile implements SourceFile {
23
+	public final String name;
24
+	public final File file;
25
+	
26
+	public FileSourceFile(String name, File file) {
27
+		this.name = name;
28
+		this.file = file;
29
+	}
30
+
31
+	@Override
32
+	public String getFilename() {
33
+		return name;
34
+	}
35
+
36
+	@Override
37
+	public Reader open() throws IOException {
38
+		return new InputStreamReader(
39
+				new BufferedInputStream(new FileInputStream(file)),
40
+				StandardCharsets.UTF_8);
41
+	}
42
+}

+ 34
- 0
Shared/src/main/java/org/openzen/zencode/shared/LiteralSourceFile.java Целия файл

@@ -0,0 +1,34 @@
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.zencode.shared;
7
+
8
+import java.io.IOException;
9
+import java.io.Reader;
10
+import java.io.StringReader;
11
+
12
+/**
13
+ *
14
+ * @author Hoofdgebruiker
15
+ */
16
+public class LiteralSourceFile implements SourceFile {
17
+	private final String filename;
18
+	private final String contents;
19
+	
20
+	public LiteralSourceFile(String filename, String contents) {
21
+		this.filename = filename;
22
+		this.contents = contents;
23
+	}
24
+
25
+	@Override
26
+	public String getFilename() {
27
+		return filename;
28
+	}
29
+
30
+	@Override
31
+	public Reader open() throws IOException {
32
+		return new StringReader(contents);
33
+	}
34
+}

+ 6
- 9
Shared/src/main/java/org/openzen/zencode/shared/SourceFile.java Целия файл

@@ -1,13 +1,10 @@
1 1
 package org.openzen.zencode.shared;
2 2
 
3
-public final class SourceFile {
4
-	public final String filename;
5
-	
6
-	public SourceFile(String filename) {
7
-	    this.filename = filename;
8
-	}
3
+import java.io.IOException;
4
+import java.io.Reader;
5
+
6
+public interface SourceFile {
7
+	String getFilename();
9 8
 	
10
-	public String getFilename() {
11
-	    return filename;
12
-	}
9
+	Reader open() throws IOException;
13 10
 }

+ 31
- 0
Shared/src/main/java/org/openzen/zencode/shared/VirtualSourceFile.java Целия файл

@@ -0,0 +1,31 @@
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.zencode.shared;
7
+
8
+import java.io.IOException;
9
+import java.io.Reader;
10
+
11
+/**
12
+ *
13
+ * @author Hoofdgebruiker
14
+ */
15
+public class VirtualSourceFile implements SourceFile {
16
+	private final String filename;
17
+	
18
+	public VirtualSourceFile(String filename) {
19
+		this.filename = filename;
20
+	}
21
+
22
+	@Override
23
+	public String getFilename() {
24
+		return filename;
25
+	}
26
+
27
+	@Override
28
+	public Reader open() throws IOException {
29
+		throw new UnsupportedOperationException("Cannot open virtual source files");
30
+	}
31
+}

+ 11
- 0
Shared/src/main/java/stdlib/Arrays.java Целия файл

@@ -2,13 +2,16 @@ package stdlib;
2 2
 
3 3
 import java.lang.reflect.Array;
4 4
 import java.util.ArrayList;
5
+import java.util.HashMap;
5 6
 import java.util.List;
7
+import java.util.Map;
6 8
 import zsynthetic.Function1;
7 9
 import zsynthetic.Function2;
8 10
 import zsynthetic.Function3;
9 11
 import zsynthetic.Function4;
10 12
 import zsynthetic.Function5;
11 13
 import zsynthetic.Function6;
14
+import zsynthetic.Function7;
12 15
 
13 16
 public final class Arrays {
14 17
     private Arrays() {}
@@ -170,4 +173,12 @@ public final class Arrays {
170 173
 	    }
171 174
 	    return result;
172 175
 	}
176
+	
177
+	public static <K, T> Map<K, T> index(Class<T> typeOfT, T[] self, Class<K> typeOfK, Function7<K, T> key) {
178
+	    Map<K, T> result = new HashMap<>();
179
+	    for (T value : self)
180
+	        
181
+	        result.put(key.invoke(value), value);
182
+	    return result;
183
+	}
173 184
 }

+ 2
- 2
Shared/src/main/java/stdlib/Assoc.java Целия файл

@@ -2,11 +2,11 @@ package stdlib;
2 2
 
3 3
 import java.util.HashMap;
4 4
 import java.util.Map;
5
-import zsynthetic.Function7;
5
+import zsynthetic.Function8;
6 6
 
7 7
 public final class Assoc {
8 8
     private Assoc() {}
9
-	static <W, K, V> Map<K, W> mapValues(Class<K> typeOfK, Class<V> typeOfV, Map<K, V> self, Class<W> typeOfW, Function7<W, V> projection) {
9
+	static <W, K, V> Map<K, W> mapValues(Class<K> typeOfK, Class<V> typeOfV, Map<K, V> self, Class<W> typeOfW, Function8<W, V> projection) {
10 10
 	    Map<K, W> result = new HashMap<>();
11 11
 	    for (Map.Entry<K, V> temp1 : self.entrySet()) {
12 12
 	        K k = temp1.getKey();

+ 4
- 4
Shared/src/main/java/stdlib/Result.java Целия файл

@@ -4,11 +4,11 @@ import stdlib.Result;
4 4
 import stdlib.Result.Error;
5 5
 import stdlib.Result.Ok;
6 6
 import zsynthetic.Function10;
7
-import zsynthetic.Function8;
7
+import zsynthetic.Function11;
8 8
 import zsynthetic.Function9;
9 9
 
10 10
 public abstract class Result<T, E> {
11
-	public <R> Result<R, E> then(Class<R> typeOfR, Function8<R, E, T> fn) {
11
+	public <R> Result<R, E> then(Class<R> typeOfR, Function9<R, E, T> fn) {
12 12
 	    Result<R, E> temp1;
13 13
 	    switch (this.getDiscriminant()) {
14 14
 	        case Ok:
@@ -25,7 +25,7 @@ public abstract class Result<T, E> {
25 25
 	    return temp1;
26 26
 	}
27 27
 	
28
-	public <X> Result<T, X> handle(Class<X> typeOfX, Function9<T, X, E> handler) {
28
+	public <X> Result<T, X> handle(Class<X> typeOfX, Function10<T, X, E> handler) {
29 29
 	    Result<T, X> temp1;
30 30
 	    switch (this.getDiscriminant()) {
31 31
 	        case Ok:
@@ -75,7 +75,7 @@ public abstract class Result<T, E> {
75 75
 	    return temp1;
76 76
 	}
77 77
 	
78
-	public T orElse(Function10<T, E> other) {
78
+	public T orElse(Function11<T, E> other) {
79 79
 	    T temp1;
80 80
 	    switch (this.getDiscriminant()) {
81 81
 	        case Ok:

+ 4
- 2
Shared/src/main/java/zsynthetic/Function10.java Целия файл

@@ -1,6 +1,8 @@
1 1
 package zsynthetic;
2
+import stdlib.Result;
3
+
2 4
 
3 5
 @FunctionalInterface
4
-public interface Function10<T, E>  {
5
-    T invoke(E error);
6
+public interface Function10<T, X, E>  {
7
+    Result<T, X> invoke(E error);
6 8
 }

+ 2
- 2
Shared/src/main/java/zsynthetic/Function7.java Целия файл

@@ -1,6 +1,6 @@
1 1
 package zsynthetic;
2 2
 
3 3
 @FunctionalInterface
4
-public interface Function7<W, V>  {
5
-    W invoke(V value);
4
+public interface Function7<K, T>  {
5
+    K invoke(T value);
6 6
 }

+ 2
- 4
Shared/src/main/java/zsynthetic/Function8.java Целия файл

@@ -1,8 +1,6 @@
1 1
 package zsynthetic;
2
-import stdlib.Result;
3
-
4 2
 
5 3
 @FunctionalInterface
6
-public interface Function8<R, E, T>  {
7
-    Result<R, E> invoke(T result);
4
+public interface Function8<W, V>  {
5
+    W invoke(V value);
8 6
 }

+ 2
- 2
Shared/src/main/java/zsynthetic/Function9.java Целия файл

@@ -3,6 +3,6 @@ import stdlib.Result;
3 3
 
4 4
 
5 5
 @FunctionalInterface
6
-public interface Function9<T, X, E>  {
7
-    Result<T, X> invoke(E error);
6
+public interface Function9<R, E, T>  {
7
+    Result<R, E> invoke(T result);
8 8
 }

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