]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
(refs #7776) Fixed module export for javaImports
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / Elaboration.java
index fccf2681507466ef7f4c9b6f44dc6aab04f76b04..abdabf5ac7e3cc55b0fb875e71dfc038d1a1f9b5 100644 (file)
@@ -61,7 +61,9 @@ import org.simantics.scl.compiler.environment.AmbiguousNameException;
 import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.environment.EnvironmentFactory;
 import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.errors.CompilationError;
 import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.errors.ErrorSeverity;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
 import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
@@ -77,6 +79,7 @@ import org.simantics.scl.compiler.internal.deriving.InstanceDerivers;
 import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector;
 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
 import org.simantics.scl.compiler.internal.header.ModuleHeader;
+import org.simantics.scl.compiler.internal.parsing.Token;
 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
@@ -93,6 +96,7 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
+import org.simantics.scl.compiler.internal.parsing.parser.SCLTerminals;
 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDClassAst;
 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
 import org.simantics.scl.compiler.internal.parsing.translation.RelationRepository;
@@ -102,8 +106,10 @@ import org.simantics.scl.compiler.module.ConcreteModule;
 import org.simantics.scl.compiler.module.ImportDeclaration;
 import org.simantics.scl.compiler.module.InvalidModulePathException;
 import org.simantics.scl.compiler.module.ModuleUtils;
+import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
 import org.simantics.scl.compiler.module.repository.ImportFailure;
 import org.simantics.scl.compiler.module.repository.ImportFailureException;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.TForAll;
 import org.simantics.scl.compiler.types.TFun;
@@ -144,6 +150,8 @@ public class Elaboration {
     ArrayList<StandardTypeConstructor> dataTypes = new ArrayList<StandardTypeConstructor>();
     THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
     THashMap<String, BranchPoint[]> branchPoints; 
+
+    THashMap<String, EVar> exportMap = null;
     
     public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
             String moduleName, ModuleHeader moduleHeader, ArrayList<ImportDeclaration> importsAst,
@@ -154,7 +162,8 @@ public class Elaboration {
         this.errorLog = compilationContext.errorLog;
         this.moduleName = moduleName;
         this.moduleHeader = moduleHeader;
-        importsAst = processRelativeImports(importsAst);
+        if(moduleName != null)
+            importsAst = processRelativeImports(compilationContext.errorLog, moduleName, importsAst);
         this.importsAst = importsAst;
         this.jrvFactory = jrvFactory;
         this.javaReferenceValidator = moduleHeader == null || moduleHeader.classLoader == null
@@ -167,19 +176,25 @@ public class Elaboration {
 
         module = new ConcreteModule(moduleName);
         compilationContext.module = module;
-        if(moduleHeader != null && moduleHeader.defaultLocalName != null)
-               module.setDefaultLocalName(moduleHeader.defaultLocalName);
+        compilationContext.moduleRepository = localEnvironmentFactory.getModuleRepository();
+        if(moduleHeader != null) {
+            if(moduleHeader.defaultLocalName != null)
+                module.setDefaultLocalName(moduleHeader.defaultLocalName);
+            if(moduleHeader.deprecated != null)
+                module.setDeprecation(moduleHeader.deprecated);
+        }
         try {
             if(timer != null)
                 timer.suspendTimer();
             importedEnvironment = localEnvironmentFactory.createEnvironment(
+                    compilationContext,
                     importsAst.toArray(new ImportDeclaration[importsAst.size()]));
             if(timer != null)
                 timer.continueTimer();
             compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module);
         } catch (ImportFailureException e) {
             for(ImportFailure failure : e.failures)
-                errorLog.log(failure.location, failure.toString());
+                errorLog.log(new CompilationError(failure.location, failure.toString(), ErrorSeverity.IMPORT_ERROR));
             return;
         }
         for(ImportDeclaration importAst : importsAst)
@@ -192,19 +207,20 @@ public class Elaboration {
         compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
     }
     
-    private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
+    public static ArrayList<ImportDeclaration> processRelativeImports(ErrorLog errorLog, String moduleName, ArrayList<ImportDeclaration> relativeImports) {
         ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
         for(ImportDeclaration relativeImport : relativeImports) {
             if(relativeImport.moduleName.startsWith(".")) {
                                try {
                                        String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName);
                     ImportDeclaration absoluteImport = new ImportDeclaration(
+                            relativeImport.location,
                             absoluteModuleName, relativeImport.localName,
                             relativeImport.reexport, relativeImport.spec);
-                    absoluteImport.location = relativeImport.location;
                     absoluteImports.add(absoluteImport);
                                } catch (InvalidModulePathException e) {
-                                       errorLog.log(relativeImport.location, e.getMessage());
+                                   if(errorLog != null)
+                                       errorLog.log(relativeImport.location, e.getMessage());
                                }
             }
             else
@@ -516,9 +532,8 @@ public class Elaboration {
                 method.setDefaultImplementation(Name.create(moduleName, fullName));
                 
                 valueDefinitionsAst.addDefinitions(fullName, defs);
-                /*valueDefinitionsAst.addAnnotation(fullName, new DAnnotationAst(new EVar("@private"), 
-                        Collections.<Expression>emptyList()));*/
-                supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType()));                
+                supplementedTypeAnnotations.add(new SupplementedValueType(defs.get(0).location, fullName, method.getType()));
+                valueDefinitionsAst.setDerived(fullName);
             }
             
             module.addTypeClass(classAst.name, typeClass);
@@ -700,6 +715,8 @@ public class Elaboration {
                         isPrivate = true;
                     }
             }
+            if(exportMap != null)
+                isPrivate = exportMap.remove(name) == null;
             
             Type type = createTypeTranslationContext().toType(javaMethod.type);
 
@@ -710,7 +727,7 @@ public class Elaboration {
                     type);
             if(callJava != null) {
                 NameExistenceChecks.checkIfValueExists(errorLog, javaMethod.location,
-                        importedEnvironment, name);
+                        importedEnvironment, module, name);
                 SCLValue value = module.addValue(name, callJava);
                 value.definitionLocation = javaMethod.methodName.location;
                 if(isPrivate)
@@ -1066,7 +1083,7 @@ public class Elaboration {
         
         final THashMap<SectionName, Query[]> sections = new THashMap<SectionName, Query[]>();
 
-        final TranslationContext context = createTranslationContext();
+        final TranslationContext context = createTranslationContext(ruleName);
         if(length > 0) {
             THashMap<String, Variable> variables = context.getVariables();
             for(TransformationRule extendsRule : extendsRules) {
@@ -1113,6 +1130,7 @@ public class Elaboration {
             int constructorTag = 0;
             for(Constructor constructor : dataType.constructors) {
                 SCLValue value = new SCLValue(constructor.name);
+                value.definitionLocation = constructor.loc;
                 SCLConstructor sclConstructor = 
                         new SCLConstructor(
                                 constructor.name.name,
@@ -1134,7 +1152,7 @@ public class Elaboration {
                 value.setType(constructor.getType());
                 
                 NameExistenceChecks.checkIfValueExists(errorLog, constructor.loc,
-                        importedEnvironment, constructor.name.name);
+                        importedEnvironment, module, constructor.name.name);
                 if(module.addValue(value)) {
                     errorLog.log(constructor.loc,
                             "Value " + constructor.name.name + " is already defined.");
@@ -1149,7 +1167,7 @@ public class Elaboration {
                 SCLValue value = method.createValue();
                 value.definitionLocation = method.location;
                 NameExistenceChecks.checkIfValueExists(errorLog, Locations.NO_LOCATION,
-                        importedEnvironment, value.getName().name);
+                        importedEnvironment, module, value.getName().name);
 
                 if(module.addValue(value)) {
                     String name = method.getName();
@@ -1169,7 +1187,7 @@ public class Elaboration {
             
             long location = valueDefinitionsAst.getLocation(name);
             NameExistenceChecks.checkIfValueExists(errorLog, location,
-                    importedEnvironment, value.getName().name);
+                    importedEnvironment, module, value.getName().name);
             value.definitionLocation = location;
             if(module.addValue(value))
                 errorLog.log(location, "Value " + name + " is already defined.");
@@ -1202,19 +1220,30 @@ public class Elaboration {
                     typeMap.put(name.name, valueTypeAst);
             }
         
-        THashMap<String, EVar> exportMap = null;
-        if(moduleHeader != null && moduleHeader.export != null) {
-            exportMap = new THashMap<String, EVar>();
-            for(EVar export : moduleHeader.export)
-                if(exportMap.put(export.name, export) != null)
-                    errorLog.log(export.location, "The symbol " + export.name + " is exported multiple times.");
+        for(String name : valueDefinitionsAst.getValueNames()) {
+            ArrayList<DValueAst> defs = valueDefinitionsAst.getDefinition(name);
+            if(defs.size() != 1 || !(defs.get(0).value instanceof EPreCHRRulesetConstructor))
+                continue;
+            try {
+                SCLValue value = module.getValue(name);
+                TranslationContext context = createTranslationContext(name);
+                Expression expression = context.translateCases2(defs);
+                value.setExpression(expression);
+                
+                if(exportMap != null && exportMap.remove(name) == null)
+                    value.addProperty(PrivateProperty.INSTANCE);
+            } catch(RuntimeException e) {
+                errorLog.setExceptionPosition(defs.get(0).location);
+                throw e;
+            }
         }
-        
         for(String name : valueDefinitionsAst.getValueNames()) {
             ArrayList<DValueAst> defs = valueDefinitionsAst.getDefinition(name);
+            if(defs.size() == 1 && defs.get(0).value instanceof EPreCHRRulesetConstructor)
+                continue;
             try {
                 SCLValue value = module.getValue(name);
-                TranslationContext context = createTranslationContext();
+                TranslationContext context = createTranslationContext(name);
                 Expression expression = context.translateCases2(defs);
                 value.setExpression(expression);
                 
@@ -1234,9 +1263,6 @@ public class Elaboration {
                 throw e;
             }
         }
-        if(exportMap != null)
-            for(EVar export : exportMap.values())
-                errorLog.log(export.location, "The symbol " + export.name + " is not defined in the module.");
         for(String name : relationDefinitionsAst.getRelationNames()) {
             ArrayList<DRelationAst> definitions = relationDefinitionsAst.getDefinition(name);
             if(definitions.size() > 1) {
@@ -1248,13 +1274,13 @@ public class Elaboration {
             DRelationAst definition = definitions.get(0);
             ConcreteRelation relation = (ConcreteRelation)module.getRelation(name);
             relation.location = definition.location;
-            TranslationContext context = createTranslationContext();
+            TranslationContext context = createTranslationContext(name);
             definition.translateTo(context, relation);
         }
     }
     
-    private TranslationContext createTranslationContext() {
-        return new TranslationContext(compilationContext, null);
+    private TranslationContext createTranslationContext(String definitionName) {
+        return new TranslationContext(compilationContext, null, definitionName);
     }
     
     private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
@@ -1336,4 +1362,23 @@ public class Elaboration {
             branchPoints.put(valueName, injector.getAndClearBranchPoints());
         }
     }
+
+    public void collectDebugInfo() {
+        module.moduleDebugInfo = compilationContext.moduleDebugInfo = new ModuleDebugInfo();
+    }
+
+    public void prepareExports() {
+        if(moduleHeader != null && moduleHeader.export != null) {
+            exportMap = new THashMap<String, EVar>();
+            for(EVar export : moduleHeader.export)
+                if(exportMap.put(export.name, export) != null)
+                    errorLog.log(export.location, "The symbol " + export.name + " is exported multiple times.");
+        }
+    }
+    
+    public void checkExports() {
+        if(exportMap != null)
+            for(EVar export : exportMap.values())
+                    errorLog.log(export.location, "The symbol " + export.name + " is not defined in the module.");
+    }
 }