]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
Merge "Minor refactorings related to SCL constructors"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / Elaboration.java
index 50296a3a1c6c287fb12b7a3564bf26af44f7a568..56e8eb3b66cc0cecaed1d4aa647e57ee7d180b1c 100644 (file)
@@ -12,11 +12,12 @@ import org.simantics.scl.compiler.constants.Constant;
 import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
 import org.simantics.scl.compiler.constants.SCLConstructor;
 import org.simantics.scl.compiler.constants.StringConstant;
+import org.simantics.scl.compiler.constants.componentaccess.ComponentAccess;
+import org.simantics.scl.compiler.constants.componentaccess.FieldComponentAccess;
 import org.simantics.scl.compiler.constants.generic.CallJava;
 import org.simantics.scl.compiler.constants.generic.ClassRef;
 import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
 import org.simantics.scl.compiler.constants.generic.MethodRef;
-import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
 import org.simantics.scl.compiler.constants.generic.OutputFilter;
 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
 import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
@@ -104,6 +105,7 @@ 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.types.TCon;
@@ -146,6 +148,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,
@@ -156,7 +160,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
@@ -169,19 +174,26 @@ 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(new CompilationError(failure.location, failure.toString(), ErrorSeverity.IMPORT_ERROR));
+                errorLog.log(new CompilationError(failure.location, failure.toString(),
+                        failure.reason == ImportFailure.MODULE_DOES_NOT_EXIST_REASON ? ErrorSeverity.ERROR : ErrorSeverity.IMPORT_ERROR));
             return;
         }
         for(ImportDeclaration importAst : importsAst)
@@ -194,19 +206,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
@@ -384,7 +397,7 @@ public class Elaboration {
                     parameterTypes[i] = context.toType(constructor.parameters[i]);
                 String javaName = constructors.length == 1 ? className 
                         : compilationContext.namingPolicy.getConstructorClassName(name);
-                String[] fieldNames = null;
+                ComponentAccess[] componentAccesses = null;
                 for(DAnnotationAst annotation : constructor.annotations)
                     if(annotation.id.text.equals("@JavaType")) {
                         try {
@@ -397,24 +410,24 @@ public class Elaboration {
                     else if(annotation.id.text.equals("@FieldNames")) {
                         try {
                             EListLiteral literal = (EListLiteral)annotation.parameters[0];
-                            fieldNames = new String[literal.getComponents().length];
-                            for(int i=0;i<fieldNames.length;++i) {
+                            componentAccesses = new ComponentAccess[literal.getComponents().length];
+                            for(int i=0;i<componentAccesses.length;++i) {
                                 Expression component = literal.getComponents()[i];
                                 if(component instanceof EVar)
-                                    fieldNames[i] = ((EVar)component).name;
+                                    componentAccesses[i] = new FieldComponentAccess(((EVar)component).name);
                                 else if(component instanceof ELiteral)
-                                    fieldNames[i] = ((StringConstant)((ELiteral)component).getValue()).getValue();
+                                    componentAccesses[i] = new FieldComponentAccess(((StringConstant)((ELiteral)component).getValue()).getValue());
                             }
                         } catch(Exception e) {
                             errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
-                            fieldNames = null;
+                            componentAccesses = null;
                         }
                     }   
                 
                 constructors[j] = new Constructor(constructor.location, dataType,
                         Name.create(moduleName, name), 
                         parameterTypes, javaName);
-                constructors[j].fieldNames = fieldNames;
+                constructors[j].componentAccesses = componentAccesses;
                 constructors[j].recordFieldNames = constructor.fieldNames;
             }
             if(constructors.length == 1) {
@@ -424,16 +437,19 @@ public class Elaboration {
                         @Override
                         public void run() {
                             Type in = Types.apply(dataType.name, dataType.parameters);
+                            
+                            ComponentAccess[] componentAccesses = constructor.componentAccesses != null
+                                       ? constructor.componentAccesses
+                                   : SCLConstructor.DEFAULT_FIELD_NAMES[constructor.recordFieldNames.length];
                             for(int i=0;i<constructor.recordFieldNames.length;++i) {
                                 Type out = constructor.parameterTypes[i];
                                 Constant accessor;
                                 if(trivialDataType)
                                     accessor = new SafeCoerce(dataType.parameters, in, out);
-                                else
+                                else 
                                     accessor = new CallJava(dataType.parameters, Types.NO_EFFECTS, out,
                                             new Type[] {in}, new StackItem[] {new ParameterStackItem(0, in)},
-                                            new FieldRef(constructor.javaName, constructor.fieldNames != null ? constructor.fieldNames[i] : "c" + i,
-                                                    javaTypeTranslator.toTypeDesc(out)),
+                                            componentAccesses[i].toMethodRef(constructor.javaName, javaTypeTranslator.toTypeDesc(out)),
                                             null);
                                 module.addFieldAccessor(constructor.recordFieldNames[i], accessor);
                             }
@@ -518,9 +534,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);
@@ -702,6 +717,8 @@ public class Elaboration {
                         isPrivate = true;
                     }
             }
+            if(exportMap != null)
+                isPrivate = exportMap.remove(name) == null;
             
             Type type = createTypeTranslationContext().toType(javaMethod.type);
 
@@ -1068,7 +1085,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) {
@@ -1115,6 +1132,7 @@ public class Elaboration {
             int constructorTag = 0;
             for(Constructor constructor : dataType.constructors) {
                 SCLValue value = new SCLValue(constructor.name);
+                value.parameterNames = constructor.recordFieldNames;
                 value.definitionLocation = constructor.loc;
                 SCLConstructor sclConstructor = 
                         new SCLConstructor(
@@ -1123,10 +1141,9 @@ public class Elaboration {
                                 constructor.getTypeVariables(),
                                 constructorTag++,
                                 constructor.getReturnType(),
-                                constructor.fieldNames == null 
+                                constructor.componentAccesses == null 
                                         ? SCLConstructor.DEFAULT_FIELD_NAMES[constructor.getParameterTypes().length] 
-                                        : constructor.fieldNames,
-                                constructor.recordFieldNames,
+                                        : constructor.componentAccesses,
                                 constructor.getParameterTypes());
                 if(dataType.constructors.length == 1 && (
                         dataType.getTypeDesc() == null ||
@@ -1205,21 +1222,13 @@ 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();
+                TranslationContext context = createTranslationContext(name);
                 Expression expression = context.translateCases2(defs);
                 value.setExpression(expression);
                 
@@ -1236,7 +1245,7 @@ public class Elaboration {
                 continue;
             try {
                 SCLValue value = module.getValue(name);
-                TranslationContext context = createTranslationContext();
+                TranslationContext context = createTranslationContext(name);
                 Expression expression = context.translateCases2(defs);
                 value.setExpression(expression);
                 
@@ -1256,9 +1265,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) {
@@ -1270,13 +1276,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) {
@@ -1358,4 +1364,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.");
+    }
 }