]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/TextualModuleSource.java
SCL compiler generates line numbers to bytecode
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / source / TextualModuleSource.java
1 package org.simantics.scl.compiler.source;
2
3 import java.io.IOException;
4 import java.io.Reader;
5 import java.io.StringReader;
6 import java.util.Arrays;
7
8 import org.simantics.scl.compiler.compilation.SCLCompiler;
9 import org.simantics.scl.compiler.environment.EnvironmentFactoryImpl;
10 import org.simantics.scl.compiler.errors.CompilationErrorFormatter;
11 import org.simantics.scl.compiler.errors.Failable;
12 import org.simantics.scl.compiler.errors.Failure;
13 import org.simantics.scl.compiler.errors.Success;
14 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
15 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
16 import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator;
17 import org.simantics.scl.compiler.module.ImportDeclaration;
18 import org.simantics.scl.compiler.module.Module;
19 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
20 import org.simantics.scl.compiler.module.repository.ModuleRepository;
21 import org.simantics.scl.compiler.module.repository.UpdateListener;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 public abstract class TextualModuleSource implements ModuleSource {
26     private static final Logger LOGGER = LoggerFactory.getLogger(TextualModuleSource.class);
27     
28     public static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] {
29         new ImportDeclaration("Builtin", ""),
30         new ImportDeclaration("Prelude", "")
31     };
32     
33     private final String moduleName;
34     private final double priority;
35     
36     public TextualModuleSource(String moduleName, double priority) {
37         this.moduleName = moduleName;
38         this.priority = priority;
39     }
40     
41     public TextualModuleSource(String moduleName) {
42         this(moduleName, 0.0);
43     }
44     
45     @Override
46     public ClassLoader getClassLoader() {
47         return getClass().getClassLoader();
48     }
49
50     protected Reader getSourceReader(UpdateListener listener) throws IOException {
51         return new StringReader(getSourceText(listener));
52     }
53     
54     protected JavaReferenceValidator<?, ?, ?, ?> getJavaReferenceValidator() {
55         return new RuntimeJavaReferenceValidator(getClassLoader());
56     }
57     
58     public String getSourceText(UpdateListener listener) throws IOException {
59         Reader reader = getSourceReader(listener);
60         char[] buffer = new char[4096];
61         int pos = 0;
62         try {
63             while(true) {
64                 int count = reader.read(buffer, pos, buffer.length-pos);
65                 if(count == -1)
66                     return new String(buffer, 0, pos);
67                 pos += count;
68                 if(pos == buffer.length)
69                     buffer = Arrays.copyOf(buffer, 2*buffer.length);
70             }
71         } finally {
72             reader.close();
73         }
74     }
75     
76     public ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
77         return DEFAULT_IMPORTS;
78     }
79     
80     @Override
81     public String getModuleName() {
82         return moduleName;
83     }
84     
85     @SuppressWarnings("unchecked")
86     @Override
87     public Failable<Module> compileModule(final ModuleRepository environment, final UpdateListener listener, ModuleCompilationOptions options) {
88         SCLCompiler compiler = new SCLCompiler(options, getJavaReferenceValidatorFactory());
89         try {
90             String source = getSourceText(listener);
91             compiler.addSource(source);
92             compiler.compile(
93                     new EnvironmentFactoryImpl(
94                             environment, 
95                             getBuiltinImports(listener),
96                             listener),
97                     moduleName);
98             if(compiler.getErrorLog().hasNoErrors())
99                 return new Success<Module>(compiler.getModule());
100             else {
101                 if(options == null || !options.silent)
102                     LOGGER.error("While compiling " + getModuleName() + ":\n    " +
103                             CompilationErrorFormatter.toString(getSourceReader(null), compiler.getErrorLog().getErrors()).replaceAll("\n", "\n    "));
104                 return new Failure(compiler.getErrorLog().getErrors());
105             }
106         } catch (IOException e) {
107             if(options == null || !options.silent)
108                 LOGGER.error("Compilation of module " + moduleName + " failed.", e);
109             return new Failure(e);
110         }
111     }
112     
113     public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() {
114         return new JavaReferenceValidatorFactory() {
115             
116             @Override
117             public JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(String context) {
118                 return (JavaReferenceValidator<Object, Object, Object, Object>)TextualModuleSource.this.getJavaReferenceValidator();
119             }
120             
121             @Override
122             public JavaReferenceValidator<Object, Object, Object, Object> getDefaultJavaReferenceValidator() {
123                 return (JavaReferenceValidator<Object, Object, Object, Object>)TextualModuleSource.this.getJavaReferenceValidator();
124             }
125         };
126     }
127
128     @Override
129     public double getPriority() {
130         return priority;
131     }
132     
133     @Override
134     public String toString() {
135         return getClass().getSimpleName() + "(" + moduleName + ")";
136     }
137     
138     public boolean isUpdateable() {
139         return false;
140     }
141     
142     public void update(String newSourceText) {
143         throw new UnsupportedOperationException();
144     }
145 }