]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
Showing compilation warnings in SCL issue view and editors
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / Elaboration.java
index d331283fd76f3ddfd624f65a4fc7c03e288379a5..0971641e8b4470b2938f2cc8ac9660dc58a7d316 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
 import org.simantics.scl.compiler.constants.generic.MethodRef;
 import org.simantics.scl.compiler.constants.generic.OutputFilter;
 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
+import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
 import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
 import org.simantics.scl.compiler.constants.generic.StackItem;
 import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
@@ -30,9 +31,11 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.EVar;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils;
 import org.simantics.scl.compiler.elaboration.fundeps.Fundep;
 import org.simantics.scl.compiler.elaboration.java.JavaMethodDeclaration;
 import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule;
+import org.simantics.scl.compiler.elaboration.modules.DeprecatedProperty;
 import org.simantics.scl.compiler.elaboration.modules.InlineProperty;
 import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
@@ -110,18 +113,17 @@ import gnu.trove.set.hash.TIntHashSet;
 
 public class Elaboration {
     // inputs
-    ErrorLog errorLog;
-    String moduleName;
-    ArrayList<ImportDeclaration> importsAst;
-    JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
-    ValueRepository valueDefinitionsAst;
-    RelationRepository relationDefinitionsAst;
+    private final CompilationContext compilationContext;
+    private final ErrorLog errorLog;
+    private final String moduleName;
+    private final ArrayList<ImportDeclaration> importsAst;
+    final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
+    private final ValueRepository valueDefinitionsAst;
+    private final RelationRepository relationDefinitionsAst;
 
     // creates
     ConcreteModule module;
     Environment importedEnvironment;
-    Environment environment;
-    JavaNamingPolicy namingPolicy;
     ArrayList<SupplementedValueType> supplementedTypeAnnotations = new ArrayList<SupplementedValueType>();
     
     JavaTypeTranslator javaTypeTranslator;
@@ -130,12 +132,13 @@ public class Elaboration {
     THashMap<String, BranchPoint[]> branchPoints; 
     
     @SuppressWarnings("unchecked")
-    public Elaboration(ErrorLog errorLog, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
+    public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
             String moduleName, ArrayList<ImportDeclaration> importsAst,
             JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
             ValueRepository valueDefinitionsAst,
             RelationRepository relationDefinitionsAst) {
-        this.errorLog = errorLog;
+        this.compilationContext = compilationContext;
+        this.errorLog = compilationContext.errorLog;
         this.moduleName = moduleName;
         importsAst = processRelativeImports(importsAst);
         this.importsAst = importsAst;
@@ -144,6 +147,7 @@ public class Elaboration {
         this.relationDefinitionsAst = relationDefinitionsAst;
 
         module = new ConcreteModule(moduleName);
+        compilationContext.module = module;
         try {
             if(timer != null)
                 timer.suspendTimer();
@@ -151,7 +155,7 @@ public class Elaboration {
                     importsAst.toArray(new ImportDeclaration[importsAst.size()]));
             if(timer != null)
                 timer.continueTimer();
-            this.environment = new EnvironmentOfModule(importedEnvironment, module);
+            compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module);
         } catch (ImportFailureException e) {
             for(ImportFailure failure : e.failures)
                 errorLog.log(failure.location, failure.toString());
@@ -164,7 +168,7 @@ public class Elaboration {
                     false,
                     importAst.spec));
         localEnvironmentFactory.addBuiltinDependencies(module);
-        namingPolicy = new JavaNamingPolicy(moduleName);
+        compilationContext.namingPolicy = new JavaNamingPolicy(moduleName);
     }
     
     private ArrayList<ImportDeclaration> processRelativeImports(ArrayList<ImportDeclaration> relativeImports) {
@@ -229,7 +233,7 @@ public class Elaboration {
 
             NameExistenceChecks.checkIfTypeExists(errorLog,
                     dataType.location, importedEnvironment, dataType.name);
-            if(module.addTypeConstructor(dataType.name, typeConstructor))
+            if(module.addTypeDescriptor(dataType.name, typeConstructor))
                 errorLog.log(dataType.location, "Type "+dataType.name+" has already been defined in this module.");
             dataType.typeConstructor = typeConstructor;
         }
@@ -238,7 +242,7 @@ public class Elaboration {
             TypeAlias alias = new TypeAlias(Types.con(moduleName, typeAlias.name), typeAlias.parameters.length);
             NameExistenceChecks.checkIfTypeExists(errorLog,
                     typeAlias.location, importedEnvironment, typeAlias.name);
-            if(module.addTypeAlias(typeAlias.name, alias)) {
+            if(module.addTypeDescriptor(typeAlias.name, alias)) {
                 errorLog.log(typeAlias.location, "Type alias "+typeAlias.name+" has already been defined in this module.");
             }
         }
@@ -253,7 +257,8 @@ public class Elaboration {
             if(module.addEffectConstructor(effect.name, effectConstructor))
                 errorLog.log(effect.location, "Type "+effect.name+" has already been defined in this module.");
         }     
-        javaTypeTranslator = new JavaTypeTranslator(environment);
+        javaTypeTranslator = new JavaTypeTranslator(compilationContext.environment);
+        compilationContext.javaTypeTranslator = javaTypeTranslator;
     }
     
     private static final int[] EMPTY_INT_ARRAY = new int[0];
@@ -307,9 +312,9 @@ public class Elaboration {
             }
         }.findComponents();
         
-        if(errorLog.isEmpty()) {
+        if(errorLog.hasNoErrors()) {
             for(DTypeAst typeAlias : orderedTypeAliases) {
-                TypeAlias alias = module.getTypeAlias(typeAlias.name);
+                TypeAlias alias = (TypeAlias)module.getTypeDescriptor(typeAlias.name);
                 TypeTranslationContext context = createTypeTranslationContext();
                 for(int i=0;i<typeAlias.parameters.length;++i)
                     context.pushTypeVar(typeAlias.parameters[i]);
@@ -346,7 +351,7 @@ public class Elaboration {
             boolean trivialDataType = dataTypeAst.constructors.length == 1 &&
                     dataTypeAst.constructors[0].parameters.length == 1;
             if(className == null && !trivialDataType)
-                className = namingPolicy.getDataTypeClassName(dataTypeAst.name);
+                className = compilationContext.namingPolicy.getDataTypeClassName(dataTypeAst.name);
             
             StandardTypeConstructor dataType = dataTypeAst.typeConstructor;
             
@@ -366,7 +371,7 @@ public class Elaboration {
                 for(int i=constructor.parameters.length-1;i>=0;--i)
                     parameterTypes[i] = context.toType(constructor.parameters[i]);
                 String javaName = constructors.length == 1 ? className 
-                        : namingPolicy.getConstructorClassName(name);
+                        : compilationContext.namingPolicy.getConstructorClassName(name);
                 String[] fieldNames = null;
                 for(DAnnotationAst annotation : constructor.annotations)
                     if(annotation.id.text.equals("@JavaType")) {
@@ -433,7 +438,7 @@ public class Elaboration {
             TypeClass typeClass = new TypeClass(classAst.location, 
                     classContext, 
                     con, 
-                    namingPolicy.getTypeClassInterfaceName(con),
+                    compilationContext.namingPolicy.getTypeClassInterfaceName(con),
                     parameters,
                     Fundep.mapFundeps(classAst.parameters, classAst.fundeps));
             
@@ -451,7 +456,7 @@ public class Elaboration {
                         typeClass.methodNames.add(name.name);
                         methods.put(name.name,
                                 new TypeClassMethod(typeClass, name.name, 
-                                        namingPolicy.getMethodName(name.name),
+                                        compilationContext.namingPolicy.getMethodName(name.name),
                                         type, Types.getArity(type),
                                         name.location)
                                 );
@@ -484,7 +489,7 @@ public class Elaboration {
     }
 
     private TypeTranslationContext createTypeTranslationContext() {
-        return new TypeTranslationContext(errorLog, environment);
+        return new TypeTranslationContext(compilationContext);
     }
     
     public void processDerivingInstances(ArrayList<DDerivingInstanceAst> derivingInstancesAst,
@@ -493,7 +498,7 @@ public class Elaboration {
             String name = derivingInstance.name.name;
             TCon con;
             try {
-                con = Environments.getTypeClassName(environment, name);
+                con = Environments.getTypeClassName(compilationContext.environment, name);
             } catch (AmbiguousNameException e) {
                 errorLog.log(derivingInstance.name.location, e.getMessage());
                 continue;
@@ -506,7 +511,7 @@ public class Elaboration {
             if(deriver == null)
                 errorLog.log(derivingInstance.location, "Doesn't know how to derive " + name + ".");
             else
-                deriver.derive(errorLog, environment, instancesAst, derivingInstance);
+                deriver.derive(errorLog, compilationContext.environment, instancesAst, derivingInstance);
         }
     }
     
@@ -520,7 +525,7 @@ public class Elaboration {
                 String name = instanceAst.name.name;
                 TCon typeClassCon;
                 try {
-                    typeClassCon = Environments.getTypeClassName(environment, name);
+                    typeClassCon = Environments.getTypeClassName(compilationContext.environment, name);
                 } catch (AmbiguousNameException e) {
                     errorLog.log(instanceAst.name.location, e.getMessage());
                     continue;
@@ -529,7 +534,7 @@ public class Elaboration {
                     errorLog.log(instanceAst.name.location, "Couldn't resolve class " + name + ".");
                     continue;
                 }
-                TypeClass typeClass = environment.getTypeClass(typeClassCon);
+                TypeClass typeClass = compilationContext.environment.getTypeClass(typeClassCon);
                 pInstanceAst.typeClass = typeClass;
                 
                 if(instanceAst.types.length != typeClass.parameters.length) {
@@ -550,7 +555,7 @@ public class Elaboration {
                 for(int i=0;i<instanceContext.length;++i)
                     instanceContext[i] = context.toTFuncApply(instanceAst.context[i]);
                 
-                String javaName = namingPolicy.getInstanceClassName(instance);
+                String javaName = compilationContext.namingPolicy.getInstanceClassName(instance);
                 String instancePrefix = instance.toName() + "$";
     
                 ValueRepository valueDefs = pInstanceAst.valueDefs;
@@ -626,6 +631,7 @@ public class Elaboration {
                         Expression expression = new EGetConstraint(instance.location, type);
                         value.setExpression(expression);
                         value.setType(Types.forAll(instance.generatorParameters, Types.constrained(instance.context, type)));
+                        value.getProperties().add(new InlineProperty(instance.context.length, 0xffffffff));
                         //TypeUnparsingContext tuc = new TypeUnparsingContext();
                         // TODO error handling
                         instance.superExpressions[i] = value;
@@ -848,7 +854,7 @@ public class Elaboration {
             effect.collectConcreteEffects(concreteEffects);
             
             for(TCon eff : concreteEffects) {
-                EffectConstructor effC = environment.getEffectConstructor(eff);
+                EffectConstructor effC = compilationContext.environment.getEffectConstructor(eff);
                 for(ThreadLocalVariable var : effC.getThreadLocalVariables()) {
                     for(int i=0;i<unresolvedItems.size();++i) {
                         int id = unresolvedItems.get(i);
@@ -893,8 +899,12 @@ public class Elaboration {
                     javaTypeTranslator.toTypeDesc(returnType);
             if(!javaReferenceValidator.isAssignableFrom(expectedReturnType,
                     providedReturnType)) {
-                if(expectedReturnType.equals(TypeDesc.VOID))
-                    filter = PopOutputFilter.INSTANCE;
+                if(expectedReturnType.equals(TypeDesc.VOID)) {
+                    if(providedReturnType.equals(TypeDesc.DOUBLE) || providedReturnType.equals(TypeDesc.LONG))
+                        filter = Pop2OutputFilter.INSTANCE;
+                    else
+                        filter = PopOutputFilter.INSTANCE;
+                }
                 else if(expectedReturnType.equals(Constants.LIST)
                         && providedReturnType.equals(Constants.COLLECTION))
                     filter = ConvertToListFilter.INSTANCE;
@@ -995,7 +1005,7 @@ public class Elaboration {
                     if(ruleAstMap.containsKey(extendsName))
                         extendsRule = processRule(extendsName);
                     else {
-                        extendsRule = Environments.getRule(environment, extendsName);
+                        extendsRule = Environments.getRule(compilationContext.environment, extendsName);
                         if(extendsRule == null)
                             errorLog.log(ruleAst.location,
                                     "Couldn't resolve rule name " + extendsName + ".");
@@ -1181,7 +1191,7 @@ public class Elaboration {
     }
     
     private TranslationContext createTranslationContext() {
-        return new TranslationContext(errorLog, environment, null);
+        return new TranslationContext(compilationContext, null);
     }
     
     private void handleAnnotation(SCLValue value, ArrayList<DValueAst> defs, DAnnotationAst annotation) {
@@ -1190,7 +1200,7 @@ public class Elaboration {
         }
         else if(annotation.id.text.equals("@inline")) {
             try {
-                int arity = defs.get(0).lhs.getFunctionDefinitionArity();
+                int arity = defs.get(0).lhs.getFunctionDefinitionPatternArity();
                 int phaseMask = 0xffffffff;
                 if(annotation.parameters.length > 0) {
                     phaseMask = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue());
@@ -1204,7 +1214,19 @@ public class Elaboration {
             value.addProperty(PrivateProperty.INSTANCE);
         }
         else if(annotation.id.text.equals("@deprecated")) {
-            // TODO
+            String description = "";
+            if(annotation.parameters.length > 0) {
+                if(annotation.parameters.length > 1)
+                    errorLog.log(annotation.location, "Invalid number of parameters, expected one string.");
+                else {
+                    String temp = AnnotationUtils.extractString(annotation.parameters[0]);
+                    if(temp == null)
+                        errorLog.log(annotation.location, "Invalid parameter, expected one string.");
+                    else
+                        description = temp;
+                }
+            }
+            value.addProperty(new DeprecatedProperty(description));
         }
         else
             errorLog.log(annotation.location, "Unknown annotation.");