]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / list / ListThen.java
1 package org.simantics.scl.compiler.elaboration.expressions.list;
2
3 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
4 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
6 import org.simantics.scl.compiler.elaboration.expressions.Expression;
7 import org.simantics.scl.compiler.errors.Locations;
8 import org.simantics.scl.compiler.types.TMetaVar;
9 import org.simantics.scl.compiler.types.Type;
10 import org.simantics.scl.compiler.types.Types;
11 import org.simantics.scl.compiler.types.exceptions.UnificationException;
12 import org.simantics.scl.compiler.types.kinds.Kinds;
13
14 public class ListThen extends ListQualifier {
15     public ListQualifier left;
16     public Expression transformer;
17     public Expression by; // optional
18     TMetaVar cType;
19     
20     public ListThen(Expression transformer, Expression by) {
21         this.transformer = transformer;
22         this.by = by;
23     }
24     
25     public void setLeft(ListQualifier inner) {
26         this.left = inner;
27     }
28     
29     @Override
30     public void checkType(TypingContext context) {
31         left.checkType(context);
32         
33         cType = Types.metaVar(Kinds.STAR);
34         Type transformerType = Types.function(Types.list(cType), Types.list(cType));
35         if(by != null) {
36             by = by.checkType(context, Types.metaVar(Kinds.STAR));
37             transformerType = Types.function(Types.function(cType, by.getType()), transformerType);
38         }
39         transformer = transformer.checkType(context, transformerType);
40         if(!(Types.canonical(cType) instanceof TMetaVar)) {
41             context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
42         }
43     }
44
45     @Override
46     public CompiledQualifier compile(SimplificationContext context) {
47         CompiledQualifier q = left.compile(context);
48         
49         try {
50             Types.unify(cType, q.pattern.getType());
51         } catch (UnificationException e) {
52             context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
53         }
54         
55         if(by == null)
56             q.value = context.apply(transformer, q.value);
57         else
58             q.value = context.apply(transformer, context.lambda(q.pattern.copy(), by), q.value);
59         return q;
60     }
61
62     @Override
63     public void resolve(TranslationContext context) {
64         transformer = transformer.resolve(context);
65         left.resolve(context);
66         if(by != null)
67             by = by.resolve(context);
68     }
69
70     @Override
71     public void setLocationDeep(long loc) {
72         if(location == Locations.NO_LOCATION) {
73             location = loc;
74             left.setLocationDeep(loc);
75             transformer.setLocationDeep(loc);
76             if(by != null)
77                 by.setLocationDeep(loc);
78         }
79     }
80     
81     @Override
82     public void accept(ListQualifierVisitor visitor) {
83         visitor.visit(this);
84     }
85     
86     @Override
87     public ListQualifier accept(ListQualifierTransformer transformer) {
88         return transformer.transform(this);
89     }
90 }