]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java
Improvements to SCL compiler error messages
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / TypeChecking.java
index 97266d6e9781e16d2c5d77ba4d0107b80f8ee251..3118142df09740dce51ead4cf262f058f0b11b0b 100644 (file)
@@ -5,16 +5,13 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.app
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda;
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
@@ -28,7 +25,6 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
 import org.simantics.scl.compiler.environment.Environment;
-import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint;
 import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintEnvironment;
 import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintSolver;
@@ -42,18 +38,22 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
 public class TypeChecking {
-    final ErrorLog errorLog;
+    final CompilationContext compilationContext;
     final Environment environment;
     final ConcreteModule module;
     
     ConstraintEnvironment ce;
     TypeCheckingScheduler scheduler;
     
-    public TypeChecking(ErrorLog errorLog, Environment environment,
-            ConcreteModule module) {
-        this.errorLog = errorLog;
-        this.environment = environment;
+    public TypeChecking(CompilationContext compilationContext, ConcreteModule module) {
+        this.compilationContext = compilationContext;
+        this.environment = compilationContext.environment;
         this.module = module;
     }
     
@@ -97,6 +97,8 @@ public class TypeChecking {
                             context.pushEffectUpperBound(expression.location, Types.PROC);
                             expression = expression.checkType(context, value.getType());
                             context.popEffectUpperBound();
+                            for(EAmbiguous overloaded : context.overloadedExpressions)
+                                overloaded.assertResolved(compilationContext.errorLog);
                             value.setExpression(expression);
                             
                             ArrayList<EVariable> constraintDemand = context.getConstraintDemand();
@@ -125,7 +127,7 @@ public class TypeChecking {
                                 
                                 for(Constraint c : red.unsolvedConstraints)
                                     if(c.constraint.isGround())
-                                        errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
+                                        compilationContext.errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
                                 
                                 ArrayList<Variable> fe = new ArrayList<Variable>(red.unsolvedConstraints.size());
                                 for(Constraint c : red.unsolvedConstraints)
@@ -199,30 +201,43 @@ public class TypeChecking {
                         @Override
                         public void run() {
                             Type type = value.getType();
+
                             Expression expression = value.getExpression();
 
+                            int errorCountBeforeTypeChecking = compilationContext.errorLog.getErrorCount();
+                            int functionArity = expression.getSyntacticFunctionArity();
+                            
                             try {
                                 ArrayList<TVar> vars = new ArrayList<TVar>();
                                 type = Types.removeForAll(type, vars);
                                 ArrayList<TPred> givenConstraints = new ArrayList<TPred>();
                                 type = Types.removePred(type, givenConstraints);
 
-                                TypingContext context = new TypingContext(errorLog, environment);
+                                TypingContext context = new TypingContext(compilationContext);
                                 context.pushEffectUpperBound(expression.location, Types.PROC);
                                 expression = expression.checkType(context, type);
                                 context.popEffectUpperBound();
+                                for(EAmbiguous overloaded : context.overloadedExpressions)
+                                    overloaded.assertResolved(compilationContext.errorLog);
                                 expression.getType().addPolarity(Polarity.POSITIVE);
                                 context.solveSubsumptions(expression.getLocation());
+                                
+                                if(compilationContext.errorLog.getErrorCount() != errorCountBeforeTypeChecking) {
+                                    int typeArity = Types.getArity(type); 
+                                    if(typeArity != functionArity)
+                                        compilationContext.errorLog.log(value.definitionLocation, "Possible problem: type declaration has " + typeArity + " parameter types, but function definition has " + functionArity + " parameters.");
+                                }
+                                
                                 ArrayList<EVariable> demands = context.getConstraintDemand();
                                 if(!demands.isEmpty() || !givenConstraints.isEmpty()) {
                                     ReducedConstraints red = 
                                             ConstraintSolver.solve(ce, givenConstraints, demands, true);    
                                     givenConstraints.clear();
                                     for(Constraint c :  red.unsolvedConstraints) {
-                                        errorLog.log(c.getDemandLocation(), 
+                                        compilationContext.errorLog.log(c.getDemandLocation(), 
                                                 "Constraint <"+c.constraint+"> is not given and cannot be derived.");
                                     }
-                                    if(errorLog.isEmpty()) { // To prevent exceptions
+                                    if(compilationContext.errorLog.isEmpty()) { // To prevent exceptions
                                         expression = ExpressionAugmentation.augmentSolved(
                                                 red.solvedConstraints,
                                                 expression);
@@ -232,13 +247,13 @@ public class TypeChecking {
                                     }
                                 }
                                 else {
-                                    if(errorLog.isEmpty()) // To prevent exceptions
+                                    if(compilationContext.errorLog.isEmpty()) // To prevent exceptions
                                         expression = expression.decomposeMatching();
                                 }
                                 expression = expression.closure(vars.toArray(new TVar[vars.size()]));
                                 value.setExpression(expression);
                             } catch(Exception e) {
-                                errorLog.log(expression.location, e);
+                                compilationContext.errorLog.log(expression.location, e);
                             }
                         }
                     });
@@ -329,7 +344,7 @@ public class TypeChecking {
     
     public void typeCheck() {
         ce = new ConstraintEnvironment(environment);
-        scheduler = new TypeCheckingScheduler(errorLog, environment);
+        scheduler = new TypeCheckingScheduler(compilationContext);
         
         typeCheckValues();
         typeCheckRelations();
@@ -417,7 +432,7 @@ public class TypeChecking {
                     for(MappingRelation mappingRelation : module.getMappingRelations())
                         for(Type parameterType : mappingRelation.parameterTypes)
                             if(!parameterType.isGround()) {
-                                errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined.");
+                                compilationContext.errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined.");
                                 break;
                             }
                 }