]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/SCLCompiler.java
(refs #7776) Fixed module export for javaImports
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / SCLCompiler.java
1 package org.simantics.scl.compiler.compilation;
2
3 import java.io.IOException;
4 import java.io.Reader;
5 import java.util.ArrayList;
6 import java.util.Map;
7
8 import org.simantics.scl.compiler.environment.EnvironmentFactory;
9 import org.simantics.scl.compiler.errors.ErrorLog;
10 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
11 import org.simantics.scl.compiler.internal.header.ModuleHeader;
12 import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
13 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
14 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
15 import org.simantics.scl.compiler.internal.parsing.parser.SCLParserOptions;
16 import org.simantics.scl.compiler.module.ConcreteModule;
17 import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
18 import org.simantics.scl.compiler.top.ModuleInitializer;
19 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
20 import org.simantics.scl.compiler.top.StandardModuleInitializer;
21
22 public class SCLCompiler {
23     CompilationContext compilationContext = new CompilationContext();
24     DeclarationClassification declarations = new DeclarationClassification(compilationContext);
25     
26     // publishable results
27     Map<String, byte[]> classes;
28     ConcreteModule module;
29     ModuleInitializer moduleInitializer;
30     
31     private CompilationTimer timer;
32     private ModuleCompilationOptions options;
33     
34     JavaReferenceValidatorFactory jrvFactory;
35     
36     public SCLCompiler(ModuleCompilationOptions options, JavaReferenceValidatorFactory jrvFactory) {
37         this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
38         this.jrvFactory = jrvFactory;
39     }
40
41     @SuppressWarnings("unchecked")
42     public void addSource(Reader sourceReader) {
43         if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
44         try {
45             SCLParserImpl parser = new SCLParserImpl(sourceReader);
46             parser.setParserOptions(SCLParserOptions.MODULE_DEFAULT);
47             parser.setCompilationContext(compilationContext);
48             if(!parser.isEmpty())
49             for(DeclarationAst declaration : (ArrayList<DeclarationAst>)parser.parseModule())
50                 declarations.handle(declaration);
51         } catch(SCLSyntaxErrorException e) {
52             compilationContext.errorLog.log(e.location, e.getMessage());
53         } catch(Exception e) {
54             compilationContext.errorLog.log(e);
55         } finally {
56             try {
57                 sourceReader.close();
58             } catch (IOException e) {
59                 e.printStackTrace();
60             }
61         }
62         if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Parsing");
63     }
64     
65     private boolean hasErrors() {
66         return !compilationContext.errorLog.hasNoErrors();
67     }
68     
69     public void compile(
70             EnvironmentFactory localEnvironmentFactory,
71             String moduleName) {
72         try {
73             if(hasErrors()) return;
74             Elaboration elaboration = new Elaboration(compilationContext,
75                     timer,
76                     localEnvironmentFactory,
77                     moduleName,
78                     compilationContext.header,
79                     declarations.importsAst,
80                     jrvFactory,
81                     declarations.valueDefinitionsAst,
82                     declarations.relationDefinitionsAst);
83             if(options.computeCoverage)
84                 elaboration.addCoverageBranchPoints();
85             if(options.collectDebugInfo)
86                 elaboration.collectDebugInfo();
87             // Elaboration
88             if(hasErrors()) return;
89             elaboration.prepareExports();
90             if(hasErrors()) return;
91             elaboration.addTypesToEnvironment(
92                     declarations.dataTypesAst,
93                     declarations.typeAliasesAst,
94                     declarations.effectsAst,
95                     declarations.rulesetsAst);
96             if(hasErrors()) return;
97             elaboration.processTypeAliases(declarations.typeAliasesAst);
98             if(hasErrors()) return;
99             elaboration.processDataTypes(declarations.dataTypesAst);
100             if(hasErrors()) return;
101             elaboration.processTypeClasses(declarations.typeClassesAst);
102             if(hasErrors()) return;
103             elaboration.processDerivingInstances(declarations.derivingInstancesAst, declarations.instancesAst);
104             if(hasErrors()) return;
105             elaboration.processInstances(declarations.instancesAst);
106             if(hasErrors()) return;
107             elaboration.processJavaMethods(declarations.javaMethodDeclarations);
108             if(hasErrors()) return;
109             elaboration.processRulesets(declarations.rulesetsAst);
110             if(hasErrors()) return;
111             elaboration.addDataTypesToEnvironment();
112             elaboration.addTypeClassesToEnvironment();
113             elaboration.preprocessValueDefinitions(declarations.typeAnnotationsAst);
114             elaboration.processMappingRelations(declarations.mappingRelationsAst);
115             elaboration.addFixityToEnvironment(declarations.fixityAst);
116             elaboration.addValueDefinitionsToEnvironment(declarations.typeAnnotationsAst);
117             elaboration.processRules(declarations.rulesAst);
118             elaboration.addSupplementedTypeAnnotationsToEnvironment();
119             elaboration.checkExports();
120             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Elaboration");
121             
122             // Type checking
123             if(hasErrors()) return;
124             //new TypeChecking(errorLog, elaboration.environment, elaboration.module).typeCheck();
125             new TypeChecking(compilationContext, elaboration.module).typeCheck();
126             
127             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("Type checking");
128             
129             // FIXME HACK for testing
130             /*if(!elaboration.module.getRules().isEmpty()) {
131                 TransformationBuilder tb = new TransformationBuilder(elaboration.module.getRules());
132                 tb.compileRules(elaboration.environment);
133                 System.out.println(tb.getCompiledExpression(elaboration.environment));
134             }*/
135             
136             // Documentation generation
137             new DocumentationGeneration(
138                     declarations.valueDocumentation,
139                     declarations.typeDocumentation,
140                     declarations.classDocumentation,
141                     elaboration.module
142                     )
143                 .generateDocumentation();
144             this.declarations = null;
145             
146             // Code generation
147             if(hasErrors()) return;
148             CodeGeneration codeGeneration = new CodeGeneration(
149                     compilationContext,
150                     elaboration.javaReferenceValidator,
151                     elaboration.module);
152             codeGeneration.simplifyValues();
153             if(hasErrors()) return;
154             codeGeneration.convertToSSA();
155             if(hasErrors()) return;
156             codeGeneration.optimizeSSA();
157             
158             if(SCLCompilerConfiguration.ENABLE_TIMING) phaseFinished("SSA conversion and optimization");
159             
160             if(hasErrors()) return;
161             codeGeneration.generateCode();
162             if(hasErrors()) return;
163             codeGeneration.generateDataTypes(elaboration.dataTypes);
164             if(hasErrors()) return;
165             codeGeneration.generateTypeClasses();
166             if(hasErrors()) return;
167             codeGeneration.generateTypeClassInstances();
168             if(hasErrors()) return;
169
170             classes = codeGeneration.classes;
171             module =  codeGeneration.module;
172             moduleInitializer = StandardModuleInitializer.create(
173                     compilationContext.namingPolicy.getModuleClassName(),
174                     codeGeneration.externalConstants);
175             
176             module.setClasses(classes);
177             module.setParentClassLoader(elaboration.javaReferenceValidator.getClassLoader());
178             module.setModuleInitializer(moduleInitializer);
179             module.setBranchPoints(elaboration.branchPoints);
180             if(compilationContext.errorLog.hasErrorsOrWarnings())
181                 module.setWarnings(compilationContext.errorLog.getErrors());
182             
183             if(SCLCompilerConfiguration.ENABLE_TIMING) {
184                 phaseFinished("Code generation");
185                 reportTiming(moduleName);
186             }
187         } catch(Exception e) {
188             compilationContext.errorLog.log(e);
189         }
190     }
191
192     public ErrorLog getErrorLog() {
193         return compilationContext.errorLog;
194     }
195     
196     public Map<String, byte[]> getClasses() {
197         return classes;
198     }
199     
200     public ConcreteModule getModule() {
201         return module;
202     }
203     
204     public ModuleInitializer getModuleInitializer() {
205         return moduleInitializer;
206     }
207     
208     private void initializeTiming() {
209         timer = new CompilationTimer();
210     }
211     
212     private void phaseFinished(String phaseName) {
213         timer.phaseFinished(phaseName);
214     }
215     
216     private void reportTiming(String moduleName) {
217         timer.report(moduleName);
218     }
219 }