]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TApplyAst.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / parsing / types / TApplyAst.java
1 package org.simantics.scl.compiler.internal.parsing.types;
2
3 import java.util.Arrays;
4
5 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
6 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
7 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
8 import org.simantics.scl.compiler.environment.AmbiguousNameException;
9 import org.simantics.scl.compiler.environment.Environments;
10 import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
11 import org.simantics.scl.compiler.types.Type;
12 import org.simantics.scl.compiler.types.Types;
13 import org.simantics.scl.compiler.types.kinds.Kind;
14 import org.simantics.scl.compiler.types.kinds.Kinds;
15
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.set.hash.TIntHashSet;
18
19
20 public class TApplyAst extends TypeAst {
21     public final TypeAst function;
22     public final TypeAst[] parameters;
23     
24     public TApplyAst(TypeAst function, TypeAst[] parameters) {
25         this.function = function;
26         this.parameters = parameters;
27     }
28
29     @Override
30     public void toString(StringBuilder b) {
31         function.toString(b, 2);
32         for(TypeAst parameter : parameters) {
33             b.append(' ');
34             parameter.toString(b, 1);
35         }
36     }
37
38     @Override
39     public Type toType(TypeTranslationContext context, Kind expectedKind) {
40         if(function instanceof TVarAst) {
41             String name = ((TVarAst)function).name;
42             TypeAlias alias = null;
43             try {
44                 TypeDescriptor tdesc = Environments.getTypeDescriptor(context.getEnvironment(), name);
45                 if(tdesc instanceof TypeAlias)
46                     alias = (TypeAlias)tdesc;
47             } catch (AmbiguousNameException e) {
48                 context.getErrorLog().log(location, e.getMessage());
49                 return Types.metaVar(Kinds.STAR);
50             }
51             if(alias != null) {
52                 int arity = alias.getArity();
53                 if(parameters.length < arity) {
54                     context.getErrorLog().log(location, "Wrong number of parameters are given to the type alias. Expected " +
55                             arity + " parameters, got " + parameters.length + " parameters.");
56                     return Types.metaVar(Kinds.metaVar());
57                 }
58                 Type[] parameterTypes = new Type[arity];
59                 for(int i=0;i<arity;++i)
60                     parameterTypes[i] = parameters[i].toType(context, Kinds.metaVar());
61                 Type result = alias.body.replace(alias.parameters, parameterTypes);
62                 for(int i=arity;i<parameters.length;++i)
63                     result = Types.apply(result, parameters[i].toType(context, Kinds.metaVar()));
64                 return result;
65             }
66         }
67         
68         Kind[] parameterKinds = new Kind[parameters.length];
69         Kind functionKind = expectedKind;
70         for(int i=parameters.length-1;i>=0;--i) {
71             Kind kind = Kinds.metaVar();
72             parameterKinds[i] = kind;
73             functionKind = Kinds.arrow(kind, functionKind);
74         }        
75         Type functionType = function.toType(context, functionKind);
76         Type[] parameterTypes = new Type[parameters.length];
77         for(int i=0;i<parameters.length;++i) {
78             parameterTypes[i] = parameters[i].toType(context, parameterKinds[i]);
79         }
80         return Types.apply(functionType, parameterTypes);
81     }
82
83     @Override
84     public Type toType(TypeElaborationContext context) {
85         Type functionType = function.toType(context);
86         Type[] parameterTypes = new Type[parameters.length];
87         for(int i=0;i<parameters.length;++i)
88             parameterTypes[i] = parameters[i].toType(context);
89         return Types.apply(functionType, parameterTypes);
90     }
91     
92     @Override
93     public int getPrecedence() {
94         return 1;
95     }
96
97     public static TApplyAst apply(TypeAst f, TypeAst p) {
98         if(f instanceof TApplyAst) {
99             TApplyAst fApply = (TApplyAst)f; 
100             TypeAst[] parameters = Arrays.copyOf(fApply.parameters,
101                     fApply.parameters.length+1);
102             parameters[fApply.parameters.length] = p;
103             return new TApplyAst(fApply.function, parameters);
104         }
105         else
106             return new TApplyAst(f, new TypeAst[] {p});
107     }
108
109     @Override
110     public void collectReferences(TObjectIntHashMap<String> typeNameMap,
111             TIntHashSet set) {
112         function.collectReferences(typeNameMap, set);
113         for(TypeAst parameter : parameters)
114             parameter.collectReferences(typeNameMap, set);
115     }
116
117 }