From: Miro Richard Eklund Date: Wed, 9 Aug 2017 06:53:38 +0000 (+0300) Subject: Merge branch 'master' into private/eclipse-4.7 X-Git-Tag: v1.31.0~264 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=6f11a60dee43d620d500c0cf5af34a1d91c80a8b;hp=3014268adf5c811d56e0bdfa963f233c8fb5e0df Merge branch 'master' into private/eclipse-4.7 Resolved Conflicts: releng/org.simantics.sdk.build.targetdefinition/simantics.target refs #7358 Change-Id: Idefea4e4c60de59664904bdd0a2a0a517af8db4c --- diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java index 450ad0618..c69c7bea6 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java @@ -20,9 +20,13 @@ import org.simantics.acorn.lru.ClusterStreamChunk; import org.simantics.acorn.lru.ClusterUpdateOperation; import org.simantics.db.service.ClusterUID; import org.simantics.utils.logging.TimeLogger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MainProgram implements Runnable, Closeable { + private static final Logger LOGGER = LoggerFactory.getLogger(MainProgram.class); + private static final int CLUSTER_THREADS = 4; private static final int CHUNK_CACHE_SIZE = 100; @@ -260,14 +264,32 @@ public class MainProgram implements Runnable, Closeable { public Exception runIdle(MainProgramRunnable runnable) { try { - mutex.acquire(); - runnable.run(); - return null; - } catch (Exception e) { - return e; + long startTime = System.currentTimeMillis(); + while (true) { + boolean hasMutex = false; + try { + synchronized (MainProgram.this) { + if (hasMutex = mutex.tryAcquire()) { + if (operations.isEmpty()) { + runnable.run(); + return null; + } + } + } + long endTime = System.currentTimeMillis(); + if ((endTime - startTime) > 100) { + startTime = endTime; + LOGGER.info("MainProgram.runIdle() retry mutex acquire!"); + } + } catch (Exception e) { + return e; + } finally { + if (hasMutex) + mutex.release(); + } + } } finally { runnable.done(); - mutex.release(); } } @@ -297,7 +319,7 @@ public class MainProgram implements Runnable, Closeable { ClusterStreamChunk last = operations.isEmpty() ? null : operations.getLast(); if (!alive) { - System.err.println("Trying to commit operation after MainProgram is closed! Operation is " + last); + LOGGER.error("Trying to commit operation after MainProgram is closed! Operation is " + last); // return; } if(last != null) last.commit(); @@ -306,7 +328,7 @@ public class MainProgram implements Runnable, Closeable { public synchronized void schedule(ClusterUpdateOperation operation) throws IllegalAcornStateException { if (!alive) { - System.err.println("Trying to schedule operation after MainProgram is closed! Operation is " + operation); + LOGGER.error("Trying to schedule operation after MainProgram is closed! Operation is " + operation); // return; } clusters.streamLRU.acquireMutex(); diff --git a/bundles/org.simantics.browsing.ui.model/adapters.xml b/bundles/org.simantics.browsing.ui.model/adapters.xml index 50b343479..4276f3feb 100644 --- a/bundles/org.simantics.browsing.ui.model/adapters.xml +++ b/bundles/org.simantics.browsing.ui.model/adapters.xml @@ -181,6 +181,14 @@ class="org.simantics.browsing.ui.model.tests.FailTest" constructor="get"> + + + + diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/HasURITest.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/HasURITest.java new file mode 100644 index 000000000..344362588 --- /dev/null +++ b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/HasURITest.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2017 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.browsing.ui.model.tests; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.InvalidVariableException; +import org.simantics.db.layer0.variable.Variable; + +/** + * @author Tuukka Lehtonen + * @since 1.30.0 + */ +public enum HasURITest implements Test { + INSTANCE; + + public static HasURITest get() { + return INSTANCE; + } + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class) || contentType.equals(Variable.class); + } + + @Override + public boolean test(ReadGraph graph, Object content) throws DatabaseException { + if (content instanceof Resource) { + return graph.getPossibleURI((Resource) content) != null; + } else if (content instanceof Variable) { + try { + Variable v = (Variable) content; + return v.getURI(graph) != null; + } catch (InvalidVariableException e) { + return false; + } + } + return false; + } + +} diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/InDevelopmentModeTest.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/InDevelopmentModeTest.java new file mode 100644 index 000000000..fa85e256b --- /dev/null +++ b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/InDevelopmentModeTest.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2017 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.browsing.ui.model.tests; + +import org.eclipse.core.runtime.Platform; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; + +/** + * @author Tuukka Lehtonen + * @since 1.30.0 + */ +public enum InDevelopmentModeTest implements Test { + INSTANCE; + + public static InDevelopmentModeTest get() { + return INSTANCE; + } + + @Override + public boolean isCompatible(Class contentType) { + return true; + } + + @Override + public boolean test(ReadGraph graph, Object content) throws DatabaseException { + return Platform.inDevelopmentMode(); + } + +} diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tooltips/DescriptionTooltipRule.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tooltips/DescriptionTooltipRule.java index 7bef8e22c..a9ebb9dfc 100644 --- a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tooltips/DescriptionTooltipRule.java +++ b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tooltips/DescriptionTooltipRule.java @@ -18,9 +18,9 @@ import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; public class DescriptionTooltipRule implements TooltipRule { - + public static final DescriptionTooltipRule INSTANCE = new DescriptionTooltipRule(); - + public DescriptionTooltipRule() { } @@ -58,28 +58,26 @@ public class DescriptionTooltipRule implements TooltipRule { public boolean isCompatible(Class contentType) { return (contentType == Resource.class || contentType == Variable.class); } - + private static String getToolTipContent(ReadGraph graph, NodeContext nodeContext) throws DatabaseException { Object input = nodeContext.getConstant(BuiltinKeys.INPUT); - String content = null; if (input instanceof Variable) { Variable var = (Variable) input; - Resource res = var.getPredicateResource(graph); - Layer0 L0 = Layer0.getInstance(graph); - String description = graph.getPossibleRelatedValue2(res, L0.HasDescription); - return description; + Resource res = var.getPossiblePredicateResource(graph); + if (res != null) { + Layer0 L0 = Layer0.getInstance(graph); + return graph.getPossibleRelatedValue2(res, L0.HasDescription); + } } else if (input instanceof Resource) { Resource res = (Resource) input; - Layer0 L0 = Layer0.getInstance(graph); - String description = graph.getPossibleRelatedValue2(res, L0.HasDescription); - return description; + return graph.getPossibleRelatedValue2(res, L0.HasDescription); } - return content; + return null; } @Override - public boolean shouldCreateToolTip(ReadGraph graph , NodeContext context, Map auxiliary) throws DatabaseException { + public boolean shouldCreateToolTip(ReadGraph graph, NodeContext context, Map auxiliary) throws DatabaseException { String content = getToolTipContent(graph, context); if (content == null || content.isEmpty()) return false; diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java index 8be698cf1..15910147a 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java @@ -21,12 +21,13 @@ public class ListUtils { WriteGraph g, Layer0 L0, Resource list, Resource before, Resource after, Iterable elements) throws DatabaseException { + Resource elementPredicate = getElementPredicate(g, list); for(Resource item : elements) { Resource cur = g.newResource(); g.claim(cur, L0.InstanceOf, null, L0.List_Entry); g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list); g.claim(before, L0.List_Next, L0.List_Previous, cur); - g.claim(cur, L0.List_Element, item); + g.claim(cur, elementPredicate, item); before = cur; } g.claim(before, L0.List_Next, L0.List_Previous, after); @@ -36,12 +37,13 @@ public class ListUtils { WriteGraph g, Layer0 L0, Resource list, Resource before, Resource after, Resource[] elements) throws DatabaseException { + Resource elementPredicate = getElementPredicate(g, list); for(Resource item : elements) { Resource cur = g.newResource(); g.claim(cur, L0.InstanceOf, null, L0.List_Entry); g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list); g.claim(before, L0.List_Next, L0.List_Previous, cur); - g.claim(cur, L0.List_Element, item); + g.claim(cur, elementPredicate, item); before = cur; } g.claim(before, L0.List_Next, L0.List_Previous, after); @@ -97,15 +99,20 @@ public class ListUtils { } public static void createExisting(WriteOnlyGraph g, Resource list, Iterable elements) throws DatabaseException { + createExisting(g, list, false, elements); + } + + public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable elements) throws DatabaseException { Layer0 L0 = g.getService(Layer0.class); Resource before = list; + Resource elementPredicate = withInverses ? L0.List_ElementWithInverse : L0.List_Element; for(Resource item : elements) { Resource cur = g.newResource(); g.claim(cur, L0.InstanceOf, null, L0.List_Entry); g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list); g.claim(before, L0.List_Next, L0.List_Previous, cur); - g.claim(cur, L0.List_Element, null, item); + g.claim(cur, elementPredicate, null, item); before = cur; } g.claim(before, L0.List_Next, L0.List_Previous, list); @@ -142,8 +149,9 @@ public class ListUtils { Resource node = getNode(g, list, element); if(node != null) { + Resource elementPredicate = getElementPredicate(g, list); g.deny(node, L0.List_Element); - g.claim(node, L0.List_Element, replacement); + g.claim(node, elementPredicate, replacement); return true; } else { return false; @@ -191,7 +199,7 @@ public class ListUtils { while(!cur.equals(list)) { Resource el = g.getPossibleObject(cur, L0.List_Element); Resource next = g.getSingleObject(cur, L0.List_Next); - if(element.equals(el)) { + if(element.equals(el)) { g.deny(cur); g.claim(prev, L0.List_Next, next); return true; @@ -213,7 +221,7 @@ public class ListUtils { while(!cur.equals(list)) { Resource el = g.getPossibleObject(cur, L0.List_Element); Resource next = g.getSingleObject(cur, L0.List_Next); - if(elements.contains(el)) { + if(elements.contains(el)) { g.deny(cur); g.claim(prev, L0.List_Next, next); removed = true; @@ -264,7 +272,7 @@ public class ListUtils { Resource prev = g.getSingleObject(node, L0.List_Previous); if(list.equals(prev)) return false; - swap(g, node, prev); + swap(g, list, node, prev); return true; } @@ -276,11 +284,11 @@ public class ListUtils { Resource next = g.getSingleObject(node, L0.List_Next); if(list.equals(next)) return false; - swap(g, node, next); + swap(g, list, node, next); return true; } - private static void swap(WriteGraph g, Resource a, Resource b) throws DatabaseException { + private static void swap(WriteGraph g, Resource list, Resource a, Resource b) throws DatabaseException { Layer0 L0 = Layer0.getInstance(g); Resource ea = g.getPossibleObject(a, L0.List_Element); Resource eb = g.getPossibleObject(b, L0.List_Element); @@ -288,11 +296,26 @@ public class ListUtils { g.deny(a, L0.List_Element); g.deny(b, L0.List_Element); + Resource elementPredicate = getElementPredicate(g, list); + if(eb != null) - g.claim(a, L0.List_Element, eb); + g.claim(a, elementPredicate, eb); if(ea != null) - g.claim(b, L0.List_Element, ea); + g.claim(b, elementPredicate, ea); } + public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate); + if(predicate != null) return predicate; + return g.isInstanceOf(list, L0.ListWithInverses) ? + L0.List_ElementWithInverse : L0.List_Element; + } + + public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + return g.getSingleObject(element, L0.IsOwnedBy); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java index 07d385235..188917994 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java @@ -32,8 +32,8 @@ public final class ForEachObjectContextProcedure implements AsyncContextMulti } @Override - public void finished(AsyncReadGraph graph) { - user.finished(graph); + public void finished(AsyncReadGraph graph, C context) { + user.finished(graph, context); } @Override diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java index 488545c5f..2347fa99e 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java @@ -70,58 +70,64 @@ public class EntityInstances implements Instances { public List perform(ReadGraph graph) throws DatabaseException { Resource type = parameter2; - - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - String typeName = graph.getRelatedValue(type, L0.HasName); - if (typeName.isEmpty()) + String filter = constructLuceneQuery(graph, type, parameter3); + if (filter == null) return Collections.emptyList(); @SuppressWarnings({ "unchecked", "rawtypes" }) - Function dependencyResources = graph.syncRequest(new Adapter(L0X.DependencyResources, Function.class), TransientCacheListener.instance()); - - StringBuilder filtersb = new StringBuilder(); - filtersb.append("Types:*").append( IndexQueries.escape( typeName, true ) ); - if (parameter3.length() > 0) - filtersb.append(" AND ").append( parameter3 ); - String filter = filtersb.toString(); + Function dependencyResources = graph.syncRequest(new Adapter(Layer0X.getInstance(graph).DependencyResources, Function.class), TransientCacheListener.instance()); if (TRACE_QUERIES) { System.out.println("EntityInstances.QueryIndex: finding " + filter + " from index " + graph.getPossibleURI(parameter)); //new Exception("EntityInstances: finding " + filter + " from index " + graph.getPossibleURI(parameter)).printStackTrace(); } - + @SuppressWarnings("unchecked") - List results = (List)dependencyResources.apply(graph, parameter, filter); + List results = (List)dependencyResources.apply(graph, parameter, filter); if (results == null || results.isEmpty()) return Collections.emptyList(); if (TRACE_QUERIES) System.out.println(" EntityInstances.QueryIndex: got " + results.size() + " results"); -// // TreeSet to keep the results in deterministic order. -// Set resultSet = new TreeSet(); -// for (Map entry : results) { -// Resource res = (Resource)entry.get("Resource"); -// if (res != null && !resultSet.contains(res)) -// resultSet.add(res); -// } + // Optimize single result case. + if (results.size() == 1) { + Resource singleResult = results.get(0); + List result = graph.isInstanceOf(singleResult, type) ? results : Collections.emptyList(); + if (TRACE_QUERIES) + System.out.println(" EntityInstances.QueryIndex: got " + results.size() + " unique type-matching results"); + return result; + } CollectionSupport coll = graph.getService(CollectionSupport.class); - List result = coll.createList(); - - for (Resource res : Layer0Utils.sortByCluster(graph, results)) { + List result = coll.createList(results.size()); + for (Resource res : Layer0Utils.sortByCluster(graph, results)) if (graph.isInstanceOf(res, type)) result.add(res); - } if (TRACE_QUERIES) System.out.println(" EntityInstances.QueryIndex: got " + results.size() + " unique type-matching results"); - + return result; + } + private String constructLuceneQuery(ReadGraph graph, Resource type, String filter) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + StringBuilder sb = new StringBuilder(); + if (!L0.Entity.equals(type)) { + String typeName = graph.getPossibleRelatedValue(type, L0.HasName, Bindings.STRING); + if (typeName == null || typeName.isEmpty()) + return null; + sb.append("Types:*").append( IndexQueries.escape( typeName, true ) ); + } + if (filter.length() > 0) { + if (sb.length() > 0) + sb.append(" AND "); + sb.append(filter); + } + return sb.toString(); } - + @Override public String toString() { return "QueryIndex " + parameter + " " + parameter2 + " " + parameter3; diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java index 9ec12047c..4162f9163 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java @@ -145,7 +145,7 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic } @Override - public void finished(AsyncReadGraph graph) { + public void finished(AsyncReadGraph graph, Resource parent) { } @Override diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java index d910f13ff..a2e64868f 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java @@ -2,6 +2,7 @@ package org.simantics.db.layer0.util; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -17,22 +18,25 @@ import org.simantics.db.procedure.AsyncContextMultiProcedure; import org.simantics.db.procedure.Procedure; import org.simantics.db.service.DirectQuerySupport; import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.Pair; class ConsistsOfProcess { final List result; + final Set childrenWithNoName; final AsyncContextMultiProcedure structure; final AsyncContextMultiProcedure names; - public static List walk(ReadGraph graph, ResourceMap status, Collection resources, Set exclusions, boolean ignoreVirtual) throws DatabaseException { + public static Pair,Set> walk(ReadGraph graph, ResourceMap status, Collection resources, Set exclusions, boolean ignoreVirtual) throws DatabaseException { ConsistsOfProcess process = new ConsistsOfProcess(graph, status, resources, exclusions, ignoreVirtual); - return process.result; + return Pair.make(process.result, process.childrenWithNoName); } static class InternalEntry { public InternalEntry parent; public Resource resource; public String name; + public boolean valid = true; InternalEntry(InternalEntry parent, Resource resource, String name) { this.parent = parent; this.resource = resource; @@ -46,7 +50,7 @@ class ConsistsOfProcess { final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class); result = new ArrayList(); - + childrenWithNoName = new HashSet<>(); names = dqs.compileForEachObject(graph, L0.HasName, new AsyncContextMultiProcedure() { @Override @@ -58,8 +62,16 @@ class ConsistsOfProcess { graph.forPossibleValue(nameResource, new Procedure() { @Override - public void execute(String result) { - entry.name = result; + public void execute(String name) { + if(!entry.valid) return; + + if(name == null) { + entry.valid = false; + } else if (entry.name != null) { + entry.valid = false; + } else { + entry.name = name; + } } @Override @@ -76,9 +88,19 @@ class ConsistsOfProcess { } @Override - public void finished(AsyncReadGraph graph) { + public void finished(AsyncReadGraph graph, InternalEntry entry) { + if(entry.valid) { + if(entry.name != null) { + result.add(entry); + } else { + // This one did not have a name - not a valid internal + childrenWithNoName.add(entry.resource); + } + } else { + // Something wrong has happened. Do not treat as valid internal + childrenWithNoName.add(entry.resource); + } } - }); structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncContextMultiProcedure() { @@ -90,16 +112,14 @@ class ConsistsOfProcess { if(!ignoreVirtual || child.isPersistent()) { InternalEntry entry = new InternalEntry(parent, child, null); - if(result.add(entry)) { - dqs.forEachObjectCompiled(graph, child, entry, structure); - dqs.forEachObjectCompiled(graph, child, entry, names); - } + dqs.forEachObjectCompiled(graph, child, entry, structure); + dqs.forEachObjectCompiled(graph, child, entry, names); } } @Override - public void finished(AsyncReadGraph graph) { + public void finished(AsyncReadGraph graph, InternalEntry parent) { } @Override diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/DomainProcessor3.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/DomainProcessor3.java index bd67680db..7a0a5f06b 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/DomainProcessor3.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/DomainProcessor3.java @@ -34,6 +34,7 @@ import org.simantics.db.service.TransferableGraphSupport; import org.simantics.graph.db.TransferableGraphSource; import org.simantics.layer0.Layer0; import org.simantics.scl.runtime.function.Function1; +import org.simantics.utils.datastructures.Pair; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TIntIntHashMap; @@ -504,7 +505,8 @@ public class DomainProcessor3 { this.datatypeBinding = Bindings.getBindingUnchecked(Datatype.class); this.datatypeSerializer = graph.getService(Databoard.class).getSerializerUnchecked(this.datatypeBinding); - state.internalEntries = ConsistsOfProcess.walk(graph, status, fringe, exclusions, ignoreVirtual); + Pair,Set> pair = ConsistsOfProcess.walk(graph, status, fringe, exclusions, ignoreVirtual); + state.internalEntries = pair.first; for(InternalEntry entry : state.internalEntries) { Resource r = entry.resource; @@ -518,6 +520,12 @@ public class DomainProcessor3 { } } + for(Resource unnamedChild : pair.second) { + if (status.put(unnamedChild, ExtentStatus.INTERNAL) == null) { + fringe.add(unnamedChild); + } + } + if (state.monitor.isCanceled()) throw new CancelTransactionException(); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSource.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSource.java index f0a0893eb..1d3cf61f5 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSource.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSource.java @@ -416,8 +416,12 @@ public class ModelTransferableGraphSource implements TransferableGraphSource { if(state.internalEntries != null) { for(InternalEntry ie : state.internalEntries) { - if(ie.parent != null && ie.name != null) { - procedure.execute(resolveInternal(graph, support, ie, internalMap)); + if(ie.parent != null) { + if(ie.name != null) { + procedure.execute(resolveInternal(graph, support, ie, internalMap)); + } else { + // In this case there is a child that has no HasName => this should be treated as a blank + } } else { throw new DatabaseException("Invalid internal entry " + ie); } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Subgraphs.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Subgraphs.java index c7e697e62..518efc882 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Subgraphs.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Subgraphs.java @@ -991,7 +991,8 @@ public class Subgraphs { * � All o are internal * � All stm are included */ - List entries = ConsistsOfProcess.walk(graph, null, fringe, exclusions, true); + Pair,Set> pair = ConsistsOfProcess.walk(graph, null, fringe, exclusions, true); + List entries = pair.first; for(InternalEntry entry : entries) { Resource r = entry.resource; if (status.put(r, ExtentStatus.INTERNAL) == null) { @@ -1003,6 +1004,12 @@ public class Subgraphs { } } + for(Resource unnamedChild : pair.second) { + if (status.put(unnamedChild, ExtentStatus.INTERNAL) == null) { + fringe.add(unnamedChild); + } + } + /* * This loop resolves the transitive closure of all p < IsRelatedTo such that p does not contain the SharedRange tag. * Such resources are guaranteed to be internal. diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TGRepresentationUtils.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TGRepresentationUtils.java index ffa399743..0bd71af86 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TGRepresentationUtils.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TGRepresentationUtils.java @@ -14,6 +14,7 @@ package org.simantics.db.layer0.util; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import org.simantics.datatypes.literal.GUID; import org.simantics.db.ReadGraph; @@ -26,6 +27,7 @@ import org.simantics.db.layer0.util.ConsistsOfProcess.InternalEntry; import org.simantics.db.layer0.util.DomainProcessor3.ExclusionDecision; import org.simantics.layer0.Layer0; import org.simantics.scl.runtime.function.Function1; +import org.simantics.utils.datastructures.Pair; /** * @author Antti Villberg @@ -63,7 +65,8 @@ public class TGRepresentationUtils { return new GUIDExclusionFunction(graph); // The root is OK - check everything beneath - List entries = ConsistsOfProcess.walk(graph, null, Collections.singleton(r), Collections.emptySet(), true); + Pair,Set> pair = ConsistsOfProcess.walk(graph, null, Collections.singleton(r), Collections.emptySet(), true); + List entries = pair.first; for(InternalEntry entry : entries) { if(findByIdentifier(graph, targetRoot, entry.resource)) return new GUIDExclusionFunction(graph); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java index 3d527e039..d9366b132 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java @@ -302,7 +302,7 @@ public abstract class AbstractVariable implements Variable { if(Variables.TYPE.equals(key)) return getTypeVariable(); else if(Variables.URI.equals(key)) return getURIVariable(); - return variable; + return null; } } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java index daae9b9c3..a5f22c83c 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java @@ -407,8 +407,8 @@ public class RVI extends Bean { } } } - if (str.indexOf(":", pos+1) > -1) { - String x = str.substring(pos+1, end); + if (str.indexOf(":", pos) > -1) { + String x = str.substring(pos, end); if (!x.isEmpty()) { String[] parts = x.split(":"); if (parts.length == 3) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java index 355764d17..40b2530f2 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java @@ -1139,11 +1139,14 @@ public final class ClusterTable implements IClusterTable { if(exist != null) return exist; ClusterI cluster = getClusterByResourceKey(id); - boolean result = cluster == null ? false : cluster.getImmutable(); - - markImmutable(cluster, result); - return result; - + if(cluster == null) { + return false; + } else { + boolean result = cluster.getImmutable(); + markImmutable(cluster, result); + return result; + } + } public void markImmutable(ClusterI cluster, boolean value) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java index 5f9a8993e..37c89ff5f 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java @@ -633,6 +633,11 @@ public class CollectionSupportImpl implements CollectionSupport { this.backend = new TIntArrayList(); } + ResourceList(SessionImplSocket session, int capacity) { + this.session = session; + this.backend = new TIntArrayList(capacity); + } + ResourceList(SessionImplSocket session, Collection rs) { this.session = session; this.backend = new TIntArrayList(rs.size()); @@ -853,6 +858,11 @@ public class CollectionSupportImpl implements CollectionSupport { return new ResourceList(session); } + @Override + public List createList(int capacity) { + return new ResourceList(session, capacity); + } + static final class StatementList implements Collection { final private SessionImplSocket session; diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java index ea1c779fa..1d3563fc1 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java @@ -306,7 +306,7 @@ public class QuerySupportImpl implements QuerySupport { } } - procedure.finished(graph); + procedure.finished(graph, context); // graph.dec(); return; diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java index 69450de7c..c0ead5d07 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java @@ -304,7 +304,7 @@ public class IntHash extends IntHashTrait { } - procedure.finished(graph); + procedure.finished(graph, context); // graph.dec(); assert(size == count); diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java index 42ca6b018..da3b7903e 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java @@ -167,7 +167,7 @@ public final class ObjectTable extends Table { if (ClusterTraits.statementIndexIsDirect(objectIndex)) { int key = modifier.execute(objectIndex); procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key)); - procedure.finished(graph); + procedure.finished(graph, context); // graph.dec(); return; } diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java index 23d15dcfd..90519a36c 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java @@ -477,7 +477,7 @@ public final class ResourceElementSmall { if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { int completeRef = getCompleteObjectRef(table, index); if (0 == completeRef) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // no objects for given complete type } @@ -496,19 +496,19 @@ public final class ResourceElementSmall { } else { // One complete type element. CompleteRef is resource reference. ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); if (pCompleteType != rCompleteType) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // Complete predicate does not match. } procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef))); } - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished } short p1 = getStm1Predicate(table, index); if (0 == p1) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished, no statements } @@ -525,7 +525,7 @@ public final class ResourceElementSmall { } short p2 = getStm2Predicate(table, index); if (0 == p2 || pRef != p2) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished, one statements } @@ -539,7 +539,7 @@ public final class ResourceElementSmall { // return true; // loop broken by procedure // return false; // loop finished procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2))); - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); } diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java index 84090af41..e997b7318 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java @@ -514,7 +514,7 @@ final class ResourceElement { if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { int completeRef = getCompleteObjectRef(table, index); if (0 == completeRef) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // no objects for given complete type } @@ -543,14 +543,14 @@ final class ResourceElement { ForeachObject t = new ForeachObject(); // CompleteRef is complete object set index. ct.foreachComplete(completeRef, t, null, support, modifier); - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished } // one complete type element ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef); if (pCompleteType != completeType) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; } @@ -562,7 +562,7 @@ final class ResourceElement { int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex); procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(externalRef))); } - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished } @@ -570,7 +570,7 @@ final class ResourceElement { long l = table[i]; int p1 = (int) (l >>> 32); if (0 == p1) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished, no statements } @@ -588,13 +588,13 @@ final class ResourceElement { long l2 = table[++i]; int p2 = (int) (l2 >>> 32); if (pRef != p2) { - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); return; // loop finished, one statements } int o2 = (int)l2; procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2))); - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); } diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java index df5920c47..2c57f3627 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java @@ -184,7 +184,7 @@ final class TableIntArraySet { } - procedure.finished(graph); + procedure.finished(graph, context); // graph.state.dec(0); } diff --git a/bundles/org.simantics.db/src/org/simantics/db/procedure/AsyncContextMultiProcedure.java b/bundles/org.simantics.db/src/org/simantics/db/procedure/AsyncContextMultiProcedure.java index 875ee37ab..c393d32da 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/procedure/AsyncContextMultiProcedure.java +++ b/bundles/org.simantics.db/src/org/simantics/db/procedure/AsyncContextMultiProcedure.java @@ -43,7 +43,7 @@ public interface AsyncContextMultiProcedure { * * @param graph asynchronous graph access */ - void finished(AsyncReadGraph graph); + void finished(AsyncReadGraph graph, Context context); /** * If an error occurs in the processing of the database request that diff --git a/bundles/org.simantics.db/src/org/simantics/db/service/CollectionSupport.java b/bundles/org.simantics.db/src/org/simantics/db/service/CollectionSupport.java index aa522203d..d5cebc864 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/service/CollectionSupport.java +++ b/bundles/org.simantics.db/src/org/simantics/db/service/CollectionSupport.java @@ -38,6 +38,7 @@ public interface CollectionSupport { Set createSet(); Set createSet(int capacity); List createList(); + List createList(int capacity); List asSortedList(Collection set); void sort(List list); Collection createStatementList(); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/NodeRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/NodeRequest.java index a6f2e0a77..198b4b341 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/NodeRequest.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/NodeRequest.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.simantics.diagram.adapter; +import java.util.List; + import org.simantics.db.AsyncReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.primitiverequest.Adapter; @@ -20,6 +22,7 @@ import org.simantics.db.procedure.Listener; import org.simantics.diagram.synchronization.ErrorHandler; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.SubstituteElementClass; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.IElement; import org.slf4j.Logger; @@ -110,8 +113,12 @@ public class NodeRequest extends BaseRequest2 { } @Override - public void execute(AsyncReadGraph graph, final ElementClass clazz) { - + public void execute(AsyncReadGraph graph, ElementClass mutableClazz) { + List substitutes = diagram.getDiagramClass().getItemsByClass(SubstituteElementClass.class); + for (SubstituteElementClass subs : substitutes) { + mutableClazz = subs.substitute(diagram, mutableClazz); + } + final ElementClass clazz = mutableClazz; graph.asyncRequest(new SpawnRequest(canvas, clazz, data), new TransientCacheAsyncListener() { @Override diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/layer/GraphLayerManager.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/layer/GraphLayerManager.java index 41947ef99..e92ce1b41 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/layer/GraphLayerManager.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/layer/GraphLayerManager.java @@ -433,8 +433,10 @@ public class GraphLayerManager { graph.forHasStatement(element, gl.getVisible(), element, new AsyncProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, Boolean result) { - synchronized (visible) { - visible.add(l); + if (result) { + synchronized (visible) { + visible.add(l); + } } if (DEBUG_LAYERS) System.out.println(" Visible on layer '" + gl.getName() + "'"); @@ -452,8 +454,10 @@ public class GraphLayerManager { graph.forHasStatement(element, gl.getFocusable(), element, new AsyncProcedureAdapter() { @Override public void execute(AsyncReadGraph graph, Boolean result) { - synchronized (focusable) { - focusable.add(l); + if (result) { + synchronized (focusable) { + focusable.add(l); + } } if (DEBUG_LAYERS) System.out.println(" Focusable on layer '" + gl.getName() + "'"); diff --git a/bundles/org.simantics.document.base.ontology/graph/ConnectionPoints.pgraph b/bundles/org.simantics.document.base.ontology/graph/ConnectionPoints.pgraph index cb396fc84..655df5666 100644 --- a/bundles/org.simantics.document.base.ontology/graph/ConnectionPoints.pgraph +++ b/bundles/org.simantics.document.base.ontology/graph/ConnectionPoints.pgraph @@ -189,14 +189,14 @@ defCommandConnectionPoint : L0.Template RELATIONS.commandExecutorRelation -- RELATIONS.commandExecutorRelation.propagate --> "Boolean" >> from = context.getData(); for (Map.Entry>> entry : from.entrySet()) { + String key = entry.getKey(); + Object existing = getValue(key); + Object newValue = context.getValue(key); + // Do not merge duplicates! + if (newValue != null && newValue.equals(existing)) + continue; List> rows = ensureRowsAvailable(entry.getKey()); rows.addAll(entry.getValue()); } diff --git a/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/ITreeTableCell.java b/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/ITreeTableCell.java index 9bf10fb3a..1849273d1 100644 --- a/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/ITreeTableCell.java +++ b/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/ITreeTableCell.java @@ -1,11 +1,9 @@ package org.simantics.document.server.io; public interface ITreeTableCell extends ITableCell { - - int getParent(); - - Object getData(); - boolean isEditable(); + int getParent(); + Object getData(); + boolean isEditable(); } diff --git a/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/JSONObjectUtils.java b/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/JSONObjectUtils.java index 558ee3204..004166dc0 100644 --- a/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/JSONObjectUtils.java +++ b/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/JSONObjectUtils.java @@ -314,6 +314,26 @@ public class JSONObjectUtils { return Collections.emptyList(); } + @SuppressWarnings("unchecked") + public static Collection getTreeTableCells(IJSONObject object) { + try { + Object tableCells = object.getValue("tableCells"); + if (tableCells instanceof String) { + String tableCellsS = (String) tableCells; + if (tableCellsS.length() == 0) + return Collections.emptyList(); + } + if (tableCells != null) { + return (List) tableCells; + } else { + return Collections.emptyList(); + } + } catch (ClassCastException e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } + public static Collection getFiles(IJSONObject object) { try { @SuppressWarnings("unchecked") diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/DocumentServerUtils.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/DocumentServerUtils.java index 4821bbd1c..5e1f5cc30 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/DocumentServerUtils.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/DocumentServerUtils.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -324,8 +325,24 @@ public class DocumentServerUtils { for(Variable attrib : statics) { String name = attrib.getName(graph); try { - Object value = DocumentServerUtils.getValue(graph, attrib); - object.addJSONField(name, value); + if (name.equals(NodeRequest.PROPERTY_VALUE_EXCEPTIONS)) { + @SuppressWarnings("unchecked") + Map exceptions = (Map)DocumentServerUtils.getValue(graph, attrib); + + List errorList = object.getJSONField(NodeRequest.ERRORS); + if(errorList == null) + errorList = new ArrayList(); + + for (Map.Entry entry : exceptions.entrySet()) { + String errorMessage = NodeRequestUtils.formatErrorMessage(entry.getKey(), entry.getValue()); + errorList.add(errorMessage); + } + object.addJSONField(NodeRequest.ERRORS, errorList); + + } else { + Object value = DocumentServerUtils.getValue(graph, attrib); + object.addJSONField(name, value); + } } catch (Throwable t) { List errorList = object.getJSONField(NodeRequest.ERRORS); if(errorList == null) diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java index 6ccffbe97..13444fdba 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java @@ -62,6 +62,7 @@ import org.simantics.document.server.io.CommandContextImpl; import org.simantics.document.server.io.CommandContextMutable; import org.simantics.document.server.io.CommandResult; import org.simantics.document.server.io.IConsole; +import org.simantics.document.server.request.NodeRequest; import org.simantics.document.server.request.ServerSCLHandlerValueRequest; import org.simantics.document.server.request.ServerSCLValueRequest; import org.simantics.document.server.serverResponse.ServerResponse; @@ -117,7 +118,35 @@ public class Functions { @SCLValue(type = "VariableMap") public static VariableMap primitiveProperties = new VariableMapImpl() { + private void storePropertyValueAndExceptions(ReadGraph graph, Variable parent, String name, Variable property, Map map) { + try { + Object value = property.getValue(graph); + map.put(name, new ConstantPropertyVariable(parent, name, value, null)); + } catch (DatabaseException e) { + Variable propertyExceptions = map.get(NodeRequest.PROPERTY_VALUE_EXCEPTIONS); + Map exceptionMap; + if (propertyExceptions == null) { + exceptionMap = new TreeMap(); + propertyExceptions = new ConstantPropertyVariable(parent, NodeRequest.PROPERTY_VALUE_EXCEPTIONS, exceptionMap, null); + map.put(NodeRequest.PROPERTY_VALUE_EXCEPTIONS, propertyExceptions); + } else { + try { + exceptionMap = propertyExceptions.getValue(graph); + } catch (DatabaseException e1) { + Logger.defaultLogError(e1); + return; + } + } + String label = name; + try { + label = property.getLabel(graph); + } catch (DatabaseException e2) { + } + exceptionMap.put(label, e); + } + } + @Override public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { return All.getStandardPropertyDomainPropertyVariableFromValue(graph, context, name); @@ -126,6 +155,8 @@ public class Functions { @Override public Map getVariables(final ReadGraph graph, Variable context, Map map) throws DatabaseException { + if(map == null) map = new HashMap(); + Variable parent = context.getParent(graph); DocumentationResource DOC = DocumentationResource.getInstance(graph); @@ -136,9 +167,8 @@ public class Functions { for(Variable property : procedural.getProperties(graph/*, DocumentationResource.URIs.Document_AttributeRelation*/)) { if(property instanceof StandardAssertedGraphPropertyVariable) { StandardAssertedGraphPropertyVariable ass = (StandardAssertedGraphPropertyVariable)property; - if("datadefinitions".equals(ass.property.name) || "commands".equals(ass.property.name) || "pollingFunction".equals(ass.property.name)) { - Object value = property.getPossibleValue(graph); - if(value != null) map.put(ass.property.name, new ConstantPropertyVariable(parent, ass.property.name, value, null)); + if("dataDefinitions".equals(ass.property.name) || "commands".equals(ass.property.name) || "pollingFunction".equals(ass.property.name)) { + storePropertyValueAndExceptions(graph, parent, ass.property.name, property, map); } continue; } @@ -146,56 +176,47 @@ public class Functions { if(predicate != null) { PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate)); if(info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) { - Variable prop = parent.getProperty(graph, predicate); - Object value = prop.getValue(graph); - if(map == null) map = new HashMap(); - map.put(info.name, new ConstantPropertyVariable(parent, info.name, value, null)); + Variable prop = parent.getProperty(graph, predicate); + storePropertyValueAndExceptions(graph, parent, info.name, prop, map); } } } } else { + Resource parentRes = parent.getRepresents(graph); + { + Variable prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_commands); + storePropertyValueAndExceptions(graph, parent, "commands", prop, map); + } + + if (graph.getPossibleObject(parentRes, DOC.Properties_dataDefinitions) != null) { + Variable prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_dataDefinitions); + storePropertyValueAndExceptions(graph, parent, "dataDefinitions", prop, map); + } + DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class); PrimitivePropertyStatementsProcedure foo = new PrimitivePropertyStatementsProcedure(); - dqs.forEachDirectPersistentStatement(graph, parent.getRepresents(graph), foo); + dqs.forEachDirectPersistentStatement(graph, parentRes, foo); for(Statement stm : foo.result) { Resource predicate = stm.getPredicate(); PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate)); if(info.isHasProperty && info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) { - if(map == null) map = new HashMap(); - Variable prop = new StandardGraphPropertyVariable(graph, parent, predicate); - Object value = prop.getValue(graph); - map.put(info.name, new ConstantPropertyVariable(parent, info.name, value, null)); + Variable prop = new StandardGraphPropertyVariable(graph, parent, predicate); + storePropertyValueAndExceptions(graph, parent, info.name, prop, map); } else { Resource definition = graph.getPossibleObject(predicate, DOC.Document_definesAttributeRelation); if(definition != null) { - if(map == null) map = new HashMap(); - try { - PropertyInfo info2 = graph.syncRequest(new PropertyInfoRequest(definition)); - Variable prop = new StandardGraphPropertyVariable(graph, parent, definition); - map.put(info2.name, new PrimitiveValueVariable(parent, info2.name, prop)); - } catch (DatabaseException e) { - Logger.defaultLogError(e); - } + PropertyInfo info2 = graph.syncRequest(new PropertyInfoRequest(definition)); + Variable prop = new StandardGraphPropertyVariable(graph, parent, definition); + map.put(info2.name, new PrimitiveValueVariable(parent, info2.name, prop)); } } } - - Variable prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_dataDefinitions); - Object value = prop.getPossibleValue(graph); - if(value != null) map.put("dataDefinitions", new ConstantPropertyVariable(parent, "dataDefinitions", value, null)); - prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_commands); - value = prop.getPossibleValue(graph); - if(value != null) map.put("commands", new ConstantPropertyVariable(parent, "commands", value, null)); - } - - if(map == null) return Collections.emptyMap(); - return map; } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java index 98bd0fb82..d9418db99 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java @@ -16,7 +16,8 @@ import org.simantics.utils.datastructures.Pair; public class NodeRequest extends VariableRead { public static final String ERRORS = "Errors"; - + public static final String PROPERTY_VALUE_EXCEPTIONS = "_PropertyValueExceptions"; + public NodeRequest(Variable node) { super(node); } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequestUtils.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequestUtils.java index ed0c54c96..00eb2a492 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequestUtils.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequestUtils.java @@ -24,10 +24,13 @@ public class NodeRequestUtils { if (t instanceof DocumentException) { return t.getMessage(); } else if (t instanceof MissingVariableException) { - return "Evaluation of property '" + name + "' failed\n" + - t.getMessage(); + return name + ":\n" + + t.getMessage().replaceAll("(?m)^", " "); } else if (t instanceof SCLDatabaseException) { - return t.getMessage(); + StringBuilder sb = new StringBuilder(); + sb.append(name + ":\n"); + sb.append(t.getMessage().replaceAll("(?m)^", " ")); + return sb.toString(); } else if (t instanceof NotFoundException) { return t.getMessage(); } else if (t instanceof ImportFailureException) { diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java index d69ef69c6..eb9e33607 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java @@ -1012,8 +1012,9 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Shape shape = ElementUtils.getElementShapeOrBounds(e); Rectangle2D bounds = shape.getBounds2D(); //System.out.println("selection bounds: "+bounds); - final double margin = 1; - bounds.setFrame(bounds.getMinX() - margin, bounds.getMinY() - margin, bounds.getWidth() + 2*margin, bounds.getHeight() + 2*margin); + final double marginX = 1 / selectionTransform.getScaleX(); + final double marginY = 1 / selectionTransform.getScaleY(); + bounds.setFrame(bounds.getMinX() - marginX, bounds.getMinY() - marginY, bounds.getWidth() + 2*marginX, bounds.getHeight() + 2*marginY); List ss = e.getElementClass().getItemsByClass(SelectionSpecification.class); if (!ss.isEmpty()) { diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/AWTImage.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/AWTImage.java index e547a663e..0fbe895be 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/AWTImage.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/AWTImage.java @@ -34,13 +34,19 @@ public class AWTImage extends AbstractImage implements Image { BufferedImage bi; Rectangle2D rect; + float alpha; - public AWTImage(BufferedImage bi) { + public AWTImage(BufferedImage bi, float alpha) { assert(bi!=null); this.bi = bi; + this.alpha = alpha; rect = new Rectangle2D.Double(bi.getMinX(),bi.getMinY(),bi.getWidth(), bi.getHeight()); } + public AWTImage(BufferedImage bi) { + this(bi, 1.0f); + } + @Override public Rectangle2D getBounds() { return rect; @@ -55,6 +61,8 @@ public class AWTImage extends AbstractImage implements Image { public Node init(G2DParentNode parent) { ImageNode node = parent.getOrCreateNode("image", ImageNode.class); node.setImage(bi); + node.setAlpha(alpha); + node.setZIndex(-100); return node; } diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/RulerPainter.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/RulerPainter.java index e4f90791e..bffe0c9df 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/RulerPainter.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/RulerPainter.java @@ -102,17 +102,21 @@ public class RulerPainter extends AbstractCanvasParticipant { @SGInit public void initSG(G2DParentNode parent) { - node = parent.addNode("ruler", RulerNode.class); + node = parent.addNode("ruler", getNodeClass()); node.setZIndex(PAINT_PRIORITY); updateNode(); } + protected Class getNodeClass() { + return RulerNode.class; + } + @SGCleanup public void cleanupSG() { node.remove(); } - void updateNode() { + protected void updateNode() { node.setEnabled(isPaintingEnabled()); node.setGridSize(getGridSize()); } diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java index 2d4171e1c..cb06d6add 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java @@ -11,7 +11,6 @@ import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -64,6 +63,8 @@ public class PrettyPrintTG { private boolean ignoreIdentifiers; + private TransferableGraphQueries query; + static class ResourceInfo { final boolean hasURI; String name; @@ -104,43 +105,51 @@ public class PrettyPrintTG { } } - public PrettyPrintTG(StringBuilder b, boolean ignoreIdentifiers) throws NoSuchAlgorithmException { + public PrettyPrintTG(TransferableGraph1 tg, StringBuilder b, boolean ignoreIdentifiers) throws NoSuchAlgorithmException { output = b; m = MessageDigest.getInstance("SHA-256"); this.ignoreIdentifiers = ignoreIdentifiers; + + this.query = new TransferableGraphQueries(tg); } - public PrettyPrintTG() throws NoSuchAlgorithmException { - this(new StringBuilder(), false); + public PrettyPrintTG(TransferableGraph1 tg) throws NoSuchAlgorithmException { + this(tg, new StringBuilder(), false); } TreeMap orderedInfos = new TreeMap<>(); TIntObjectHashMap infos = new TIntObjectHashMap<>(); - String tgNodeName(String name) { + private static String tgNodeName(String name) { if (name.contains(" ")) return "\"" + name + "\""; else return name; } - ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName, int parentId) { - String name = parentName + "." + tgNodeName(TransferableGraphUtils.getName(parent)); - ResourceInfo info = new ResourceInfo(true, name, parent.resource, parentId); - orderedInfos.put(name, info); - // infos.put(parent.resource, info); - for (Identity child : TransferableGraphUtils.getChildren(graph, parent)) { - recurseURI(graph, child, name, info.resource); - } + private ResourceInfo recurseURI(Map infos, Identity identity, String parentName, int parentId) { + String name = parentName + "." + tgNodeName(TransferableGraphUtils.getName(identity)); + int identityResource = identity.resource; + ResourceInfo info = new ResourceInfo(true, name, identityResource, parentId); + infos.put(name, info); + for (Identity child : query.getChildren(identity)) + recurseURI(infos, child, name, identityResource); return info; } - private TreeMap> sortByPredicateUniqueStatements(TransferableGraph1 graph, int resource) { + /** + * Sorts statements by predicateURI in natural order + * + * @param graph + * @param resource + * @return + */ + private TreeMap> sortByPredicateUniqueStatements(int resource) { TreeMap> results = new TreeMap<>(); - TIntArrayList statements = TransferableGraphUtils.getStatements(graph, resource); + TIntArrayList statements = query.getStatements(resource); for (int i = 0; i < statements.size(); i += 2) { int predicate = statements.get(i); - String predicateURI = TransferableGraphUtils.getURI(graph, predicate); + String predicateURI = query.getURI(predicate); TreeSet objects = results.get(predicateURI); if (objects == null) { objects = new TreeSet<>(); @@ -151,32 +160,32 @@ public class PrettyPrintTG { return results; } - void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) throws Exception { + void discoverBlank(int resource, TIntArrayList todo) throws Exception { // TIntArrayList statements = // TransferableGraphUtils.getStatements(graph, resource); // for(int i=0;i objects : sortByPredicateUniqueStatements(graph, resource).values()) { + for (TreeSet objects : sortByPredicateUniqueStatements(resource).values()) { for (int object : objects) { // int object = statements.get(i+1); - Identity objectId = TransferableGraphUtils.getIdentity(graph, object); + Identity objectId = query.getIdentity(object); if (objectId != null) { if (objectId.definition instanceof External) continue; } - Value value = TransferableGraphUtils.findValue(graph, object); + Value value = query.findValue(object); if (value != null) { infos.put(object, new ResourceInfo(false, printValue(value), object, resource)); - continue; - } - ResourceInfo existing = infos.get(object); - if (existing == null) { - - existing = new ResourceInfo(false, "blank" + blankCounter++, object, resource); - - // System.out.println("created blank" + blankCounter + " - // with object " + object + " resource " + resource); - infos.put(object, existing); - todo.add(object); + } else { + ResourceInfo existing = infos.get(object); + if (existing == null) { + + existing = new ResourceInfo(false, "blank" + blankCounter++, object, resource); + + // System.out.println("created blank" + blankCounter + " + // with object " + object + " resource " + resource); + infos.put(object, existing); + todo.add(object); + } } } } @@ -188,10 +197,10 @@ public class PrettyPrintTG { return new BigInteger(1, m.digest()).toString(16); } - void discoverOwners(TransferableGraph1 graph, ResourceInfo info) { + void discoverOwners(ResourceInfo info) { log("Discovering owners for {}", info); int resource = info.resource; - TIntArrayList statements = TransferableGraphUtils.getStatements(graph, resource); + TIntArrayList statements = query.getStatements(resource); for (int i = 0; i < statements.size(); i += 2) { int predicate = statements.get(i); int object = statements.get(i + 1); @@ -201,7 +210,7 @@ public class PrettyPrintTG { // Check if predicate is inverse, this just resolves all // predicates to be inverse with ending "Inverse".. - String predicateUri = rewritePredicateURI(graph, predicate); + String predicateUri = rewritePredicateURI(predicate); if (!predicateUri.endsWith("Inverse") && !predicateUri.endsWith("Of")) { existing.ownedResourcesWithPredicates.put(resource, predicate); // if (predicateUri.endsWith("Of")) { @@ -241,7 +250,7 @@ public class PrettyPrintTG { } } - public static String getExternalURI(TransferableGraph1 tg, External ext) { + public String getExternalURI(External ext) { String name = ext.name; if (name.contains(" ")) name = name.replace(" ", "_").replaceAll("@", "_");// name = "\"" + @@ -249,9 +258,9 @@ public class PrettyPrintTG { int parentId = ext.parent; // if(parentId == 0) return ext.name; // else { - Identity id = TransferableGraphUtils.getIdentity(tg, parentId); + Identity id = query.getIdentity(parentId); if (id.definition instanceof External) { - return getExternalURI(tg, (External) id.definition) + "/" + name; + return getExternalURI((External) id.definition) + "/" + name; } else if (id.definition instanceof Root) { Root root = (Root) id.definition; return "http:/" + root.name + "/" + name; @@ -261,20 +270,20 @@ public class PrettyPrintTG { // } } - public static String getExternalURI(TransferableGraph1 tg, int resource) { - Identity id = TransferableGraphUtils.getIdentity(tg, resource); + public String getExternalURI(int resource) { + Identity id = query.getIdentity(resource); if (id == null) return null; if (id.definition instanceof External) { External ext = (External) id.definition; - return getExternalURI(tg, ext); + return getExternalURI(ext); } return null; } - String rewritePredicateURI(TransferableGraph1 graph, int predicate) { + String rewritePredicateURI(int predicate) { - String uri = getExternalURI(graph, predicate); + String uri = getExternalURI(predicate); if (uri == null) { ResourceInfo info = infos.get(predicate); if (info != null) @@ -301,7 +310,7 @@ public class PrettyPrintTG { output.append(" "); } - String printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info, int indent) { + String printBlank(String predicateURI2, ResourceInfo info, int indent) { if (info.hasURI) return null; @@ -328,7 +337,7 @@ public class PrettyPrintTG { if (info.ownedResourcesWithPredicates.isEmpty()) { if (DEBUG) System.out.print("printBlank"); - String uri = printURI(graph, info, false, indent, false); + String uri = printURI(info, false, indent, false); if (uri != null) output.append(uri); } @@ -354,14 +363,14 @@ public class PrettyPrintTG { return ((predicate & 0xffffffffL) << 32) | (object & 0xffffffffL); } - private void addInlineStatement(TransferableGraph1 graph, Map> statements, String predicate, + private void addInlineStatement(Map> statements, String predicate, ResourceInfo objectInfo, int indent) { Set objects = statements.get(predicate); if (objects == null) { objects = new TreeSet<>(); statements.put(predicate, objects); } - String uri = printURI(graph, objectInfo, false, indent + 1, true); + String uri = printURI(objectInfo, false, indent + 1, true); if (uri != null) { // TODO: this is not the right place to remove trailing newline uri = uri.endsWith("\n") ? uri.substring(0, uri.length() - 2) : uri; @@ -382,7 +391,7 @@ public class PrettyPrintTG { objects.add(object); } - String printURI(TransferableGraph1 graph, ResourceInfo info, boolean requireURI, int indent, boolean inline) { + String printURI(ResourceInfo info, boolean requireURI, int indent, boolean inline) { if (requireURI && !info.hasURI) return null; @@ -393,8 +402,7 @@ public class PrettyPrintTG { return null; Map> statements = new TreeMap<>(); - Identity consistsOf = TransferableGraphUtils.findExternal(graph, - "http://www.simantics.org/Layer0-1.1/ConsistsOf"); + Identity consistsOf = query.findExternalByURI("http://www.simantics.org/Layer0-1.1/ConsistsOf"); // Identity partOf = TransferableGraphUtils.findExternal(graph, // "http://www.simantics.org/Layer0-1.1/PartOf"); TLongHashSet processed = new TLongHashSet(); @@ -410,9 +418,9 @@ public class PrettyPrintTG { processed.add(stmId); } - TreeMap predicateURIs = new TreeMap<>(); + TreeMap> predicateURIs = new TreeMap<>(); - TIntArrayList rawStatements = TransferableGraphUtils.getStatements(graph, info.resource); + TIntArrayList rawStatements = query.getStatements(info.resource); if (DEBUG) System.out.println( "rawStatements size for " + info.name + " : " + rawStatements.size() + " " + rawStatements); @@ -442,32 +450,38 @@ public class PrettyPrintTG { // indent++; // } } - String predicateURI = rewritePredicateURI(graph, predicate); - predicateURIs.put(predicateURI, object); + String predicateURI = rewritePredicateURI(predicate); + List objects = predicateURIs.get(predicateURI); + if (objects == null) { + objects = new ArrayList<>(); + predicateURIs.put(predicateURI, objects); + } + objects.add(object); } - for (Entry entry : predicateURIs.entrySet()) { + for (Entry> entry : predicateURIs.entrySet()) { String predicateURI = entry.getKey(); - int object = entry.getValue(); - - ResourceInfo objectInfo = infos.get(object); - if (objectInfo == null) { - String objectURI = rewritePredicateURI(graph, object); - if (DEBUG) - System.out.println(" adding statement " + predicateURI + " " + objectURI); - addStatement(statements, predicateURI, objectURI); - } else if (objectInfo.ownedBy.size() == 1 && objectInfo.ownedBy.contains(info)) { - // inline printing with _ - if (DEBUG) - System.out.println(" adding inline statement " + predicateURI + " " + objectInfo.name); - addInlineStatement(graph, statements, predicateURI, objectInfo, indent); - } else { - String objectName = objectInfo.name; - if (objectName.startsWith("blank")) { - objectName = getBlankRewrite(objectName); + List objects = entry.getValue(); + for (int object : objects) { + ResourceInfo objectInfo = infos.get(object); + if (objectInfo == null) { + String objectURI = rewritePredicateURI(object); + if (DEBUG) + System.out.println(" adding statement " + predicateURI + " " + objectURI); + addStatement(statements, predicateURI, objectURI); + } else if (objectInfo.ownedBy.size() == 1 && objectInfo.ownedBy.contains(info)) { + // inline printing with _ + if (DEBUG) + System.out.println(" adding inline statement " + predicateURI + " " + objectInfo.name); + addInlineStatement(statements, predicateURI, objectInfo, indent); + } else { + String objectName = objectInfo.name; + if (objectName.startsWith("blank")) { + objectName = getBlankRewrite(objectName); + } + if (DEBUG) + System.out.println(" adding statement " + predicateURI + " " + objectName); + addStatement(statements, predicateURI, objectName); } - if (DEBUG) - System.out.println(" adding statement " + predicateURI + " " + objectName); - addStatement(statements, predicateURI, objectName); } } @@ -547,46 +561,37 @@ public class PrettyPrintTG { } } - TreeMap ownedOrdered = new TreeMap<>(); + TreeMap> ownedOrdered = new TreeMap<>(); for (int i = 0; i < info.owned.size(); i += 2) { - String predicateURI = rewritePredicateURI(graph, info.owned.get(i)); - ownedOrdered.put(predicateURI, info.owned.get(i + 1)); + String predicateURI = rewritePredicateURI(info.owned.get(i)); + Set owneds = ownedOrdered.get(predicateURI); + if (owneds == null) { + owneds = new TreeSet<>(); + ownedOrdered.put(predicateURI, owneds); + } + owneds.add(info.owned.get(i + 1)); } if (DEBUG) System.out.println(info.name + " : " + ownedOrdered.keySet()); - for (Entry entry : ownedOrdered.entrySet()) { + for (Entry> entry : ownedOrdered.entrySet()) { String predicateURI = entry.getKey(); - int owned = entry.getValue(); - ResourceInfo ownedInfo = infos.get(owned); - - String blank = printBlank(graph, predicateURI, ownedInfo, indent + 1); - if (blank != null) { - output.append(blank); + Set owneds = entry.getValue(); + for (int owned : owneds) { + ResourceInfo ownedInfo = infos.get(owned); + + String blank = printBlank(predicateURI, ownedInfo, indent + 1); + if (blank != null) { + output.append(blank); + } } } return output.toString(); } - void prettyPrint(Path input, Path output) throws Exception { - - System.out.format("Converting exported shared ontology%n\t" + input.toString() - + "%nto bundle-compatible ontology%n\t" + output.toString()); - try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128 * 1024)) { - DataInput dis = new DataInputStream(is); - org.simantics.databoard.container.DataContainer container = DataContainers.readFile(dis); - Binding binding = TransferableGraph1.BINDING; - TransferableGraph1 graph = (TransferableGraph1) container.content.getValue(binding); - prettyPrint(graph); - Files.write(output, this.output.toString().getBytes()); - - } - - } - static Map knownOntologies = new HashMap<>(); static { @@ -607,26 +612,26 @@ public class PrettyPrintTG { knownOntologies.put("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WORKBENCH"); } - void prettyPrint(TransferableGraph1 graph) throws Exception { + void prettyPrint() throws Exception { log("Starting prettyPrint for TransferableGraph with {} resources, {} identities, {} statements and {} values", - graph.resourceCount, graph.identities, graph.statements.length, graph.values.length); + query.getGraph().resourceCount, query.getGraph().identities, query.getGraph().statements.length, query.getGraph().values.length); - for (Identity id : graph.identities) { + query.forIdentities(id -> { + int identityResource = id.resource; if (id.definition instanceof Internal) { Internal internal = (Internal) id.definition; - Identity parent = TransferableGraphUtils.getIdentity(graph, internal.parent); - if (parent.definition instanceof External) { + Identity parent = query.getIdentity(internal.parent); + if (parent.definition instanceof External || parent.definition instanceof Root) { log("Resolving internal identity {}", id); String name = "BASE"; - ResourceInfo info = new ResourceInfo(true, name, id.resource, -1); - info.aliasURI = TransferableGraphUtils.getURI(graph, id.resource); + ResourceInfo info = new ResourceInfo(true, name, identityResource, -1); + info.aliasURI = query.getURI(identityResource); info.newResource = true; orderedInfos.put(name, info); // infos.put(id.resource, info); log(" which parent is external {} and has an aliasURI {}", parent, info.aliasURI); - for (Identity child : TransferableGraphUtils.getChildren(graph, id)) { - recurseURI(graph, child, name, info.resource); - } + for (Identity child : query.getChildren(id)) + recurseURI(orderedInfos, child, name, identityResource); log(" and has {} children", infos.size()); } } else if (id.definition instanceof External) { @@ -640,7 +645,7 @@ public class PrettyPrintTG { String prefix = ext.name.substring(0, index); int index2 = ext.name.indexOf('/', index); String ontology = index2 == -1 ? ext.name : ext.name.substring(0, index2); - String uri = TransferableGraphUtils.getURI(graph, id.resource); + String uri = query.getURI(identityResource); log(" which was resolved as URI={} and prefix={}", uri, prefix); @@ -648,7 +653,7 @@ public class PrettyPrintTG { } else if (ext.name.contains("-")) { log("Resolving possible ontology {}", ext); - String uri = TransferableGraphUtils.getURI(graph, id.resource); + String uri = query.getURI(identityResource); Matcher m = versionExtractPattern.matcher(uri); if (m.matches()) { if (!ontologies.containsKey(uri)) { @@ -660,7 +665,8 @@ public class PrettyPrintTG { } } } - } + return true; + }); // Discover other resources log("Discovering other resources.."); @@ -675,10 +681,10 @@ public class PrettyPrintTG { while (!todo.isEmpty()) { int resource = todo.removeAt(todo.size() - 1); - discoverBlank(graph, resource, todo); + discoverBlank(resource, todo); } for (ResourceInfo info : infos.valueCollection()) - discoverOwners(graph, info); + discoverOwners(info); // for(ResourceInfo info : infos.valueCollection()) // fixInstanceOf(graph, info); @@ -697,12 +703,15 @@ public class PrettyPrintTG { @Override public boolean execute(int owner, int predicate) { + ResourceInfo ownerInfo = infos.get(owner); ownerInfo.owned.add(predicate); ownerInfo.owned.add(info.resource); return false; } }); + } else { + System.err.println("Here we are with " + info); } } @@ -717,21 +726,18 @@ public class PrettyPrintTG { } } - Identity routeGraphConn = TransferableGraphUtils.findExternal(graph, - "http://www.simantics.org/Diagram-2.2/RouteGraphConnection"); - Identity instanceOf = TransferableGraphUtils.findExternal(graph, - "http://www.simantics.org/Layer0-1.1/InstanceOf"); - Identity diagramConnetionToConnection = TransferableGraphUtils.findExternal(graph, - "http://www.simantics.org/Modeling-1.2/DiagramConnectionToConnection"); + Identity routeGraphConn = query.findExternalByURI("http://www.simantics.org/Diagram-2.2/RouteGraphConnection"); + Identity instanceOf = query.findExternalByURI("http://www.simantics.org/Layer0-1.1/InstanceOf"); + Identity diagramConnetionToConnection = query.findExternalByURI("http://www.simantics.org/Modeling-1.2/DiagramConnectionToConnection"); + Identity elemTo = query.findExternalByURI("http://www.simantics.org/Modeling-1.2/ElementToComponent"); for (ResourceInfo infoo : infos.valueCollection()) { - Identity elemTo = TransferableGraphUtils.findExternal(graph, "http://www.simantics.org/Modeling-1.2/ElementToComponent"); if (elemTo != null) { - int elemToComponent = TransferableGraphUtils.getPossibleObject2(graph, infoo.resource, elemTo); + int elemToComponent = query.getPossibleObject(infoo.resource, elemTo); if (elemToComponent != TransferableGraphUtils.NOT_FOUND) { - Identity component = TransferableGraphUtils.getIdentity(graph, elemToComponent); - Identity internal = TransferableGraphUtils.getIdentity(graph, infoo.resource); + Identity component = query.getIdentity(elemToComponent); + Identity internal = query.getIdentity(infoo.resource); if (internal.definition instanceof Internal && component.definition instanceof Internal) { Internal iComponent = (Internal) component.definition; infoo.name = infoo.name.substring(0, infoo.name.lastIndexOf(".") + 1) + iComponent.name; @@ -740,29 +746,29 @@ public class PrettyPrintTG { } if (instanceOf != null) { - int instOf = TransferableGraphUtils.getPossibleObject2(graph, infoo.resource, instanceOf); + int instOf = query.getPossibleObject( infoo.resource, instanceOf); if (instOf != TransferableGraphUtils.NOT_FOUND && routeGraphConn != null) { if (instOf == routeGraphConn.resource) { // Found routegraphconnection, change name // Lets go to configuration - int connection = TransferableGraphUtils.getPossibleObject2(graph, infoo.resource, + int connection = query.getPossibleObject( infoo.resource, diagramConnetionToConnection); if (connection != TransferableGraphUtils.NOT_FOUND) { // Gather all inverse statements to construct unique // name List nameParts = new ArrayList<>(); - TIntArrayList statements = TransferableGraphUtils.getStatements(graph, connection); + TIntArrayList statements = query.getStatements(connection); for (int i = 0; i < statements.size(); i += 2) { int predicate = statements.get(i); - Identity possibleInverse = TransferableGraphUtils.getIdentity(graph, predicate); + Identity possibleInverse = query.getIdentity(predicate); if (possibleInverse != null) { int inverseRelation = TransferableGraphUtils.NOT_FOUND; int parentId = TransferableGraphUtils.NOT_FOUND; if (possibleInverse.definition instanceof Internal) { Internal iPossibleInverse = (Internal) possibleInverse.definition; if (iPossibleInverse.name.equals("Inverse")) { - inverseRelation = TransferableGraphUtils.getPossibleObject2(graph, + inverseRelation = query.getPossibleObject( connection, possibleInverse); parentId = iPossibleInverse.parent; } else { @@ -771,7 +777,7 @@ public class PrettyPrintTG { } else if (possibleInverse.definition instanceof External) { External ePossibleInverse = (External) possibleInverse.definition; if (ePossibleInverse.name.equals("Inverse")) { - inverseRelation = TransferableGraphUtils.getPossibleObject2(graph, + inverseRelation = query.getPossibleObject( connection, possibleInverse); parentId = ePossibleInverse.parent; } else { @@ -782,8 +788,8 @@ public class PrettyPrintTG { } if (inverseRelation != TransferableGraphUtils.NOT_FOUND) { // Ok found something - Identity object = TransferableGraphUtils.getIdentity(graph, inverseRelation); - Identity parent = TransferableGraphUtils.getIdentity(graph, parentId); + Identity object = query.getIdentity(inverseRelation); + Identity parent = query.getIdentity(parentId); String objectName, parentName; if (object.definition instanceof Internal) { objectName = ((Internal) object.definition).name; @@ -818,7 +824,6 @@ public class PrettyPrintTG { infoo.name = infoo.name.substring(0, infoo.name.lastIndexOf(".") + 1) + name; } else { LOGGER.error("Could not find connection for " + infoo + ". Statements of graph below"); - LOGGER.error(Arrays.toString(graph.statements)); LOGGER.error("Subject -> Predicate : " + infoo.resource + " -> " + diagramConnetionToConnection.resource); } @@ -828,7 +833,7 @@ public class PrettyPrintTG { } for (ResourceInfo info : infos.valueCollection()) { if (info.name.startsWith("blank")) { - info.name = "blank" + findHash(graph, info); + info.name = "blank" + findHash(info); } } @@ -839,7 +844,7 @@ public class PrettyPrintTG { for (ResourceInfo info : order.values()) { if (DEBUG) System.out.print("info "); - String uri = printURI(graph, info, true, 0, false); + String uri = printURI(info, true, 0, false); if (uri != null) output.append(uri); } @@ -854,7 +859,7 @@ public class PrettyPrintTG { // These will be printed later rblanks.put(getBlankRewrite(info.name), info); } else { - String uri = printURI(graph, info, false, 0, false); + String uri = printURI(info, false, 0, false); if (uri != null) output.append(uri); } @@ -865,7 +870,7 @@ public class PrettyPrintTG { if (!info.hasURI && info.ownedResourcesWithPredicates.size() != 1) { if (DEBUG) System.out.print("ownedResources "); - String uri = printURI(graph, info, false, 0, false); + String uri = printURI(info, false, 0, false); if (uri != null) output.append(uri); } @@ -886,7 +891,7 @@ public class PrettyPrintTG { } - private String calculateHash(TransferableGraph1 graph, ResourceInfo info) { + private String calculateHash(ResourceInfo info) { StringBuilder statementHash = new StringBuilder(); TreeSet parts = new TreeSet<>(); for (int i = 0; i < info.owned.size(); i += 2) { @@ -895,7 +900,7 @@ public class PrettyPrintTG { // Lets resolve a unique name for this based on the statements this // one has - String predicatee = rewritePredicateURI(graph, predicate); + String predicatee = rewritePredicateURI(predicate); ResourceInfo objInfo = infos.get(object); parts.add(predicatee + "->" + objInfo.name + ";;;"); } @@ -921,14 +926,14 @@ public class PrettyPrintTG { return hash; } - private String findHash(TransferableGraph1 graph, ResourceInfo info) { + private String findHash(ResourceInfo info) { if (info.name.startsWith("blank")) { String hash = hashes.get(info.name); if (hash == null) { String oldName = info.name; if (DEBUG) System.out.print("calculating hash for " + oldName + " "); - hash = calculateHash(graph, info); + hash = calculateHash(info); if (hashes.put(oldName, hash) != null) { System.err.println("!!!!A clash occured for " + info + " with hash " + hash); } @@ -943,19 +948,31 @@ public class PrettyPrintTG { public static String print(TransferableGraph1 tg, boolean ignoreIdentifiers) throws Exception { StringBuilder b = new StringBuilder(); - new PrettyPrintTG(b, ignoreIdentifiers).prettyPrint(tg); + new PrettyPrintTG(tg, b, ignoreIdentifiers).prettyPrint(); return b.toString(); } public static void main(String[] args) throws Exception { if (args.length < 1) { System.out.println("Required arguments: []"); - } else if (args.length < 2) { - Path input = Paths.get(args[0]); - Path output = input.getParent().resolve(input.getName(input.getNameCount() - 1) + ".fixed"); - new PrettyPrintTG().prettyPrint(input, output); + } + Path input; + Path output; + if (args.length < 2) { + input = Paths.get(args[0]); + output = input.getParent().resolve(input.getName(input.getNameCount() - 1) + ".fixed"); } else { - new PrettyPrintTG().prettyPrint(Paths.get(args[0]), Paths.get(args[1])); + input = Paths.get(args[0]); + output = Paths.get(args[1]); + } + System.out.format("Converting exported shared ontology%n\t" + input.toString() + + "%nto bundle-compatible ontology%n\t" + output.toString()); + try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128 * 1024)) { + DataInput dis = new DataInputStream(is); + org.simantics.databoard.container.DataContainer container = DataContainers.readFile(dis); + Binding binding = TransferableGraph1.BINDING; + TransferableGraph1 graph = (TransferableGraph1) container.content.getValue(binding); + new PrettyPrintTG(graph).prettyPrint(); } } diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java new file mode 100644 index 000000000..5d4c1850b --- /dev/null +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java @@ -0,0 +1,205 @@ +package org.simantics.graph.representation; + +import java.util.Comparator; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import gnu.trove.impl.Constants; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TObjectProcedure; + +public class TransferableGraphQueries { + + private static final int NOT_FOUND = TransferableGraphUtils.NOT_FOUND; + + private final TransferableGraph1 tg; + + private final TIntObjectHashMap internalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND); + private final TIntObjectHashMap externalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND); + private final TIntObjectHashMap rootIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND); + + private final TObjectIntHashMap internalIdentitiesByURI = new TObjectIntHashMap<>(); + private final TObjectIntHashMap externalIdentitiesByURI = new TObjectIntHashMap<>(); + private final TObjectIntHashMap rootIdentitiesByURI = new TObjectIntHashMap<>(); + + private final TIntObjectHashMap statementsCache = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND); + + public TransferableGraphQueries(TransferableGraph1 graph) { + this.tg = graph; + + // Calculate internals + initializeIdentities(); + } + + private void initializeIdentities() { + for (Identity identity : tg.identities) { + IdentityDefinition definition = identity.definition; + if (definition instanceof Internal) { + Internal internal = (Internal) definition; + internalIdentities.put(identity.resource, identity); + internalIdentitiesByURI.put(getURI(identity), identity.resource); + } else if (definition instanceof External) { + External external = (External) definition; + externalIdentities.put(identity.resource, identity); + externalIdentitiesByURI.put(getURI(identity), identity.resource); + } else if (definition instanceof Root) { + Root root = (Root) definition; + rootIdentities.put(identity.resource, identity); + rootIdentitiesByURI.put(getURI(identity), identity.resource); + } + } + } + + public String getURI(Identity identity) { + IdentityDefinition definition = identity.definition; + if(definition instanceof External) { + External def = (External)definition; + if(def.parent == -1) return "http:/"; + else return getURI(def.parent) + "/" + def.name; + } else if(definition instanceof Root) { + Root def = (Root)definition; + if(def.name.isEmpty()) return "http:/"; + return def.name; + } else if (definition instanceof Internal) { + Internal def = (Internal)definition; + return getURI(def.parent) + "/" + def.name; + } else { + return ""; + } + } + + public String getURI(int id) { + Identity identity = getIdentity(id); + if (identity == null) + return ":"; + return getURI(identity); + } + + private static final Comparator IDENTITY_NAME_COMPARATOR = new Comparator() { + + @Override + public int compare(Identity o1, Identity o2) { + if (o1.definition instanceof Internal && o2.definition instanceof Internal) { + Internal i1 = (Internal) o1.definition; + Internal i2 = (Internal) o2.definition; + return i1.name.compareTo(i2.name); + } else if (o1.definition instanceof External && o2.definition instanceof External) { + External e1 = (External) o1.definition; + External e2 = (External) o2.definition; + return e1.name.compareTo(e2.name); + } else { + throw new IllegalArgumentException(o1 + " " + o2); + } + } + }; + + public Set getChildren(Identity parent) { + TreeSet children = new TreeSet<>(IDENTITY_NAME_COMPARATOR); + internalIdentities.forEachEntry((resource, identity) -> { + Internal internal = (Internal) identity.definition; + if (internal.parent == parent.resource) + children.add(identity); + return true; + }); + + return children; + } + + public Identity findInternalByName(String name) { + int internal = internalIdentitiesByURI.get(name); + if (internal == NOT_FOUND) + return null; + return internalIdentities.get(internal); + } + + private Identity findExternalByName(String name) { + int external = externalIdentitiesByURI.get(name); + if (external == NOT_FOUND) + return null; + return externalIdentities.get(external); + } + + private Identity findExternalByNameAndParent(String name, int parent) { + Identity external = findExternalByName(name); + if (external.resource == parent) + return external; + return null; + } + + public Identity findExternalByURI(String uri) { + int v = externalIdentitiesByURI.get(uri); + if (v == NOT_FOUND) + return null; + return externalIdentities.get(v); + } + + public Identity findRootByName(String name) { + int root = rootIdentitiesByURI.get(name); + if (root == NOT_FOUND) + return null; + return rootIdentities.get(root); + } + + public String getName(Identity identity) { + return TransferableGraphUtils.getName(identity); + } + + public void forIdentities(TObjectProcedure procedure) { + for (Identity identity : tg.identities) { + if (!procedure.execute(identity)) { + break; + } + } + } + + public Identity getIdentity(int resource) { + Identity result = rootIdentities.get(resource); + if (result == null) + result = externalIdentities.get(resource); + if (result == null) + result = internalIdentities.get(resource); + return result; + } + + public Value findValue(int object) { + return TransferableGraphUtils.findValue(tg, object); + } + + public TreeMap> sortByPredicateUniqueStatements(int resource) { + TreeMap> results = new TreeMap<>(); + TIntArrayList statements = getStatements(resource); + for (int i = 0; i < statements.size(); i += 2) { + int predicate = statements.get(i); + String predicateURI = getURI(predicate); + TreeSet objects = results.get(predicateURI); + if (objects == null) { + objects = new TreeSet<>(); + } + objects.add(statements.get(i + 1)); + results.put(predicateURI, objects); + } + return results; + } + + public TIntArrayList getStatements(int resource) { +// System.out.println("getting statements with " + resource); + TIntArrayList statements = statementsCache.get(resource); + if (statements == null) { + statements = TransferableGraphUtils.getStatements(tg, resource); + statementsCache.put(resource, statements); + } + return statements; + } + + public int getPossibleObject(int subject, Identity predicate) { + return TransferableGraphUtils.getPossibleObject2(tg, subject, predicate); + } + + public TransferableGraph1 getGraph() { + return tg; + } + +} diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java index b210d8dd7..10637ad65 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java @@ -16,156 +16,205 @@ import gnu.trove.map.hash.TIntObjectHashMap; public class TransferableGraphUtils { - public static Collection getRoots(TransferableGraph1 tg) { - - ArrayList result = new ArrayList(); - for(Identity id : tg.identities) { - if(id.definition instanceof Root) result.add(id); - } - return result; - - } - - public static Identity findRootWithName(TransferableGraph1 tg, String name) { - - for(Identity id : tg.identities) { - if(id.definition instanceof Root) { - Root ext = (Root)id.definition; - if(ext.name.equals(name)) return id; - } - } - return null; - - } + public static Collection getRoots(TransferableGraph1 tg) { + + ArrayList result = new ArrayList(); + for(Identity id : tg.identities) { + if(id.definition instanceof Root) result.add(id); + } + return result; + + } + + public static Identity findRootWithName(TransferableGraph1 tg, String name) { + + for(Identity id : tg.identities) { + if(id.definition instanceof Root) { + Root ext = (Root)id.definition; + if(ext.name.equals(name)) return id; + } + } + return null; + + } - public static Identity findExternalWithName(TransferableGraph1 tg, String name) { - - for(Identity id : tg.identities) { - if(id.definition instanceof External) { - External ext = (External)id.definition; - if(ext.name.equals(name)) return id; - } - } - return null; - - } + public static Identity findExternalWithName(TransferableGraph1 tg, String name) { + + for(Identity id : tg.identities) { + if(id.definition instanceof External) { + External ext = (External)id.definition; + if(ext.name.equals(name)) return id; + } + } + return null; + + } + + public static Identity findExternalWithNameAndParent(TransferableGraph1 tg, int parent, String name) { + + for(Identity id : tg.identities) { + if(id.definition instanceof External) { + External ext = (External)id.definition; + if(ext.name.equals(name) && ext.parent == parent) return id; + } + } + return null; + + } + + public static Identity findExternal(TransferableGraph1 tg, String uri) { + + Identity identity = findExternalWithName(tg, "http:/"); + if(identity == null) identity = findExternalWithName(tg, ""); + if(identity == null) identity = findRootWithName(tg, ""); + if("http:/".equals(uri)) return identity; + String[] tokens = uri.substring("http://".length()).split("/"); + for(String token : tokens) { + identity = findExternalWithNameAndParent(tg, identity.resource, token); + if (identity == null) { + return null; + } + } + return identity; + + } + + public static Identity getIdentity(TransferableGraph1 tg, int resource) { + for(Identity id : tg.identities) { + if(id.resource == resource) return id; + } + return null; + } + + public static TIntArrayList getStatements(TransferableGraph1 tg, int resource) { + TIntArrayList result = new TIntArrayList(); + for(int i=0;i getChildren2(TransferableGraph1 tg, Identity parent) { + return getChildren2(tg, parent.resource); + } + + public static Collection getChildren2(TransferableGraph1 tg, int parentResource) { + TreeMap result = new TreeMap<>(); + for (Identity id : tg.identities) { + if (id.definition instanceof Internal) { + Internal internal = (Internal) id.definition; + if (internal.parent == parentResource) + result.put(internal.name, id); + } + } + Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf"); + Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName"); + for (int i = 0; i < tg.statements.length; i += 4) { + if (tg.statements[i] == parentResource) { + if (tg.statements[i + 1] == consistsOf.resource) { + Identity identity = getIdentity(tg, tg.statements[i + 3]); + if (identity != null) { + if (identity.definition instanceof Internal) { + Internal internal = (Internal) identity.definition; + result.put(internal.name, identity); + } + } else { + int possibleNameResource = getPossibleObject2(tg, tg.statements[i + 3], hasName); + if (possibleNameResource != NOT_FOUND) { + Value value = findValue(tg, possibleNameResource); + if (value != null) { + try { + String name = (String) value.value.getValue(Bindings.STRING); + result.put(name, new Identity(tg.statements[i + 3], new Internal(tg.statements[i], name))); + } catch (AdaptException e) { + e.printStackTrace(); + } + } + } + } + } + } + } + return result.values(); + } - public static Identity findExternalWithNameAndParent(TransferableGraph1 tg, int parent, String name) { - - for(Identity id : tg.identities) { - if(id.definition instanceof External) { - External ext = (External)id.definition; - if(ext.name.equals(name) && ext.parent == parent) return id; - } - } - return null; - - } - - public static Identity findExternal(TransferableGraph1 tg, String uri) { - - Identity identity = findExternalWithName(tg, "http:/"); - if(identity == null) identity = findExternalWithName(tg, ""); - if(identity == null) identity = findRootWithName(tg, ""); - if("http:/".equals(uri)) return identity; - String[] tokens = uri.substring("http://".length()).split("/"); - for(String token : tokens) { - identity = findExternalWithNameAndParent(tg, identity.resource, token); - if (identity == null) { - return null; - } - } - return identity; - - } - - public static Identity getIdentity(TransferableGraph1 tg, int resource) { - for(Identity id : tg.identities) { - if(id.resource == resource) return id; - } - return null; - } - - public static TIntArrayList getStatements(TransferableGraph1 tg, int resource) { - TIntArrayList result = new TIntArrayList(); - for(int i=0;i getChildren(TransferableGraph1 tg, Identity parent) { - TreeMap result = new TreeMap<>(); - for(Identity id : tg.identities) { - if(id.definition instanceof Internal) { - Internal internal = (Internal)id.definition; - if(internal.parent == parent.resource) result.put(internal.name, id); - } - } - Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf"); - Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName"); - for(int i=0;i getChildren(TransferableGraph1 tg, Identity parent) { + TreeMap result = new TreeMap<>(); + for(Identity id : tg.identities) { + if(id.definition instanceof Internal) { + Internal internal = (Internal)id.definition; + if(internal.parent == parent.resource) result.put(internal.name, id); + } + } + Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf"); + Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName"); + for(int i=0;i getNames(TransferableGraph1 tg, Collection ids) { - Map result = new HashMap(); - for(Identity id : ids) { - if(id.definition instanceof Internal) { - Internal internal = (Internal)id.definition; - result.put(id, internal.name); - } - } - return result; - } + public static Map getNames(TransferableGraph1 tg, Collection ids) { + Map result = new HashMap(); + for(Identity id : ids) { + if(id.definition instanceof Internal) { + Internal internal = (Internal)id.definition; + result.put(id, internal.name); + } + } + return result; + } - public static String getName(TransferableGraph1 tg, Identity id) { - return getName(id); - } + public static String getName(TransferableGraph1 tg, Identity id) { + return getName(id); + } - public static String getName(Identity id) { - if(id.definition instanceof Internal) { - Internal internal = (Internal)id.definition; - return internal.name; - } else if(id.definition instanceof External) { - External external = (External)id.definition; - return external.name; - } else if(id.definition instanceof Root) { - Root root = (Root)id.definition; - return root.name; - } else { - Optional optional = (Optional)id.definition; - return optional.name; - } - } + public static String getName(Identity id) { + if(id.definition instanceof Internal) { + Internal internal = (Internal)id.definition; + return internal.name; + } else if(id.definition instanceof External) { + External external = (External)id.definition; + return external.name; + } else if(id.definition instanceof Root) { + Root root = (Root)id.definition; + return root.name; + } else { + Optional optional = (Optional)id.definition; + return optional.name; + } + } - public static String getRootType(Identity id) { - if(id.definition instanceof Root) { - Root root = (Root)id.definition; - return root.type; - } else { - throw new IllegalArgumentException("Expected root, got " + id); - } - } + public static String getRootType(Identity id) { + if(id.definition instanceof Root) { + Root root = (Root)id.definition; + return root.type; + } else { + throw new IllegalArgumentException("Expected root, got " + id); + } + } - public static Value findValue(TransferableGraph1 tg, int subject) { - for(Value v : tg.values) { - if(v.resource == subject) return v; - } - return null; - } - - public static String getURI(TransferableGraph1 tg, int id) { - return getURI(tg.resourceCount, tg.identities, id); - } - - public static String getURI(int resourceCount, Identity[] identities, int id) { - for(Identity identity : identities) { - if(identity.resource == id) { - IdentityDefinition definition = identity.definition; - if(definition instanceof External) { - External def = (External)definition; - if(def.parent == -1) return "http:/"; - else return getURI(resourceCount, identities, def.parent) + "/" + def.name; - } else if(definition instanceof Root) { - Root def = (Root)definition; - if(def.name.isEmpty()) return "http:/"; - return def.name; - } else if (definition instanceof Internal) { - Internal def = (Internal)definition; - return getURI(resourceCount, identities, def.parent) + "/" + def.name; - } else { - return ""; - } - } - } - return ":"; - } + public static Value findValue(TransferableGraph1 tg, int subject) { + for(Value v : tg.values) { + if(v.resource == subject) return v; + } + return null; + } + + public static String getURI(TransferableGraph1 tg, int id) { + return getURI(tg.identities, id); + } + + public static String getURI(Identity[] identities, int id) { + for(Identity identity : identities) { + if(identity.resource == id) { + IdentityDefinition definition = identity.definition; + if(definition instanceof External) { + External def = (External)definition; + if(def.parent == -1) return "http:/"; + else return getURI(identities, def.parent) + "/" + def.name; + } else if(definition instanceof Root) { + Root def = (Root)definition; + if(def.name.isEmpty()) return "http:/"; + return def.name; + } else if (definition instanceof Internal) { + Internal def = (Internal)definition; + return getURI(identities, def.parent) + "/" + def.name; + } else { + return ""; + } + } + } + return ":"; + } - public static TIntObjectMap mapIdentities(TransferableGraph1 tg) { - return mapIdentities(tg.identities); - } + public static TIntObjectMap mapIdentities(TransferableGraph1 tg) { + return mapIdentities(tg.identities); + } - public static TIntObjectMap mapIdentities(Identity[] identities) { - // Integer.MIN_VALUE cannot be the value of Identity.resource - TIntObjectMap map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE); - for (Identity id : identities) - map.put(id.resource, id); - return map; - } + public static TIntObjectMap mapIdentities(Identity[] identities) { + // Integer.MIN_VALUE cannot be the value of Identity.resource + TIntObjectMap map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE); + for (Identity id : identities) + map.put(id.resource, id); + return map; + } - public static String getURI(int resourceCount, TIntObjectMap identities, int id) { - Identity identity = identities.get(id); - if(identity != null) { - IdentityDefinition definition = identity.definition; - if(definition instanceof External) { - External def = (External)definition; - if(def.parent == -1) return "http:/"; - else return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name); - } else if(definition instanceof Root) { - Root def = (Root)definition; - if(def.name.isEmpty()) return "http:/"; - return def.name; - } else if (definition instanceof Internal) { - Internal def = (Internal)definition; - return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name); - } else { - return ""; - } - } - return ":"; - } + public static String getURI(int resourceCount, TIntObjectMap identities, int id) { + Identity identity = identities.get(id); + if(identity != null) { + IdentityDefinition definition = identity.definition; + if(definition instanceof External) { + External def = (External)definition; + if(def.parent == -1) return "http:/"; + else return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name); + } else if(definition instanceof Root) { + Root def = (Root)definition; + if(def.name.isEmpty()) return "http:/"; + return def.name; + } else if (definition instanceof Internal) { + Internal def = (Internal)definition; + return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name); + } else { + return ""; + } + } + return ":"; + } } diff --git a/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java b/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java index 6610d17f2..4e405e2ac 100644 --- a/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java +++ b/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java @@ -12,9 +12,7 @@ package org.simantics.history.csv; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.math.BigDecimal; -import java.net.URLDecoder; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.Format; @@ -85,20 +83,12 @@ public class CSVFormatter { i.history = history; i.label = label!=null?label:""; i.variableReference = variableReference!=null?variableReference:""; - i.variableReference = unescape(i.variableReference); + i.variableReference = URIs.safeUnescape(i.variableReference); i.historyItemId = historyItemId; i.unit = unit; if ( !items.contains(i) ) items.add( i ); } - private static String unescape(String url) { - try { - return URLDecoder.decode(url, "UTF-8"); - } catch (UnsupportedEncodingException e) { - return url; - } - } - /** * Sort items by variableId, label1, label2 */ diff --git a/bundles/org.simantics.history/src/org/simantics/history/csv/URIs.java b/bundles/org.simantics.history/src/org/simantics/history/csv/URIs.java new file mode 100644 index 000000000..57a819a64 --- /dev/null +++ b/bundles/org.simantics.history/src/org/simantics/history/csv/URIs.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2017 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.history.csv; + +/** + * @author Tuukka Lehtonen + * @since 1.30.0, 1.28.1 + */ +class URIs { + + public static String safeUnescape(String uri) { + try { + return unescape(uri); + } catch (IllegalArgumentException e) { + return uri; + } + } + + public static String unescape(String uri) { + try { + if (!needsUnescaping(uri)) + return uri; + + int len = uri.length(); + String unicode = uri; + char result[] = new char[len]; + int in = 0; + int out = 0; + while (in < len) { + char inCh = unicode.charAt(in++); + if (inCh == '%' && in+1 < len) { + char d1 = unicode.charAt(in); + char d2 = unicode.charAt(in+1); + if (d1 > 127 || d2 > 127) + throw new IllegalArgumentException("Invalid hex digit escape sequence in " + uri + " at " + in); + result[out++] = (char) (hexDecode(d1) * 16 | hexDecode(d2)); + in += 2; + } else { + result[out++] = inCh; + } + } + return new String(result, 0, out); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Problem while unescaping string: " + uri, e); + } catch (IndexOutOfBoundsException ee) { + throw new IllegalArgumentException("Incomplete hex digit escape sequence in " + uri); + } + } + + private static boolean needsUnescaping(String s) { + int l = s.length(); + for (int i = -1; i < l;) { + i = s.indexOf('%', i+1); + if (i < 0) + break; + if (i+2 < l + && isHexDigit(s.charAt(i+1)) + && isHexDigit(s.charAt(i+2))) + return true; + } + return false; + } + + private static int hexDecode(char c) { + switch (c) { + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return ((c) & 255) - 'a' + 10; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + return c - 'A' + 10; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + return c - '0'; + default: + throw new IllegalArgumentException("Bad Hex escape character: " + ((c)&255) ); + } + } + + private static boolean isHexDigit(char c) { + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); + } + +// public static void main(String[] args) { +// System.out.println(unescape("%")); +// System.out.println(unescape("%.AI")); +// System.out.println(unescape("%6B")); +// System.out.println(unescape("%6g")); +// System.out.println(unescape("%g5")); +// System.out.println(unescape("%f5")); +// System.out.println(unescape("%A1")); +// System.out.println(unescape("%A")); +// System.out.println(unescape("%A.")); +// System.out.println(unescape("%AI")); +// } + +} diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeverityRecursive.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeverityRecursive.java index db537ee26..7646271e3 100644 --- a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeverityRecursive.java +++ b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeverityRecursive.java @@ -12,6 +12,8 @@ package org.simantics.issues.common; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import org.simantics.db.AsyncReadGraph; import org.simantics.db.Resource; @@ -29,66 +31,71 @@ public class MaxIssueSeverityRecursive extends TernaryAsyncRead typesToRecurse) { super(resource, childRelation, typesToRecurse); } - -// @Override -// public Severity perform(ReadGraph graph) throws DatabaseException { -// Layer0 L0 = Layer0.getInstance(graph); -// IssueResource ISSUE = IssueResource.getInstance(graph); -// //System.out.println("severity: " + NameUtils.getSafeName(graph, resource)); -// Collection issues = graph.getObjects(resource, ISSUE.IsIssueContextOf); -// if (issues.isEmpty()) { -// // This content does not have directly attached issues, try to look -// // for some in the child components. -// return graph.syncRequest(new ChildMaxIssueSeverity(resource, L0.ConsistsOf)); -// } -// -// Severity maxSeverity = graph.syncRequest(new MaxIssueSeveritySingle(resource)); -// if (maxSeverity == null) -// maxSeverity = graph.syncRequest(new ChildMaxIssueSeverity(resource, L0.ConsistsOf)); -// -// return maxSeverity; -// } - + @Override public void perform(AsyncReadGraph graph, final AsyncProcedure procedure) { + IssueResource ISSUE = graph.getService(IssueResource.class); - //System.out.println(getClass().getSimpleName() + ": " + parameter); + + AtomicInteger issues = new AtomicInteger(); + AtomicBoolean excepted = new AtomicBoolean(false); graph.forEachObject(parameter, ISSUE.Issue_HasContext_Inverse, new AsyncMultiProcedure() { - volatile int issues = 0; @Override public void execute(AsyncReadGraph graph, Resource result) { - ++issues; + issues.incrementAndGet(); } @Override public void finished(AsyncReadGraph graph) { - if (issues == 0) { - // This content does not have directly attached issues, try to look - // for some in the child components. - graph.asyncRequest(new ChildMaxIssueSeverity(parameter, parameter2, parameter3), procedure); - } else { - // Try local issues first - graph.asyncRequest(new MaxIssueSeveritySingle(parameter), new AsyncProcedure() { - @Override - public void execute(AsyncReadGraph graph, Severity maxSeverity) { - if (maxSeverity == null) - // No severity for local issues, try children next. - graph.asyncRequest(new ChildMaxIssueSeverity(parameter, parameter2, parameter3), procedure); - else - procedure.execute(graph, maxSeverity); - } - @Override - public void exception(AsyncReadGraph graph, Throwable throwable) { - procedure.exception(graph, throwable); - } - }); - } + } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { - procedure.exception(graph, throwable); + if(excepted.compareAndSet(false, true)) + procedure.exception(graph, throwable); } }); + + graph.forEachObject(parameter, ISSUE.Issue_ContextList_Element_Inverse, new AsyncMultiProcedure() { + @Override + public void execute(AsyncReadGraph graph, Resource result) { + issues.incrementAndGet(); + } + @Override + public void finished(AsyncReadGraph graph) { + + } + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + if(excepted.compareAndSet(false, true)) + procedure.exception(graph, throwable); + } + }); + + if(excepted.get()) return; + + if (issues.get() == 0) { + // This content does not have directly attached issues, try to look + // for some in the child components. + graph.asyncRequest(new ChildMaxIssueSeverity(parameter, parameter2, parameter3), procedure); + } else { + // Try local issues first + graph.asyncRequest(new MaxIssueSeveritySingle(parameter), new AsyncProcedure() { + @Override + public void execute(AsyncReadGraph graph, Severity maxSeverity) { + if (maxSeverity == null) + // No severity for local issues, try children next. + graph.asyncRequest(new ChildMaxIssueSeverity(parameter, parameter2, parameter3), procedure); + else + procedure.execute(graph, maxSeverity); + } + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + if(excepted.compareAndSet(false, true)) + procedure.exception(graph, throwable); + } + }); + } } } diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeveritySingle.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeveritySingle.java index e8ed917aa..89816d6fa 100644 --- a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeveritySingle.java +++ b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeveritySingle.java @@ -14,8 +14,12 @@ package org.simantics.issues.common; import java.util.concurrent.atomic.AtomicReference; import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceAsyncRead; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.issues.Severity; @@ -52,11 +56,12 @@ public class MaxIssueSeveritySingle extends ResourceAsyncRead{ @Override public void perform(AsyncReadGraph graph, final AsyncProcedure procedure) { + final IssueResource ISSUE = graph.getService(IssueResource.class); - //System.out.println(getClass().getSimpleName() + ": " + resource); + + AtomicReference maxSeverity = new AtomicReference(); graph.forEachObject(resource, ISSUE.Issue_HasContext_Inverse, new AsyncMultiProcedure() { - AtomicReference maxSeverity = new AtomicReference(); @Override public void execute(AsyncReadGraph graph, final Resource issue) { @@ -69,13 +74,54 @@ public class MaxIssueSeveritySingle extends ResourceAsyncRead{ } @Override public void finished(AsyncReadGraph graph) { - procedure.execute(graph, maxSeverity.get()); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); + + graph.forEachObject(resource, ISSUE.Issue_ContextList_Element_Inverse, new AsyncMultiProcedure() { + @Override + public void execute(AsyncReadGraph graph, final Resource element) { + + graph.asyncRequest(new ResourceRead(element) { + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + Resource list = ListUtils.getListElementList(graph, resource); + return graph.getSingleObject(list, ISSUE.Issue_HasContexts_Inverse); + } + }, new AsyncProcedure() { + + @Override + public void execute(AsyncReadGraph graph, Resource issue) { + /* + * Compare severity of each related issue and find the maximum severity. + * The issues that are not resolved and have active issue source manager + * are taken into account. + */ + acceptIfNotResolved(graph, procedure, ISSUE, issue, maxSeverity); + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + procedure.exception(graph, throwable); + } + }); + + + } + @Override + public void finished(AsyncReadGraph graph) { + } + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + procedure.exception(graph, throwable); + } + }); + + procedure.execute(graph, maxSeverity.get()); + } /** diff --git a/bundles/org.simantics.issues.ontology/graph/Issue.pgraph b/bundles/org.simantics.issues.ontology/graph/Issue.pgraph index 47a8160b5..c68e561f4 100644 --- a/bundles/org.simantics.issues.ontology/graph/Issue.pgraph +++ b/bundles/org.simantics.issues.ontology/graph/Issue.pgraph @@ -27,12 +27,16 @@ ISSUE.ContinuousIssueSource -- ISSUE.Issue.HasContext -- ISSUE.Issue.HasSeverity --> ISSUE.Severity -- ISSUE.Issue.HasContexts --> L0.List -- ISSUE.Issue.HasContexts --> ISSUE.Issue.ContextList -- ISSUE.Issue.contexts ==> "[Resource]" -- ISSUE.Issue.severity ==> "String" -- ISSUE.Issue.resource ==> "String" -- L0.List.ElementPredicate --> L0.Relation TabContribution" -MOD.SymbolCodeStyle : DIA.Style \ No newline at end of file +MOD.SymbolCodeStyle : DIA.Style + +MOD.IssueDecorationStyle : DIA.Style \ No newline at end of file diff --git a/bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph b/bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph index 0255339ac..86171a31a 100644 --- a/bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph +++ b/bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph @@ -420,10 +420,23 @@ MOD.Contributions.Help : VP.ActionContribution VP.ActionContribution.HasCategory VP.EditActionCategory VP.ActionContribution.HasNodeType L0.Entity VP.ActionContribution.HasAction ACTIONS.Help - + +MOD.Contributions.CopyURI : VP.ActionContribution + L0.HasLabel "Copy URI" + VP.ActionContribution.HasImage SILK.clipboard + VP.ActionContribution.HasCategory VP.EditActionCategory + VP.ActionContribution.HasNodeType L0.Entity + VP.ActionContribution.HasNodeType MBC.Variable + VP.ActionContribution.HasAction ACTIONS.CopyURI + VP.ActionContribution.IsVisibleIf _ : VP.AndTest + VP.AndTest.HasTest + _ : VP.InDevelopmentModeTest + _ : VP.HasURITest + // Actions MAC VP.BrowseContext.HasActionContribution MOD.Contributions.Help + VP.BrowseContext.HasActionContribution MOD.Contributions.CopyURI VP.BrowseContext.HasActionContribution _ : VP.ActionContribution L0.HasLabel "Migrate" VP.ActionContribution.HasImage SILK.star @@ -659,6 +672,7 @@ ACTIONS.CompilePGraphs : ACT.Action //ACTIONS.MigrateMasterTypical : ACT.Action ACTIONS.RenameDiagramComponents : ACT.Action ACTIONS.Help : ACT.Action +ACTIONS.CopyURI : ACT.Action ACTIONS.NavigateToSubstructure @MOD.sclAction "navigateToSubstructureAction" diff --git a/bundles/org.simantics.modeling.ui/adapters.xml b/bundles/org.simantics.modeling.ui/adapters.xml index 891ac0d46..495e4e406 100644 --- a/bundles/org.simantics.modeling.ui/adapters.xml +++ b/bundles/org.simantics.modeling.ui/adapters.xml @@ -439,4 +439,10 @@ + + + + + \ No newline at end of file diff --git a/bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl b/bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl index a662f57f4..436557f31 100644 --- a/bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl +++ b/bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl @@ -97,7 +97,7 @@ importJava "org.simantics.browsing.ui.content.LabelDecorator" where Decorates the given label with the name of the UI column which the label is for and the index of this label within its parenting INodeContext. Returns the decorated Label """ - decorateLabel :: LabelDecorator -> String -> String -> Integer -> String + decorateLabel :: LabelDecorator -> String -> String -> Integer -> Maybe String decorateForeground :: LabelDecorator -> a -> String -> Integer -> a decorateBackground :: LabelDecorator -> a -> String -> Integer -> a decorateFont :: LabelDecorator -> Maybe a -> String -> Integer -> Maybe a diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/e4/ImportSVGPNG.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/e4/ImportSVGPNG.java index 931bfdf3d..b864c4bcf 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/e4/ImportSVGPNG.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/e4/ImportSVGPNG.java @@ -36,7 +36,12 @@ import org.simantics.db.common.request.IndexRoot; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; +import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints; +import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager; import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.participant.MouseUtil; import org.simantics.g2d.participant.MouseUtil.MouseInfo; import org.simantics.modeling.ModelingResources; @@ -112,10 +117,12 @@ public class ImportSVGPNG { IResourceEditorInput input = (IResourceEditorInput)viewer.getEditorInput(); Resource composite = input.getResource(); - addSVG(mpos.getX(), mpos.getY(), composite); + IDiagram idiagram = viewer.getAdapter(IDiagram.class); + + addSVG(mpos.getX(), mpos.getY(), composite, idiagram); } - public static void addSVG(final double mposX, final double mposY, final Resource composite) { + public static void addSVG(final double mposX, final double mposY, final Resource composite, IDiagram idiagram) { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); @@ -135,9 +142,20 @@ public class ImportSVGPNG { @Override public void perform(WriteGraph g) throws DatabaseException { - Commands.get(g, "Simantics/Diagram/createSVGElement") + Object svg = Commands.get(g, "Simantics/Diagram/createSVGElementR") .execute(g, g.syncRequest(new IndexRoot(composite)), composite, suffix(filename), data, mposX, mposY); + + if (svg != null && svg instanceof Resource) { + Resource resource = (Resource) svg; + // 7. Put the element on all the currently active layers if possible. + IModifiableSynchronizationContext context = idiagram.getHint(SynchronizationHints.CONTEXT); + GraphLayerManager glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER); + if (glm != null) { + glm.removeFromAllLayers(g, resource); + glm.putElementOnVisibleLayers(idiagram, g, resource); + } + } } }); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java index b5381917d..1762dea7f 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java @@ -727,9 +727,7 @@ public class DiagramViewer addKeyBindingParticipants(ctx); // Grid & Ruler & Background - ctx.add(new GridPainter()); - ctx.add(new RulerPainter()); - ctx.add(new BackgroundPainter()); + addGridRulerBackgroundParticipants(ctx); h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE)); h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS)); @@ -776,6 +774,12 @@ public class DiagramViewer ctx.setLocked(false); } + protected void addGridRulerBackgroundParticipants(CanvasContext ctx) { + ctx.add(new GridPainter()); + ctx.add(new RulerPainter()); + ctx.add(new BackgroundPainter()); + } + protected void loadPageSettings(ICanvasContext ctx) { DiagramDesc diagramDesc = null; diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromIssue.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromIssue.java index 6af1ff84b..7fd13bbdd 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromIssue.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromIssue.java @@ -14,12 +14,16 @@ package org.simantics.modeling.ui.diagramEditor; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.List; +import java.util.Set; +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; -import org.simantics.db.common.utils.ListUtils; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; import org.simantics.diagram.content.ConnectionUtil; import org.simantics.diagram.flag.FlagUtil; import org.simantics.diagram.stubs.DiagramResource; @@ -27,8 +31,14 @@ import org.simantics.issues.ontology.IssueResource; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.ui.Activator; -import org.simantics.ui.SimanticsUI; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.ui.selection.AnyResource; +import org.simantics.ui.selection.AnyVariable; +import org.simantics.ui.selection.WorkbenchSelectionContentType; +import org.simantics.ui.selection.WorkbenchSelectionElement; import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.ISelectionUtils; /** * @author Tuukka Lehtonen @@ -38,7 +48,7 @@ public class OpenDiagramFromIssue extends AbstractResourceEditorAdapter { private static final String EDITOR_ID = "org.simantics.modeling.ui.plainDiagramEditor"; public OpenDiagramFromIssue() { - super("Open Diagram Containing Referenced Element", Activator.COMPOSITE_ICON); + super("Open Diagram Containing Referenced Component", Activator.COMPOSITE_ICON); } protected String getEditorId() { @@ -46,88 +56,147 @@ public class OpenDiagramFromIssue extends AbstractResourceEditorAdapter { } @Override - public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException { - return findElement(g, r) != null; + public boolean canHandle(ReadGraph g, Object input) throws DatabaseException { + return extractContext(g, input) != null; } @Override - public void openEditor(final Resource r) throws Exception { - SimanticsUI.getSession().asyncRequest(new ReadRequest() { + public void openEditor(Object input) throws Exception { + Simantics.getSession().asyncRequest(new ReadRequest() { @Override public void run(ReadGraph g) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(g); - ModelingResources MOD = ModelingResources.getInstance(g); - - Resource element = findElement(g, r); - if(element == null) return; - - System.err.println("element " + g.getURI(element)); - - Resource diagram = g.getSingleObject(element, L0.PartOf); - Resource composite = g.getSingleObject(diagram, MOD.DiagramToComposite); - - OpenDiagramFromConfigurationAdapter.openEditor(g, composite, getEditorId(), Collections.singleton(element)); - + Pair> data = extractContext(g, input); + if (data != null) + OpenDiagramFromConfigurationAdapter.openEditor(g, data.first, getEditorId(), data.second); } }); } - private static Resource findConfigurationForElement(ReadGraph graph, Resource element) throws DatabaseException { + private static Pair> extractContext(ReadGraph graph, Object input) throws DatabaseException { + Pair p = extractInput(graph, input); + Pair> result = p.first != null ? findConfigurationAndObjects(graph, p.first) : null; + if (result == null && p.second != null) + result = findConfigurationAndObjects(graph, p.second); + return result; + } - Layer0 L0 = Layer0.getInstance(graph); - ModelingResources MOD = ModelingResources.getInstance(graph); + protected static T extractContent(ReadGraph graph, Object input, WorkbenchSelectionContentType contentType, Class contentClass) throws DatabaseException { + if (contentClass.isInstance(input)) + return contentClass.cast(input); + if (input instanceof WorkbenchSelectionElement) { + WorkbenchSelectionElement single = (WorkbenchSelectionElement) input; + if (single != null) + return single.getContent(contentType); + } + return ISelectionUtils.filterSingleSelection(input, contentClass); + } - Resource diagram = graph.getPossibleObject(element, L0.PartOf); - if (diagram == null) return null; + protected static Pair extractInput(ReadGraph graph, Object input) throws DatabaseException { + return Pair.make( + extractContent(graph, input, new AnyVariable(graph), Variable.class), + extractContent(graph, input, new AnyResource(graph), Resource.class)); + } - return graph.getPossibleObject(diagram, MOD.DiagramToComposite); - + protected static Pair> findConfigurationAndObjects(ReadGraph graph, Resource issue) throws DatabaseException { + IssueResource ISSUE = IssueResource.getInstance(graph); + if (!graph.isInstanceOf(issue, ISSUE.Issue)) + return null; + List contexts = graph.getRelatedValue2(issue, ISSUE.Issue_contexts); + return contexts != null ? findConfigurationAndObjects(graph, contexts) : null; } - - private static Resource findElement(ReadGraph graph, Resource issue) throws DatabaseException { - - IssueResource ISSUE = IssueResource.getInstance(graph); - DiagramResource DIA = DiagramResource.getInstance(graph); - - if(!graph.isInstanceOf(issue, ISSUE.Issue)) return null; - - Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts); - for(Resource context : ListUtils.toList(graph, list)) { - if(graph.isInstanceOf(context, DIA.Element) && !graph.isInstanceOf(context, DIA.Diagram)) { - return context; - } - - } - - return null; - + + protected static Pair> findConfigurationAndObjects(ReadGraph graph, Variable v) throws DatabaseException { + List contexts = v.getPossiblePropertyValue(graph, IssueResource.getInstance(graph).Issue_contexts); + return contexts != null ? findConfigurationAndObjects(graph, contexts) : null; + } + + protected static Pair> findConfigurationAndObjects(ReadGraph graph, List contexts) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + + for(Resource context : contexts) { + Set types = graph.getTypes(context); + if (types.contains(DIA.Element)) { + Resource config = findConfigurationForElement(graph, context); + if (config != null) { + Collection elements = Collections.singleton(context); + return Pair.make(config, elements); + } + } else if (types.contains(STR.Component) && !types.contains(STR.Composite)) { + Resource config = graph.getPossibleObject(context, L0.PartOf); + if (config != null) { + return Pair.make(config, findElementObjects(graph, context)); + } + } else if (types.contains(STR.Connection)) { + Resource element = graph.getPossibleObject(context, MOD.ConnectionToDiagramConnection); + if (element != null) { + Resource config = findConfigurationForElement(graph, element); + if (config != null) { + return Pair.make(config, Collections.singleton(element)); + } + } + } + } + + return null; } - public static Collection findElementObjects(ReadGraph g, Resource module) throws DatabaseException { + protected static Resource findConfigurationForElement(ReadGraph graph, Resource element) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + Resource diagram = graph.getPossibleObject(element, L0.PartOf); + if (diagram == null) return null; + return graph.getPossibleObject(diagram, MOD.DiagramToComposite); + } + + protected static Collection findElementObjects(ReadGraph g, Resource component) throws DatabaseException { + Collection result = findElementObjects(g, component, ""); + ModelingResources MOD = ModelingResources.getInstance(g); + for (Resource element : g.getObjects(component, MOD.HasParentComponent_Inverse)) + result.add(element); + return result; + } + + public static Collection findElementObjects(ReadGraph g, Resource component, String rviFromComponent) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); DiagramResource DIA = DiagramResource.getInstance(g); ModelingResources MOD = ModelingResources.getInstance(g); - final Collection selectedObjects = new ArrayList(); - for (Resource element : g.getObjects(module, MOD.ComponentToElement)) { - if (g.isInstanceOf(element, DIA.Flag) && FlagUtil.isExternal(g, element)) { - // Use external flag primarily if one exists in the correspondences - selectedObjects.clear(); - selectedObjects.add(element); - break; - } else if (g.isInstanceOf(element, DIA.RouteGraphConnection)) { - selectedObjects.add(element); - } else if (g.isInstanceOf(element, DIA.Connection)) { - // Okay, we need to find a part of the connection - ConnectionUtil cu = new ConnectionUtil(g); - cu.gatherConnectionParts(element, selectedObjects); - } else { - selectedObjects.add(element); + final Collection selectedObjects = new ArrayList<>(4); + if (rviFromComponent.isEmpty()) { + // The selected objects are configuration objects + for (Resource element : g.getObjects(component, MOD.ComponentToElement)) { + if (g.isInstanceOf(element, DIA.Flag) && FlagUtil.isExternal(g, element)) { + // Use external flag primarily if one exists in the correspondences + selectedObjects.clear(); + selectedObjects.add(element); + break; + } else if (g.isInstanceOf(element, DIA.RouteGraphConnection)) { + selectedObjects.add(element); + } else if (g.isInstanceOf(element, DIA.Connection)) { + // Okay, we need to find a part of the connection + ConnectionUtil cu = new ConnectionUtil(g); + cu.gatherConnectionParts(element, selectedObjects); + } else { + selectedObjects.add(element); + } + } + } else { + // The selected objects are generated components + for (Resource refElement : g.getObjects(component, MOD.HasParentComponent_Inverse)) { + Resource relation = g.getPossibleObject(refElement, MOD.HasReferenceRelation); + if (relation != null) { + String suffix = g.getPossibleRelatedValue(relation, L0.HasName, Bindings.STRING); + if (suffix != null) { + if (rviFromComponent.equals(suffix)) { + selectedObjects.add(refElement); + } + } + } } - } - for(Resource element : g.getObjects(module, MOD.HasParentComponent_Inverse)) { - selectedObjects.add(element); } return selectedObjects; - } + } } diff --git a/bundles/org.simantics.modeling/adapters.xml b/bundles/org.simantics.modeling/adapters.xml index 0e3870c35..b74449f82 100644 --- a/bundles/org.simantics.modeling/adapters.xml +++ b/bundles/org.simantics.modeling/adapters.xml @@ -161,6 +161,8 @@ + diff --git a/bundles/org.simantics.modeling/scl/Simantics/Diagram.scl b/bundles/org.simantics.modeling/scl/Simantics/Diagram.scl index bf5c589e8..0ee3e9d28 100644 --- a/bundles/org.simantics.modeling/scl/Simantics/Diagram.scl +++ b/bundles/org.simantics.modeling/scl/Simantics/Diagram.scl @@ -149,9 +149,15 @@ hasRandomIdentifier entity = runProc (claimRelatedValue_ entity L0.identifier GU """Returns all diagrams of the given model.""" diagramsOf :: Model -> [Diagram] -diagramsOf model = recurse - DIA.Diagram - (configurationOf model) +diagramsOf model = diagramsUnder $ configurationOf model + +""" +Returns all diagrams under the specified diagram folder. +The parameter can also be the configuration root `configurationOf` +in which case this function returns the same as `diagramsOf model`. +""" +diagramsUnder :: DiagramFolder -> [Resource] +diagramsUnder folder = recurse DIA.Diagram folder where recurse t r = do cs = children r @@ -805,8 +811,10 @@ setTransform element transform = claimRelatedValueWithType element DIA.HasTransf importJava "org.simantics.modeling.svg.CreateSVGElement" where createSVGElement :: Resource -> String -> ByteArray -> Double -> Double -> () + createSVGElementR :: Resource -> String -> ByteArray -> Double -> Double -> Resource importSVGElement :: Resource -> File -> Double -> Double -> () + importSVGElementR :: Resource -> File -> Double -> Double -> Resource importJava "org.simantics.diagram.synchronization.graph.RemoveElement" where removeElement :: Resource -> Resource -> () diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ComponentTypeScriptRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ComponentTypeScriptRequest.java index 53b601fa2..e5ae63935 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ComponentTypeScriptRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ComponentTypeScriptRequest.java @@ -13,6 +13,7 @@ import org.simantics.db.request.Read; import org.simantics.scl.compiler.environment.LocalEnvironment; import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification; import org.simantics.scl.compiler.errors.CompilationError; +import org.simantics.scl.compiler.errors.ErrorSeverity; import org.simantics.scl.compiler.module.repository.ImportFailure; import org.simantics.scl.compiler.module.repository.ImportFailureException; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; @@ -47,7 +48,7 @@ public class ComponentTypeScriptRequest implements Read errors = new ArrayList(); for (ImportFailure failure : cause.failures) { - errors.add(new CompilationError(0, failure.toString())); + errors.add(new CompilationError(0, failure.toString(), ErrorSeverity.IMPORT_ERROR)); } return new ComponentTypeScriptResult(errors, null); } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java index 511eeb3fa..2afdac992 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java @@ -91,6 +91,7 @@ import org.simantics.db.layer0.adapter.CopyHandler; import org.simantics.db.layer0.adapter.GenericRelationIndex; import org.simantics.db.layer0.adapter.Instances; import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; +import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex; import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory; import org.simantics.db.layer0.genericrelation.IndexedRelations; import org.simantics.db.layer0.migration.MigrationUtils; @@ -704,7 +705,7 @@ public class ModelingUtils { } public static List searchByTypeShallow(ReadGraph graph, Resource model, Resource type) throws DatabaseException { - return filterByIndexRoot(graph, model, searchByType(graph, model, type)); + return graph.syncRequest(new QueryIndex(model, type, ""), TransientCacheListener.>instance()); } public static List searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException { @@ -721,7 +722,7 @@ public class ModelingUtils { } public static List searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException { - return filterByIndexRoot(graph, model, searchByQuery(graph, model, query)); + return graph.syncRequest(new QueryIndex(model, Layer0.getInstance(graph).Entity, query), TransientCacheListener.>instance()); } public static List searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException { @@ -774,7 +775,7 @@ public class ModelingUtils { } public static List searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException { - return filterByIndexRoot(graph, model, searchByTypeAndName(graph, model, type, name)); + return graph.syncRequest(new QueryIndex(model, type, name), TransientCacheListener.>instance()); } /** diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/CopyURI.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/CopyURI.java new file mode 100644 index 000000000..cdb56beea --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/CopyURI.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2017 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.actions; + +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.Display; +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.db.layer0.request.PossibleURI; +import org.simantics.db.layer0.request.VariableURI; +import org.simantics.db.layer0.variable.Variable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Jani Simomaa + * @since 1.30.0 + */ +public class CopyURI implements ActionFactory { + + private static final Logger LOGGER = LoggerFactory.getLogger(CopyURI.class); + + @Override + public Runnable create(Object target) { + return () -> { + try { + String uri = getPossibleURI(target); + if (uri != null) { + Clipboard cb = new Clipboard(Display.getCurrent()); + cb.setContents(new Object[] { uri }, new Transfer[] { TextTransfer.getInstance() }); + } + } catch (Exception e) { + LOGGER.error("Could not get URI for input {} to copy to clipboard", target, e); + } + }; + } + + private String getPossibleURI(Object input) throws DatabaseException { + if (input instanceof Resource) { + return Simantics.getSession().syncRequest(new PossibleURI((Resource) input)); + } else if (input instanceof Variable) { + return Simantics.getSession().syncRequest(new VariableURI((Variable) input)); + } + return null; + } + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java index 307a32ccc..a4c1c4b2a 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java @@ -153,4 +153,14 @@ public class GraphPropertyRelation implements SCLRelation { w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE), parameters[1].toVal(compilationContext, w)); } + + @Override + public Type getEnforceEffect() { + return Types.WRITE_GRAPH; + } + + @Override + public Type getQueryEffect() { + return Types.READ_GRAPH; + } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java index 331cef2cb..f1c8a79f8 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java @@ -183,4 +183,14 @@ public class GraphRelation implements SCLRelation { w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE), parameters[1].toVal(compilationContext, w)); } + + @Override + public Type getEnforceEffect() { + return Types.WRITE_GRAPH; + } + + @Override + public Type getQueryEffect() { + return Types.READ_GRAPH; + } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/svg/CreateSVGElement.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/svg/CreateSVGElement.java index 994d417c9..1f302a64d 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/svg/CreateSVGElement.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/svg/CreateSVGElement.java @@ -19,6 +19,10 @@ import org.simantics.utils.FileUtils; public class CreateSVGElement { public static void createSVGElement(WriteGraph g, Resource diagram, String suffix, byte[] data, double mposX, double mposY) throws DatabaseException { + createSVGElement(g, diagram, suffix, data, mposX, mposY); + } + + public static Resource createSVGElementR(WriteGraph g, Resource diagram, String suffix, byte[] data, double mposX, double mposY) throws DatabaseException { Layer0 L0 = Layer0.getInstance(g); DiagramResource DIA = DiagramResource.getInstance(g); @@ -50,19 +54,22 @@ public class CreateSVGElement { throw new DatabaseException("Unknown image format " + suffix); OrderedSetUtils.addFirst(g, diagram, element); g.claim(diagram, L0.ConsistsOf, element); - + return element; } - + public static void importSVGElement(WriteGraph graph, Resource diagram, File file, double posX, double posY) throws DatabaseException, IOException { - + importSVGElementR(graph, diagram, file, posX, posY); + } + + public static Resource importSVGElementR(WriteGraph graph, Resource diagram, File file, double posX, double posY) throws DatabaseException, IOException { final byte[] data = FileUtils.readFile(file); - createSVGElement(graph, diagram, suffix(file.getName()), data, posX, posY); + return createSVGElementR(graph, diagram, suffix(file.getName()), data, posX, posY); } - + private static String suffix(String fileName) { int len = fileName.length(); if(len < 3) return null; else return fileName.substring(len-3,len).toLowerCase(); } - + } diff --git a/bundles/org.simantics.platform.ui.ontology/graph/PlatformUIViews.pgraph b/bundles/org.simantics.platform.ui.ontology/graph/PlatformUIViews.pgraph index a265df8b1..eeab91d81 100644 --- a/bundles/org.simantics.platform.ui.ontology/graph/PlatformUIViews.pgraph +++ b/bundles/org.simantics.platform.ui.ontology/graph/PlatformUIViews.pgraph @@ -101,7 +101,7 @@ VIEWS.SharedLibraryContribution : SWT.TypedVariableTabContribution //VIEWS.SharedLibraryContribution2 : SWT.TypedVariableTabContribution // SEL.AbstractVariableTabContribution.HasPriority 1 -// SEL.AbstractTypedVariableTabContribution.HasType L0.SharedOntology +// SEL.AbstractTypedTabContribution.HasType L0.SharedOntology // SWT.TypedVariableTabContribution.HasView SharedLibraries // L0.HasLabel "Shared Libraries" diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ImageNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ImageNode.java index df35e968e..43cf64eb0 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ImageNode.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ImageNode.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.simantics.scenegraph.g2d.nodes; +import java.awt.AlphaComposite; +import java.awt.Composite; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; @@ -28,6 +30,7 @@ public class ImageNode extends G2DNode { protected Boolean visible = Boolean.TRUE; protected BufferedImage img = null; + protected float alpha = 1.0f; @SyncField("visible") public void setVisible(Boolean visible) { @@ -50,6 +53,10 @@ public class ImageNode extends G2DNode { img = src; } + public void setAlpha(float alpha) { + this.alpha = Math.max(0.0f, Math.min(alpha, 1.0f)); + } + @Override public void render(Graphics2D g) { if (!visible || img == null) return; @@ -65,8 +72,17 @@ public class ImageNode extends G2DNode { // Rectangle2D b = parent.getBoundsInLocal(); // g.drawImage(img, (int)b.getMinX(), (int)b.getMinY(), (int)b.getWidth()+(int)b.getMinX(), (int)b.getHeight()+(int)b.getMinY(), 0, 0, img.getWidth(), img.getHeight(), null); // } + + Composite old = null; + if (alpha < 1.0f) { + old = g.getComposite(); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); + } + g.drawImage(img, 0, 0, null); + if (old != null) + g.setComposite(old); if (ot != null) g.setTransform(ot); } diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java index f7e0d1e5c..27c1c1fd2 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java @@ -57,7 +57,7 @@ public class RulerNode extends G2DNode { public void render(Graphics2D g) { if (!enabled) return; - + AffineTransform tr = g.getTransform(); double scaleX = Math.abs(tr.getScaleX()); double scaleY = Math.abs(tr.getScaleY()); @@ -109,7 +109,9 @@ public class RulerNode extends G2DNode { // Vertical ruler for(double x = offsetX%stepX-stepX; x < bounds.getMaxX(); x+=stepX) { if(x > 20) { - String str = formatValue((x-offsetX)/scaleX); + double val = (x-offsetX)/scaleX / getTransform().getScaleX(); + double modifiedValue = modifyHorizontalValue(val); + String str = formatValue(modifiedValue); FontMetrics fm = g.getFontMetrics(); Rectangle2D r = fm.getStringBounds(str, g); if((x-r.getWidth()/2) > previousText) { @@ -140,10 +142,9 @@ public class RulerNode extends G2DNode { previousText = -100; for(double y = offsetY%stepY-stepY; y < bounds.getMaxY(); y+=stepY) { if(y > 20) { - double val = (y-offsetY)/scaleY; - if (MAP_Y_SCALING) - val = Math.toDegrees(Math.atan(Math.sinh(Math.toRadians(val)))); - String str = formatValue(val); + double val = (y-offsetY)/scaleY / getTransform().getScaleY(); + double modifiedValue = modifyVerticalValue(val); + String str = formatValue(modifiedValue); FontMetrics fm = g.getFontMetrics(); Rectangle2D r = fm.getStringBounds(str, g); if(y-1+r.getHeight()/2 > previousText) { @@ -175,6 +176,26 @@ public class RulerNode extends G2DNode { g.setTransform(tr); } + /** + * A method for subclasses to alter the actual X-value of the ruler + * + * @param value + * @return possibly modified X-value + */ + protected double modifyHorizontalValue(double value) { + return value; + } + + /** + * A method for subclasses to alter the actual Y-value of the ruler + * + * @param value + * @return possibly modified Y-value + */ + protected double modifyVerticalValue(double value) { + return value; + } + private static final transient int MAX_DIGITS = 5; private static final transient double EPSILON = 0.01; private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 4); diff --git a/bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF index 10a24ddce..1007cf675 100644 --- a/bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF @@ -32,6 +32,7 @@ Export-Package: org.cojen.classfile, org.simantics.scl.compiler.elaboration.expressions.block, org.simantics.scl.compiler.elaboration.expressions.lhstype, org.simantics.scl.compiler.elaboration.expressions.list, + org.simantics.scl.compiler.elaboration.expressions.visitors, org.simantics.scl.compiler.elaboration.fundeps, org.simantics.scl.compiler.elaboration.java, org.simantics.scl.compiler.elaboration.macros, diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java new file mode 100644 index 000000000..57858a5cf --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java @@ -0,0 +1,89 @@ +package org.simantics.scl.compiler.commands; + + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; + +import org.simantics.scl.compiler.errors.Failable; +import org.simantics.scl.compiler.errors.Failure; +import org.simantics.scl.compiler.module.Module; +import org.simantics.scl.compiler.module.repository.ModuleRepository; +import org.simantics.scl.compiler.module.repository.UpdateListener; +import org.simantics.scl.compiler.source.StringModuleSource; +import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository; +import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler; +import org.simantics.scl.runtime.reporting.SCLReportingHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CommandSessionWithModules { + private static final Logger LOGGER = LoggerFactory.getLogger(CommandSessionWithModules.class); + + private MapModuleSourceRepository localModuleSourceRepository; + private ModuleRepository moduleRepository; + private CommandSession commandSession; + + private static final SCLReportingHandler DEFAULT_REPORTING_HANDLER = new AbstractSCLReportingHandler() { + @Override + public void print(String text) { + CommandSessionWithModules.LOGGER.info(text); + } + }; + + public CommandSessionWithModules(ModuleRepository parentRepository) { + this.localModuleSourceRepository = new MapModuleSourceRepository(); + this.moduleRepository = new ModuleRepository(parentRepository, localModuleSourceRepository); + this.commandSession = new CommandSession(moduleRepository, DEFAULT_REPORTING_HANDLER); + this.commandSession.setDependenciesListener(new UpdateListener() { + @Override + public void notifyAboutUpdate() { + commandSession.updateRuntimeEnvironment(true); + } + }); + } + + public CommandSession getCommandSession() { + return commandSession; + } + + /** + * Puts the given module to the local module repository. Returns null, if the + * compilation of the module succeeded or a string containing the compilation + * errors, if it failed. + */ + public String putModule(String moduleName, String moduleText) { + StringModuleSource moduleSource = new StringModuleSource(moduleName, moduleText); + synchronized(localModuleSourceRepository) { + localModuleSourceRepository.addModuleDescriptor(moduleSource); + } + Failable module = moduleRepository.getModule(moduleName); + if(module.didSucceed()) + return null; + else + return ((Failure)module).toString(moduleText); + } + + /** + * Runs commands read from commandReader and writes responses to + * responseWriter. + */ + public void runCommands(Reader commandReader, Writer responseWriter) { + SCLReportingHandler handler = new AbstractSCLReportingHandler() { + @Override + public void printCommand(String command) { + // Don't echo commands + } + @Override + public void print(String text) { + try { + responseWriter.write(text + "\n"); + responseWriter.flush(); + } catch (IOException e) { + CommandSessionWithModules.LOGGER.error("Writing reponse failed.", e); + } + } + }; + commandSession.execute(commandReader, handler); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java index 50729430d..183d85796 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java @@ -20,6 +20,7 @@ public class Names { public static final Name JavaBuiltin_unsafeCoerce = Name.create("JavaBuiltin", "unsafeCoerce"); public static final Name MList_add = Name.create("MList", "add"); public static final Name MList_create = Name.create("MList", "create"); + public static final Name MList_freeze = Name.create("MList", "freeze"); public static final Name MList_removeLast = Name.create("MList", "removeLast"); public static final TCon MList_T = Types.con("MList", "T"); public static final Name MSet_add = Name.create("MSet", "add"); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java index fccf26815..ff5ee3b29 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java @@ -61,7 +61,9 @@ import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.environment.EnvironmentFactory; import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.ErrorLog; +import org.simantics.scl.compiler.errors.ErrorSeverity; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable; @@ -179,7 +181,7 @@ public class Elaboration { compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module); } catch (ImportFailureException e) { for(ImportFailure failure : e.failures) - errorLog.log(failure.location, failure.toString()); + errorLog.log(new CompilationError(failure.location, failure.toString(), ErrorSeverity.IMPORT_ERROR)); return; } for(ImportDeclaration importAst : importsAst) @@ -1113,6 +1115,7 @@ public class Elaboration { int constructorTag = 0; for(Constructor constructor : dataType.constructors) { SCLValue value = new SCLValue(constructor.name); + value.definitionLocation = constructor.loc; SCLConstructor sclConstructor = new SCLConstructor( constructor.name.name, diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java index 58bb98a41..52b8692d8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java @@ -408,7 +408,7 @@ public class TypeChecking { for(TransformationRule rule : module.getRules()) for(Query[] queries : rule.sections.values()) for(Query query : queries) - query.collectRefs(allRefs, refs); + query.collectRefs(allRefs, refs); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java index 7de438d15..336ed04e3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java @@ -8,7 +8,7 @@ import org.simantics.scl.compiler.types.Type; public class LocalVariableConstant extends Constant { - LocalVariable var; + public LocalVariable var; public LocalVariableConstant(Type type, LocalVariable var) { super(type); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java index f44609e6c..e0921dc10 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java @@ -5,6 +5,7 @@ import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation; import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation; +import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext.ExistentialFrame; @@ -12,7 +13,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.ERecord; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor; import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; @@ -24,7 +24,6 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public class CHRLiteral extends Symbol { @@ -38,15 +37,20 @@ public class CHRLiteral extends Symbol { public boolean negated; public boolean passive = true; - public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) { + public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean killAfterMatch, boolean negated) { this.location = location; this.relation = relation; this.parameters = parameters; - this.killAfterMatch = remove; + this.killAfterMatch = killAfterMatch; this.negated = negated; } public void resolve(TranslationContext context) { + if(relation == SpecialCHRRelation.ASSIGN) { + parameters[1] = parameters[1].resolve(context); + parameters[0] = parameters[0].resolveAsPattern(context); + return; + } if(parameters != null) { for(int i=0;i allRefs, TIntHashSet refs) { - for(Expression parameter : parameters) - parameter.collectRefs(allRefs, refs); - if(typeConstraintEvidenceParameters != null) - for(Expression parameter : typeConstraintEvidenceParameters) - parameter.collectRefs(allRefs, refs); - } - public void checkType(TypingContext context) { if(relation == SpecialCHRRelation.EXECUTE) { if(parameters.length != 1) @@ -123,6 +119,11 @@ public class CHRLiteral extends Symbol { parameters[0] = parameters[0].checkIgnoredType(context); typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY; } + else if(relation == SpecialCHRRelation.ASSIGN) { + parameters[1] = parameters[1].inferType(context); + parameters[0] = parameters[0].checkTypeAsPattern(context, parameters[1].getType()); + typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY; + } else { TVar[] typeVariables = relation.getTypeVariables(); typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length]; @@ -147,22 +148,6 @@ public class CHRLiteral extends Symbol { parameter.collectVars(allVars, vars); } - public void forVariables(VariableProcedure procedure) { - for(Expression parameter : parameters) - parameter.forVariables(procedure); - if(typeConstraintEvidenceParameters != null) - for(Expression parameter : typeConstraintEvidenceParameters) - parameter.forVariables(procedure); - } - - public void collectFreeVariables(THashSet vars) { - for(Expression parameter : parameters) - parameter.collectFreeVariables(vars); - if(typeConstraintEvidenceParameters != null) - for(Expression parameter : typeConstraintEvidenceParameters) - parameter.collectFreeVariables(vars); - } - public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { this.location = loc; @@ -186,9 +171,14 @@ public class CHRLiteral extends Symbol { return b.toString(); } - public void collectQueryEffects(THashSet effects) { - } - - public void collectEnforceEffects(THashSet effects) { + public CHRLiteral replace(ReplaceContext context) { + CHRLiteral copy = new CHRLiteral(location, relation, context.replace(parameters), killAfterMatch, negated); + for(int i=0;i allRefs, TIntHashSet refs) { - for(CHRLiteral literal : literals) - literal.collectRefs(allRefs, refs); - } - public void checkType(TypingContext context) { for(CHRLiteral literal : literals) literal.checkType(context); @@ -43,17 +38,7 @@ public class CHRQuery extends Symbol { for(CHRLiteral literal : literals) literal.collectVars(allVars, vars); } - - public void forVariables(VariableProcedure procedure) { - for(CHRLiteral literal : literals) - literal.forVariables(procedure); - } - - public void collectFreeVariables(THashSet vars) { - for(CHRLiteral literal : literals) - literal.collectFreeVariables(vars); - } - + public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { this.location = loc; @@ -62,7 +47,7 @@ public class CHRQuery extends Symbol { } } - public boolean createQueryPlan(QueryPlanningContext context, Expression inputFact, int activeLiteralId) { + public boolean createQueryPlan(QueryPlanningContext context, Expression inputFact, int activeLiteralId, CHRConstraint initConstraint) { for(int i=0;i effects); + void collectQueryEffects(THashSet effects); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java index 0c81daafd..78224ebb0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java @@ -11,7 +11,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.parsing.Symbol; @@ -19,7 +18,6 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public class CHRRule extends Symbol { @@ -45,6 +43,10 @@ public class CHRRule extends Symbol { this.body = body; this.existentialVariables = existentialVariables; } + + public CHRRule(long location, CHRQuery head, CHRQuery body) { + this(location, head, body, null); + } public void resolve(TranslationContext context) { context.pushExistentialFrame(); @@ -54,11 +56,6 @@ public class CHRRule extends Symbol { existentialVariables = context.popExistentialFrame(); } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - head.collectRefs(allRefs, refs); - body.collectRefs(allRefs, refs); - } - public void checkType(TypingContext context) { for(Variable variable : existentialVariables) variable.setType(Types.metaVar(Kinds.STAR)); @@ -71,16 +68,6 @@ public class CHRRule extends Symbol { body.collectVars(allVars, vars); } - public void forVariables(VariableProcedure procedure) { - head.forVariables(procedure); - body.forVariables(procedure); - } - - public void collectFreeVariables(THashSet vars) { - head.collectFreeVariables(vars); - body.collectFreeVariables(vars); - } - public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { this.location = loc; @@ -104,7 +91,7 @@ public class CHRRule extends Symbol { Variable activeFact = new Variable("activeFact", constraint.factType); QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables); - if(!head.createQueryPlan(context, new EVariable(activeFact), i)) + if(!head.createQueryPlan(context, new EVariable(activeFact), i, initConstraint)) return; body.createEnforcePlan(context, priority); addPlan(new CHRSearchPlan(constraint, activeFact, context.getPlanOps())); @@ -115,7 +102,7 @@ public class CHRRule extends Symbol { if(!hasLocalActiveLiteral) { Variable activeFact = new Variable("activeFact", initConstraint.factType); QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables); - if(!head.createQueryPlan(context, null, -1)) + if(!head.createQueryPlan(context, new EVariable(activeFact), -1, initConstraint)) return; body.createEnforcePlan(context, priority); /*System.out.println(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java index d670300cb..55bbcfe34 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java @@ -23,7 +23,6 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement; import org.simantics.scl.compiler.environment.AmbiguousNameException; import org.simantics.scl.compiler.errors.Locations; @@ -43,7 +42,6 @@ import org.simantics.scl.compiler.types.Types; 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 CHRRuleset extends Symbol { @@ -123,13 +121,6 @@ public class CHRRuleset extends Symbol { }*/ } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - for(IncludeStatement include : includes) - include.value.collectRefs(allRefs, refs); - for(CHRRule rule : rules) - rule.collectRefs(allRefs, refs); - } - public void checkType(TypingContext context) { for(IncludeStatement include : includes) include.value = include.value.checkType(context, include.ruleset.runtimeRulesetType); @@ -144,20 +135,6 @@ public class CHRRuleset extends Symbol { rule.collectVars(allVars, vars); } - public void forVariables(VariableProcedure procedure) { - for(IncludeStatement include : includes) - include.value.forVariables(procedure); - for(CHRRule rule : rules) - rule.forVariables(procedure); - } - - public void collectFreeVariables(THashSet vars) { - for(IncludeStatement include : includes) - include.value.collectFreeVariables(vars); - for(CHRRule rule : rules) - rule.collectFreeVariables(vars); - } - public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { this.location = loc; @@ -283,7 +260,7 @@ public class CHRRuleset extends Symbol { methodWriter.return_(BooleanConstant.TRUE); } } - if(!includes.isEmpty()) { + if(!includes.isEmpty() || extensible) { { CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext}); initializer = methodWriter.getFunction(); @@ -292,6 +269,10 @@ public class CHRRuleset extends Symbol { new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}), object.getTarget(), methodWriter.getParameters()[0], include.storeVar); } + if(extensible) + methodWriter.apply(Locations.NO_LOCATION, + new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}), + object.getTarget(), methodWriter.getParameters()[0]); methodWriter.return_(NoRepConstant.UNIT); } { @@ -302,6 +283,10 @@ public class CHRRuleset extends Symbol { new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}), object.getTarget(), methodWriter.getParameters()[0], include.storeVar); } + if(extensible) + methodWriter.apply(Locations.NO_LOCATION, + new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}), + object.getTarget(), methodWriter.getParameters()[0]); methodWriter.return_(NoRepConstant.UNIT); } } @@ -324,15 +309,6 @@ public class CHRRuleset extends Symbol { return runtimeRulesetVariable; } - public void collectEffects(THashSet effects) { - for(CHRRule rule : rules) { - for(CHRLiteral literal : rule.head.literals) - literal.collectQueryEffects(effects); - for(CHRLiteral literal : rule.head.literals) - literal.collectEnforceEffects(effects); - } - } - public void addRule(CHRRule rule) { rules.add(rule); rule.parentRuleset = this; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java new file mode 100644 index 000000000..7b5f4ffa6 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java @@ -0,0 +1,148 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; +import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.EBinary; +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.ERecord; +import org.simantics.scl.compiler.elaboration.expressions.EVar; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment; +import org.simantics.scl.compiler.environment.AmbiguousNameException; +import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.errors.Locations; +import org.simantics.scl.compiler.types.Types; + +public class CHRAstAtom extends CHRAstQuery { + public Expression expression; + public boolean remove; + + public CHRAstAtom(Expression expression, boolean remove) { + this.expression = expression; + this.remove = remove; + } + + @Override + public void accept(CHRAstQueryVisitor visitor) { + visitor.visit(this); + } + + public static CHRAstQuery atom(Expression expression) { + boolean remove = false; + if(expression instanceof EVar) { + EVar var = (EVar)expression; + if(var.name.equals("True")) { + CHRAstConjunction query = new CHRAstConjunction(Collections.emptyList()); + query.location = expression.location; + return query; + } + } + else if(expression instanceof EBinary) { + EBinary binary = (EBinary)expression; + if(binary.negation != null && binary.rights.isEmpty()) { + remove = true; + expression = binary.left; + } + // If query is marked for removal, it must be an atom + } + else if(expression instanceof EApply) { + EApply apply = (EApply)expression; + if(apply.function instanceof EVar && ((EVar)apply.function).name.equals("not")) { + Expression subExpression; + if(apply.parameters.length == 1) + subExpression = apply.parameters[0]; + else + subExpression = new EApply( + Locations.combine(apply.parameters[0].location, apply.parameters[apply.parameters.length-1].location), + apply.parameters[0], + Arrays.copyOfRange(apply.parameters, 1, apply.parameters.length)); + CHRAstNegation query = new CHRAstNegation(atom(subExpression)); + query.location = expression.location; + return query; + } + else if(apply.function instanceof EConstant) { + Name valueName = ((EConstant)apply.function).getValue().getName(); + if(valueName.module.equals(Types.BUILTIN) && valueName.name.startsWith("(")) { + CHRAstQuery[] conjuncts = new CHRAstQuery[apply.parameters.length]; + for(int i=0;i literals) { + if(isConstraint(context, expression)) { + literals.add(convertConstraint(remove, expression)); + } + else { + if(remove) + context.getErrorLog().log(location, "Only constraints can be marked for removal"); + else + literals.add(convertExpression(mode, expression)); + } + } + + private static boolean isConstraint(TranslationContext context, Expression expression) { + if(expression instanceof EApply) + expression = ((EApply)expression).function; + else if(expression instanceof ERecord) + expression = ((ERecord)expression).constructor; + if(!(expression instanceof EVar)) + return false; + String name = ((EVar)expression).name; + if(TranslationContext.isConstructorName(name)) + return true; + try { + return Environments.getRelation(context.getEnvironment(), name) != null; + } catch (AmbiguousNameException e) { + return true; + } + } + + private static CHRLiteral convertExpression(CHRQueryTranslationMode mode, Expression expression) { + if(mode.isHead) + return new CHRLiteral(expression.location, SpecialCHRRelation.CHECK, new Expression[] {expression}, false, false); + else + return new CHRLiteral(expression.location, SpecialCHRRelation.EXECUTE, new Expression[] {expression}, false, false); + } + + private static CHRLiteral convertConstraint(boolean remove, Expression expression) { + long location = expression.location; + Expression[] parameters; + FieldAssignment[] fields = null; + if(expression instanceof EApply) { + EApply apply = (EApply)expression; + parameters = apply.parameters; + expression = apply.function; + } + else if(expression instanceof ERecord) { + ERecord record = (ERecord)expression; + parameters = null; + fields = record.fields; + expression = record.constructor; + } + else // if(expression instanceof EVar) + parameters = Expression.EMPTY_ARRAY; + EVar var = (EVar)expression; // this should succeed because of isConstraint test + CHRLiteral literal = new CHRLiteral(location, new UnresolvedCHRRelation(var.location, var.name), + parameters, remove, false); + literal.fields = fields; + return literal; + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java new file mode 100644 index 000000000..2f2654c12 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java @@ -0,0 +1,29 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; +import org.simantics.scl.compiler.elaboration.expressions.Expression; + +public class CHRAstBinds extends CHRAstQuery { + public Expression left; + public Expression right; + + public CHRAstBinds(Expression left, Expression right) { + this.left = left; + this.right = right; + } + + @Override + public void accept(CHRAstQueryVisitor visitor) { + visitor.visit(this); + } + + @Override + protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList literals) { + literals.add(new CHRLiteral(location, SpecialCHRRelation.MEMBER, + new Expression[] { left, right }, false, false)); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java new file mode 100644 index 000000000..1aadb6978 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java @@ -0,0 +1,40 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +import java.util.ArrayList; +import java.util.List; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; + +public class CHRAstConjunction extends CHRAstQuery { + public List conjuncts; + + public CHRAstConjunction(List conjuncts) { + this.conjuncts = conjuncts; + } + + @Override + public void accept(CHRAstQueryVisitor visitor) { + visitor.visit(this); + } + + public static CHRAstQuery conjunction(CHRAstQuery[] conjuncts) { + ArrayList result = new ArrayList(conjuncts.length); + for(CHRAstQuery conjunct : conjuncts) { + if(conjunct instanceof CHRAstConjunction) + result.addAll(((CHRAstConjunction)conjunct).conjuncts); + else + result.add(conjunct); + } + if(result.size() == 1) + return result.get(0); + else + return new CHRAstConjunction(result); + } + + @Override + protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList literals) { + for(CHRAstQuery conjunct : conjuncts) + conjunct.translate(context, mode, literals); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java new file mode 100644 index 000000000..6c5e6e87d --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java @@ -0,0 +1,29 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; +import org.simantics.scl.compiler.elaboration.expressions.Expression; + +public class CHRAstEquals extends CHRAstQuery { + public Expression left; + public Expression right; + + public CHRAstEquals(Expression left, Expression right) { + this.left = left; + this.right = right; + } + + @Override + public void accept(CHRAstQueryVisitor visitor) { + visitor.visit(this); + } + + @Override + protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList literals) { + literals.add(new CHRLiteral(location, mode.isHead ? SpecialCHRRelation.EQUALS : SpecialCHRRelation.ASSIGN, + new Expression[] { left, right }, false, false)); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java new file mode 100644 index 000000000..4f73d666b --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java @@ -0,0 +1,24 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; + +public class CHRAstNegation extends CHRAstQuery { + public CHRAstQuery subquery; + + public CHRAstNegation(CHRAstQuery subquery) { + this.subquery = subquery; + } + + @Override + public void accept(CHRAstQueryVisitor visitor) { + visitor.visit(this); + } + + @Override + protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList literals) { + context.getCompilationContext().errorLog.log(location, "CHR negation is not yet supported."); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java new file mode 100644 index 000000000..e655c78e7 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java @@ -0,0 +1,20 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.CHRQuery; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; +import org.simantics.scl.compiler.internal.parsing.Symbol; + +public abstract class CHRAstQuery extends Symbol { + public CHRQuery translate(TranslationContext context, CHRQueryTranslationMode mode) { + ArrayList literals = new ArrayList(); + translate(context, mode, literals); + return new CHRQuery(literals.toArray(new CHRLiteral[literals.size()])); + } + + protected abstract void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList literals); + + public abstract void accept(CHRAstQueryVisitor visitor); +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java new file mode 100644 index 000000000..3c7b42525 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java @@ -0,0 +1,9 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +public interface CHRAstQueryVisitor { + void visit(CHRAstAtom query); + void visit(CHRAstBinds query); + void visit(CHRAstConjunction query); + void visit(CHRAstEquals query); + void visit(CHRAstNegation query); +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRQueryTranslationMode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRQueryTranslationMode.java new file mode 100644 index 000000000..483c028c2 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRQueryTranslationMode.java @@ -0,0 +1,13 @@ +package org.simantics.scl.compiler.elaboration.chr.ast; + +public enum CHRQueryTranslationMode { + RULE_HEAD(true), + QUERY_HEAD(true), + RULE_BODY(false); + + public final boolean isHead; + + private CHRQueryTranslationMode(boolean isHead) { + this.isHead = isHead; + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java index 4874c14fe..ab37d253a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java @@ -47,5 +47,4 @@ public class AccessFactOp extends PlanOp { if(end != null) end.return_(BooleanConstant.FALSE); } - } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java index 5ef54ea82..730caba73 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java @@ -25,6 +25,4 @@ public class AssignOp extends PlanOp { variable.setVal(expression.toVal(context, w)); planContext.nextOp(w); } - - } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java index a79225604..aa317a2b2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java @@ -17,6 +17,6 @@ public abstract class PlanOp { return b.toString(); } - public abstract void toString(StringBuilder b); + public void toString(StringBuilder b) {} public abstract void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java index 537a2aa9d..56d436f55 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java @@ -8,6 +8,7 @@ import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; import org.simantics.scl.compiler.elaboration.chr.plan.AccessFactOp; import org.simantics.scl.compiler.elaboration.chr.plan.ClaimOp; import org.simantics.scl.compiler.elaboration.chr.plan.ExecuteOp; +import org.simantics.scl.compiler.elaboration.chr.plan.MatchOp; import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp; import org.simantics.scl.compiler.elaboration.chr.planning.items.CheckPrePlanItem; import org.simantics.scl.compiler.elaboration.chr.planning.items.EqualsPrePlanItem; @@ -22,6 +23,7 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.errors.Locations; import gnu.trove.impl.Constants; import gnu.trove.map.hash.TObjectIntHashMap; @@ -64,6 +66,8 @@ public class QueryPlanningContext { case MEMBER: addMember(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority); return; + case ASSIGN: + throw new InternalCompilerError(literal.location, "ASSIGN constraint is not allowed in query compilation."); case EXECUTE: throw new InternalCompilerError(literal.location, "EXECUTE constraint is not allowed in query compilation."); } @@ -223,6 +227,10 @@ public class QueryPlanningContext { for(int i=0;i effects) { + effects.add(Types.PROC); + } + + @Override + public void collectQueryEffects(THashSet effects) { + effects.add(Types.PROC); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java index 6f44bc2ab..fdfa195ac 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java @@ -6,6 +6,8 @@ import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import gnu.trove.set.hash.THashSet; + public class ExternalCHRRelation implements CHRRelation { public final SCLRelation relation; @@ -37,4 +39,14 @@ public class ExternalCHRRelation implements CHRRelation { public String[] getFieldNames() { return relation.getFieldNames(); } + + @Override + public void collectEnforceEffects(THashSet effects) { + effects.add(relation.getEnforceEffect()); + } + + @Override + public void collectQueryEffects(THashSet effects) { + effects.add(relation.getQueryEffect()); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java index c5dbe3c41..8abf73b3e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java @@ -6,11 +6,14 @@ import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; +import gnu.trove.set.hash.THashSet; + public enum SpecialCHRRelation implements CHRRelation { - EQUALS(A, A), - MEMBER(A, Types.list(A)), - CHECK(Types.BOOLEAN), - EXECUTE(Types.UNIT); + EQUALS(A, A), // only in head + ASSIGN(A, A), // only in body + MEMBER(A, Types.list(A)), // only in head + CHECK(Types.BOOLEAN), // only in head + EXECUTE(Types.UNIT); // only in body private final TVar[] typeVariables; private final Type[] parameterTypes; @@ -33,4 +36,12 @@ public enum SpecialCHRRelation implements CHRRelation { public TPred[] getTypeConstraints() { return TPred.EMPTY_ARRAY; } + + @Override + public void collectEnforceEffects(THashSet effects) { + } + + @Override + public void collectQueryEffects(THashSet effects) { + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java index c852062fb..6cf2930de 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java @@ -6,6 +6,9 @@ import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; + +import gnu.trove.set.hash.THashSet; public class UnresolvedCHRRelation extends Symbol implements CHRRelation { public String name; @@ -28,4 +31,14 @@ public class UnresolvedCHRRelation extends Symbol implements CHRRelation { public TPred[] getTypeConstraints() { throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking."); } + + @Override + public void collectEnforceEffects(THashSet effects) { + effects.add(Types.PROC); + } + + @Override + public void collectQueryEffects(THashSet effects) { + effects.add(Types.PROC); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java index 367960dfa..260927b74 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java @@ -3,10 +3,8 @@ package org.simantics.scl.compiler.elaboration.chr.translation; import java.util.ArrayList; import java.util.Arrays; -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; import org.simantics.scl.compiler.elaboration.chr.CHRQuery; -import org.simantics.scl.compiler.elaboration.chr.CHRRule; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation; @@ -16,7 +14,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EBinary; import org.simantics.scl.compiler.elaboration.expressions.ERecord; import org.simantics.scl.compiler.elaboration.expressions.EVar; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement; import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement; import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment; import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator; @@ -131,24 +128,22 @@ public class CHRTranslation { } } - public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) { - ArrayList head = new ArrayList(statement.head.length); - for(ListQualifier qualifier : statement.head) { - CHRLiteral literal = convertListQualifier(context, true, qualifier); + public static CHRQuery convertCHRQuery(TranslationContext context, boolean isHead, ListQualifier[] lqs) { + ArrayList query = new ArrayList(lqs.length); + for(ListQualifier qualifier : lqs) { + CHRLiteral literal = convertListQualifier(context, isHead, qualifier); if(literal != null) - head.add(literal); - } - ArrayList body = new ArrayList(statement.body.length); - for(ListQualifier qualifier : statement.body) { - CHRLiteral literal = convertListQualifier(context, false, qualifier); - if(literal != null) - body.add(literal); + query.add(literal); } + return new CHRQuery(query.toArray(new CHRLiteral[query.size()])); + } + + /*public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) { return new CHRRule(statement.location, - new CHRQuery(head.toArray(new CHRLiteral[head.size()])), - new CHRQuery(body.toArray(new CHRLiteral[body.size()])), + convertCHRQuery(context, true, statement.head), + convertCHRQuery(context, false, statement.body), null); - } + }*/ public static CHRConstraint convertConstraintStatement(TranslationContext context, ConstraintStatement statement) { CHRConstraint constraint = new CHRConstraint(statement.location, statement.name.text, TypeAst.toTypes(context, statement.parameterTypes)); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/ReplaceContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/ReplaceContext.java index 1bb40c5fa..b526cb3f0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/ReplaceContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/ReplaceContext.java @@ -3,8 +3,10 @@ package org.simantics.scl.compiler.elaboration.contexts; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; import gnu.trove.map.hash.THashMap; @@ -37,4 +39,28 @@ public class ReplaceContext { public ReplaceContext(TypingContext typingContext) { this(new THashMap(), new THashMap(), typingContext); } + + public Expression[] replace(Expression[] expressions) { + if(expressions == null) + return null; + Expression[] result = new Expression[expressions.length]; + for(int i=0;i chrConstraintEntries = new ArrayList(); + public CHRRuleset currentRuleset; + static class Entry { String name; Variable variable; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqBasic.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqBasic.java index 80d2a7578..785c27da0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqBasic.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqBasic.java @@ -4,15 +4,7 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; public class EqBasic extends Equation { public Expression left; @@ -37,48 +29,12 @@ public class EqBasic extends Equation { } } - @Override - public void forVariables(VariableProcedure procedure) { - left.forVariables(procedure); - right.forVariables(procedure); - } - - @Override - public void collectFreeVariables(THashSet vars) { - left.collectFreeVariables(vars); - right.collectFreeVariables(vars); - } - - @Override - public void decorate(ExpressionDecorator decorator) { - left = left.decorate(decorator); - right = right.decorate(decorator); - } - - @Override - public void collectEffects(THashSet effects) { - left.collectEffects(effects); - right.collectEffects(effects); - } - @Override public void checkType(TypingContext context) { left = left.inferType(context); right = right.checkType(context, left.getType()); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - left.collectRefs(allRefs, refs); - right.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - left.collectVars(allVars, vars); - right.collectVars(allVars, vars); - } - @Override public void resolve(TranslationContext context) { left = left.resolve(context); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java index c8bf5c120..c72d9433f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java @@ -4,15 +4,7 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; public class EqGuard extends Equation { public Expression guard; @@ -34,41 +26,11 @@ public class EqGuard extends Equation { } } - @Override - public void forVariables(VariableProcedure procedure) { - guard.forVariables(procedure); - } - - @Override - public void collectFreeVariables(THashSet vars) { - guard.collectFreeVariables(vars); - } - - @Override - public void decorate(ExpressionDecorator decorator) { - guard = guard.decorate(decorator); - } - - @Override - public void collectEffects(THashSet effects) { - guard.collectEffects(effects); - } - @Override public void checkType(TypingContext context) { guard = guard.checkIgnoredType(context); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - guard.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - guard.collectVars(allVars, vars); - } - @Override public void resolve(TranslationContext context) { guard = guard.resolve(context); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/Equation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/Equation.java index dbd22037f..cb801a33d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/Equation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/Equation.java @@ -3,28 +3,14 @@ package org.simantics.scl.compiler.elaboration.equation; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.Symbol; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; public abstract class Equation extends Symbol { public static final Equation[] EMPTY_ARRAY = new Equation[0]; public abstract void setLocationDeep(long loc); - public abstract void forVariables(VariableProcedure procedure); - public abstract void collectFreeVariables(THashSet vars); - public abstract void decorate(ExpressionDecorator decorator); - public abstract void collectEffects(THashSet effects); public abstract void checkType(TypingContext context); - public abstract void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs); - public abstract void collectVars(TObjectIntHashMap allVars, TIntHashSet vars); public abstract void resolve(TranslationContext context); public abstract void accept(EquationVisitor visitor); public abstract Equation replace(ReplaceContext context); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java index fbc0a7901..c96218b65 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java @@ -3,14 +3,10 @@ package org.simantics.scl.compiler.elaboration.expressions; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; +import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public abstract class ASTExpression extends SimplifiableExpression { public ASTExpression() { } @@ -20,41 +16,18 @@ public abstract class ASTExpression extends SimplifiableExpression { throw new InternalCompilerError(getClass().getSimpleName() + " does not support simplify."); } - @Override - final public void collectFreeVariables(THashSet vars) { - throw new InternalCompilerError(getClass().getSimpleName() + " does not support collectFreeVariables."); - - } - - @Override - final public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - throw new InternalCompilerError(getClass().getSimpleName() + " does not support collectRefs."); - } - - @Override - final public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - throw new InternalCompilerError(getClass().getSimpleName() + " does not support collectVars."); - } - @Override final protected void updateType() throws MatchException { throw new InternalCompilerError(getClass().getSimpleName() + " does not support updateType."); } @Override - final public Expression decorate(ExpressionDecorator decorator) { - throw new InternalCompilerError(getClass().getSimpleName() + " does not support decorate."); - } - - @Override - final public void collectEffects(THashSet effects) { - throw new InternalCompilerError(getClass().getSimpleName() + " does not support collectEffects."); + public void accept(ExpressionVisitor visitor) { + throw new InternalCompilerError(getClass().getSimpleName() + " does not support accept."); } @Override - public void accept(ExpressionVisitor visitor) { + public Expression accept(ExpressionTransformer transformer) { throw new InternalCompilerError(getClass().getSimpleName() + " does not support accept."); } @@ -71,8 +44,8 @@ public abstract class ASTExpression extends SimplifiableExpression { } @Override - public void forVariables(VariableProcedure procedure) { - throw new InternalCompilerError("Class " + - getClass().getSimpleName() + " does not implement method forVariables."); + public void setLocationDeep(long loc) { + if(location == Locations.NO_LOCATION) + location = loc; } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Assignment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Assignment.java index 7cc70aaa7..cb525a9ad 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Assignment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Assignment.java @@ -1,7 +1,6 @@ package org.simantics.scl.compiler.elaboration.expressions; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; public class Assignment { @@ -25,17 +24,8 @@ public class Assignment { return new Assignment(newPattern, newValue); } - public void decorate(ExpressionDecorator decorator) { - pattern = pattern.decorate(decorator); - value = value.decorate(decorator); - } - public void setLocationDeep(long loc) { pattern.setLocationDeep(loc); value.setLocationDeep(loc); } - - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java index 4a34cebcf..a50bcc2dd 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java @@ -5,14 +5,9 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.types.Type; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class Case extends Symbol { public Expression[] patterns; public Expression value; @@ -36,21 +31,6 @@ public class Case extends Symbol { return lhs; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - value.collectRefs(allRefs, refs); - } - - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - } - - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - for(int i=patterns.length-1;i>=0;--i) - patterns[i].removeFreeVariables(vars); - } - public void resolve(TranslationContext context) { context.pushFrame(); for(int i=0;i allRefs, TIntHashSet refs) { - expression.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - expression.collectVars(allVars, vars); - } - @Override protected void updateType() throws MatchException { setType(expression.getType()); } - @Override - public void collectFreeVariables(THashSet vars) { - expression.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { expression = expression.simplify(context); @@ -87,17 +66,6 @@ public abstract class DecoratingExpression extends SimplifiableExpression { public int getFunctionDefinitionPatternArity() throws NotPatternException { return expression.getFunctionDefinitionPatternArity(); } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - expression = expression.decorate(decorator); - return this; - } - - @Override - public void collectEffects(THashSet effects) { - expression.collectEffects(effects); - } @Override public void setLocationDeep(long loc) { @@ -107,11 +75,6 @@ public abstract class DecoratingExpression extends SimplifiableExpression { } } - @Override - public void forVariables(VariableProcedure procedure) { - expression.forVariables(procedure); - } - @Override public IVal toVal(CompilationContext context, CodeWriter w) { throw new InternalCompilerError("Cannot generate code for " + getClass().getSimpleName() + "."); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java index 6121a57b1..09397ba05 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java @@ -6,7 +6,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Skeletons; import org.simantics.scl.compiler.types.TMetaVar; import org.simantics.scl.compiler.types.Type; @@ -17,9 +16,6 @@ import org.simantics.scl.compiler.types.util.TypeListener; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; 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 EAmbiguous extends SimplifiableExpression { public static final boolean DEBUG = false; @@ -28,7 +24,7 @@ public class EAmbiguous extends SimplifiableExpression { boolean[] active; int activeCount; transient TypingContext context; - Expression resolvedExpression; + public Expression resolvedExpression; public abstract static class Alternative { public abstract Type getType(); @@ -43,20 +39,6 @@ public class EAmbiguous extends SimplifiableExpression { this.activeCount = alternatives.length; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - - @Override - public void forVariables(VariableProcedure procedure) { - } - @Override protected void updateType() throws MatchException { throw new InternalCompilerError(); @@ -94,7 +76,7 @@ public class EAmbiguous extends SimplifiableExpression { StringBuilder b = new StringBuilder(); b.append("Expected <"); requiredType.toString(new TypeUnparsingContext(), b); - b.append(">, but no alteratives match the type: "); + b.append(">, but no alternatives match the type: "); for(int i=0;i vars) { - } @Override public Expression resolve(TranslationContext context) { @@ -189,19 +167,9 @@ public class EAmbiguous extends SimplifiableExpression { location = loc; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - return this; - } - - @Override - public void collectEffects(THashSet effects) { - // TODO Auto-generated method stub - } - @Override public void accept(ExpressionVisitor visitor) { - // TODO Auto-generated method stub + visitor.visit(this); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java index c7bce4667..02c7dff45 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java @@ -19,7 +19,6 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IApply; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.IListLiteral; @@ -33,14 +32,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.MultiFunction; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EApply extends Expression { public Expression function; public Expression[] parameters; - Type effect = Types.NO_EFFECTS; + public Type effect = Types.NO_EFFECTS; public EApply(Expression function, Expression ... parameters) { this.function = function; @@ -76,22 +71,9 @@ public class EApply extends Expression { public Expression[] getParameters() { return parameters; } - - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - function.collectRefs(allRefs, refs); - for(Expression parameter : parameters) - parameter.collectRefs(allRefs, refs); - } - - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - function.collectVars(allVars, vars); - for(Expression parameter : parameters) - parameter.collectVars(allVars, vars); - } - - @Override - protected void updateType() throws MatchException { + @Override + protected void updateType() throws MatchException { MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); /*for(int i=0;i vars) { - function.collectFreeVariables(vars); - for(Expression parameter : parameters) - parameter.collectFreeVariables(vars); - } private void combineApplications() { if(function instanceof EApply) { @@ -194,13 +169,6 @@ public class EApply extends Expression { for(Expression parameter : this.parameters) parameters.add(parameter); } - - @Override - public void removeFreeVariables(THashSet vars) { - function.removeFreeVariables(vars); - for(Expression parameter : parameters) - parameter.removeFreeVariables(vars); - } @Override public Expression replace(ReplaceContext context) { @@ -303,16 +271,6 @@ public class EApply extends Expression { return new ESimpleLet(location, null, this, new ELiteral(NoRepConstant.PUNIT)); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - if(decorator.decorateSubstructure(this)) { - function = function.decorate(decorator); - for(int i=0;i effects) { - effects.add(effect); - function.collectEffects(effects); - for(Expression parameter : parameters) - parameter.collectEffects(effects); - } - @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); @@ -380,13 +330,6 @@ public class EApply extends Expression { return false; } } - - @Override - public void forVariables(VariableProcedure procedure) { - function.forVariables(procedure); - for(Expression parameter : parameters) - parameter.forVariables(procedure); - } @Override public boolean isPattern(int arity) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApplyType.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApplyType.java index d07b6d13b..30d1209ce 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApplyType.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApplyType.java @@ -9,19 +9,14 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EApplyType extends Expression { - Expression expression; + public Expression expression; Type parameter; public EApplyType(Expression expression, Type parameter) { @@ -51,30 +46,17 @@ public class EApplyType extends Expression { return parameter; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - expression.collectRefs(allRefs, refs); + @Override + protected void updateType() throws MatchException { + setType(Types.instantiate(expression.getType(), parameter)); } - - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - expression.collectVars(allVars, vars); - } - @Override - protected void updateType() throws MatchException { - setType(Types.instantiate(expression.getType(), parameter)); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { + @Override + public IVal toVal(CompilationContext context, CodeWriter w) { IVal val = expression.toVal(context, w); return val.createSpecialization(parameter); } - @Override - public void collectFreeVariables(THashSet vars) { - expression.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { expression = expression.simplify(context); @@ -90,11 +72,6 @@ public class EApplyType extends Expression { expression = expression.resolve(context); return this; } - - @Override - public void removeFreeVariables(THashSet vars) { - expression.removeFreeVariables(vars); - } @Override public Expression replace(ReplaceContext context) { @@ -111,22 +88,11 @@ public class EApplyType extends Expression { public Expression inferType(TypingContext context) { throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + "."); } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - expression = expression.decorate(decorator); - return decorator.decorate(this); - } @Override public boolean isEffectful() { return expression.isEffectful(); } - - @Override - public void collectEffects(THashSet effects) { - expression.collectEffects(effects); - } @Override public void setLocationDeep(long loc) { @@ -140,11 +106,6 @@ public class EApplyType extends Expression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - expression.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAsPattern.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAsPattern.java index 62cea76d8..21248179f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAsPattern.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAsPattern.java @@ -9,19 +9,14 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EAsPattern extends Expression { - Variable var; - EVar eVar; - Expression pattern; + public Variable var; + public EVar eVar; + public Expression pattern; public EAsPattern(EVar eVar, Expression pattern) { this.eVar = eVar; @@ -40,32 +35,6 @@ public class EAsPattern extends Expression { public Expression getPattern() { return pattern; } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - pattern.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - int id = allVars.get(var); - if(id >= 0) - vars.add(id); - pattern.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - throw new InternalCompilerError(location, "Cannot collect free variables for a pattern."); - } - - @Override - public void removeFreeVariables(THashSet vars) { - vars.remove(var); - pattern.removeFreeVariables(vars); - } @Override public Expression simplify(SimplificationContext context) { @@ -109,12 +78,6 @@ public class EAsPattern extends Expression { var.setType(pattern.getType()); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - pattern = pattern.decorate(decorator); - return decorator.decorate(this); - } @Override public Expression replace(ReplaceContext context) { @@ -130,11 +93,6 @@ public class EAsPattern extends Expression { return result; } - - @Override - public void collectEffects(THashSet effects) { - pattern.collectEffects(effects); - } @Override public void setLocationDeep(long loc) { @@ -150,12 +108,6 @@ public class EAsPattern extends Expression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - procedure.execute(eVar.location, var); - pattern.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBind.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBind.java index d950e7b73..5c4a729e2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBind.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBind.java @@ -9,22 +9,17 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EBind extends SimplifiableExpression { public Expression pattern; public Expression value; public Expression in; - private EVariable monadEvidence; + public EVariable monadEvidence; SCLValue bindFunction; Type monadType; Type valueContentType; @@ -44,19 +39,6 @@ public class EBind extends SimplifiableExpression { this.value = value; this.in = in; } - - @Override - public void collectRefs(final TObjectIntHashMap allRefs, final TIntHashSet refs) { - value.collectRefs(allRefs, refs); - in.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - in.collectVars(allVars, vars); - } @Override protected void updateType() throws MatchException { @@ -117,13 +99,6 @@ public class EBind extends SimplifiableExpression { return simplified.simplify(context); } - @Override - public void collectFreeVariables(THashSet vars) { - in.collectFreeVariables(vars); - value.collectFreeVariables(vars); - pattern.removeFreeVariables(vars); - } - @Override public Expression resolve(TranslationContext context) { value = value.resolve(context); @@ -138,21 +113,6 @@ public class EBind extends SimplifiableExpression { return this; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - pattern = pattern.decorate(decorator); - value = value.decorate(decorator); - in = in.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - pattern.collectEffects(effects); - value.collectEffects(effects); - in.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -167,14 +127,6 @@ public class EBind extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - pattern.forVariables(procedure); - value.forVariables(procedure); - if(monadEvidence != null) - monadEvidence.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java index 2c70bd907..ea47c57b2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java @@ -3,7 +3,9 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; import java.util.List; +import org.simantics.scl.compiler.elaboration.chr.CHRRule; import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRQueryTranslationMode; import org.simantics.scl.compiler.elaboration.chr.translation.CHRTranslation; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement; @@ -18,7 +20,7 @@ import org.simantics.scl.compiler.errors.Locations; public class EBlock extends ASTExpression { - ArrayList statements = new ArrayList(); + public ArrayList statements = new ArrayList(); boolean monadic; public EBlock() { @@ -92,8 +94,12 @@ public class EBlock extends ASTExpression { ruleset.location = Locations.combine(statements.get(begin).location, statements.get(end-1).location); for(int i=begin;i allRefs, TIntHashSet refs) { - ruleset.collectRefs(allRefs, refs); - in.collectRefs(allRefs, refs); - } - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - ruleset.collectVars(allVars, vars); - in.collectVars(allVars, vars); - } - @Override - public void forVariables(VariableProcedure procedure) { - ruleset.forVariables(procedure); - in.forVariables(procedure); - } + @Override protected void updateType() throws MatchException { setType(in.getType()); } + @Override public IVal toVal(CompilationContext context, CodeWriter w) { ruleset.generateCode(w); return in.toVal(context, w); } - @Override - public void collectFreeVariables(THashSet vars) { - ruleset.collectFreeVariables(vars); - in.collectFreeVariables(vars); - } + @Override public Expression resolve(TranslationContext context) { + if(context.currentRuleset != null) { + context.getErrorLog().log(location, "Current version of SCL compiler does not support nested rulesets."); + return this; + } + context.currentRuleset = ruleset; + context.pushFrame(); context.pushCHRConstraintFrame(); ruleset.resolve(context); in = in.resolve(context); context.popCHRConstraintFrame(ruleset.constraints); context.popFrame(); + + context.currentRuleset = null; + return this; } @Override @@ -74,16 +59,7 @@ public class ECHRRuleset extends Expression { in.setLocationDeep(loc); } } - @Override - public Expression decorate(ExpressionDecorator decorator) { - in = in.decorate(decorator); - return this; - } - @Override - public void collectEffects(THashSet effects) { - ruleset.collectEffects(effects); - in.collectEffects(effects); - } + @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRulesetConstructor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRulesetConstructor.java index 7965b5011..431bd850d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRulesetConstructor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRulesetConstructor.java @@ -9,47 +9,27 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ECHRRulesetConstructor extends Expression { - CHRRuleset ruleset; + public CHRRuleset ruleset; public ECHRRulesetConstructor(CHRRuleset ruleset) { this.ruleset = ruleset; } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - ruleset.collectRefs(allRefs, refs); - } - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - ruleset.collectVars(allVars, vars); - } - @Override - public void forVariables(VariableProcedure procedure) { - ruleset.forVariables(procedure); - } + @Override protected void updateType() throws MatchException { throw new InternalCompilerError("Type of ECHRRulesetConstructor should be already given."); } + @Override public IVal toVal(CompilationContext context, CodeWriter w) { return ruleset.generateCode(w); } - @Override - public void collectFreeVariables(THashSet vars) { - ruleset.collectFreeVariables(vars); - } + @Override public Expression resolve(TranslationContext context) { context.pushFrame(); @@ -67,14 +47,6 @@ public class ECHRRulesetConstructor extends Expression { } } @Override - public Expression decorate(ExpressionDecorator decorator) { - return this; - } - @Override - public void collectEffects(THashSet effects) { - ruleset.collectEffects(effects); - } - @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java new file mode 100644 index 000000000..db651684f --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java @@ -0,0 +1,128 @@ +package org.simantics.scl.compiler.elaboration.expressions; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.common.names.Names; +import org.simantics.scl.compiler.compilation.CompilationContext; +import org.simantics.scl.compiler.constants.NoRepConstant; +import org.simantics.scl.compiler.elaboration.chr.CHRQuery; +import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; +import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext; +import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp; +import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer; +import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext; +import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; +import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; +import org.simantics.scl.compiler.elaboration.contexts.TypingContext; +import org.simantics.scl.compiler.errors.Locations; +import org.simantics.scl.compiler.internal.codegen.references.IVal; +import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; +import org.simantics.scl.compiler.types.Types; +import org.simantics.scl.compiler.types.exceptions.MatchException; +import org.simantics.scl.compiler.types.kinds.Kinds; + +public class ECHRSelect extends Expression { + public CHRQuery query; + public Variable[] existentialVariables; + public Expression expression; + private ArrayList planOps; + private CHRRuleset currentRuleset; + + public ECHRSelect(Expression expression, CHRQuery query) { + this.expression = expression; + this.query = query; + } + + @Override + protected void updateType() throws MatchException { + setType(Types.list(expression.getType())); + } + + @Override + public Expression inferType(TypingContext context) { + for(Variable variable : existentialVariables) + variable.setType(Types.metaVar(Kinds.STAR)); + query.checkType(context); + expression = expression.inferType(context); + return this; + } + + @Override + public Expression simplify(SimplificationContext simplificationContext) { + this.expression = expression.simplify(simplificationContext); + query.simplify(simplificationContext); + + return this; + } + + @Override + public IVal toVal(CompilationContext context, CodeWriter w) { + QueryPlanningContext queryContext = new QueryPlanningContext(context, existentialVariables); + if(query.createQueryPlan(queryContext, null, -1, null)) + planOps = queryContext.getPlanOps(); + + IVal list = w.apply(location, context.getValue(Names.MList_create).getValue(), NoRepConstant.UNIT); + planOps.add(new PlanOp(location) { + @Override + public void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w) { + w.apply(location, context.getValue(Names.MList_add).getValue(), list, expression.toVal(context, w)); + } + }); + PlanRealizer realizer = new PlanRealizer(context, currentRuleset, currentRuleset != null ? currentRuleset.runtimeRulesetVariable : null, null, planOps); + realizer.nextOp(w); + return w.apply(location, context.getValue(Names.MList_freeze).getValue(), list); + } + + @Override + public Expression resolve(TranslationContext context) { + currentRuleset = context.currentRuleset; + + context.pushExistentialFrame(); + query.resolve(context); + context.disallowNewExistentials(); + expression = expression.resolve(context); + existentialVariables = context.popExistentialFrame(); + return this; + } + + @Override + public void setLocationDeep(long loc) { + if(location == Locations.NO_LOCATION) { + query.setLocationDeep(loc); + expression.setLocationDeep(loc); + } + } + + @Override + public void accept(ExpressionVisitor visitor) { + visitor.visit(this); + } + + @Override + public Expression accept(ExpressionTransformer transformer) { + return transformer.transform(this); + } + + @Override + public Expression replace(ReplaceContext context) { + Variable[] newExistentialVariables = new Variable[existentialVariables.length]; + for(int i=0;i(planOps.size()); + throw new InternalCompilerError(location, "Copying of ECHRSelect is not supported."); + //for(PlanOp op : planOps) + // copy.planOps.add(op.replace(context)); + } + return copy; + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java index 6b99e6d37..b33ebcf25 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java @@ -1,6 +1,8 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.common.precedence.Precedence; @@ -13,11 +15,11 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.errors.NotPatternException; import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType; import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs; +import org.simantics.scl.compiler.elaboration.java.DynamicConstructor; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IConstant; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; @@ -31,12 +33,8 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.MultiFunction; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EConstant extends Expression { - SCLValue value; + public SCLValue value; Type[] typeParameters; public EConstant(SCLValue value, Type ... typeParameters) { @@ -83,24 +81,18 @@ public class EConstant extends Expression { setType(Types.instantiate(getType(), type)); return this; } - - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - int id = allRefs.get(value); - if(id >= 0) - refs.add(id); + + @Override + public Set getFreeVariables() { + return Collections.emptySet(); } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - public void toString(StringBuilder b, TypeUnparsingContext tuc) { - Name name = value.getName(); - if(name.module.equals("Builtin") || name.module.equals("Prelude")) - b.append(name.name); - else - b.append(name); + public void toString(StringBuilder b, TypeUnparsingContext tuc) { + Name name = value.getName(); + if(name.module.equals("Builtin") || name.module.equals("Prelude")) + b.append(name.name); + else + b.append(name); /*for(Type type : typeParameters) { b.append(" <"); b.append(type.toString(tuc)); @@ -113,17 +105,13 @@ public class EConstant extends Expression { setType(Types.instantiate(value.getType(), typeParameters)); } - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - IVal val = value.getValue(); - if(typeParameters.length > 0) { - val = val.createSpecialization(typeParameters); - } - return val; - } - @Override - public void collectFreeVariables(THashSet vars) { + public IVal toVal(CompilationContext context, CodeWriter w) { + IVal val = value.getValue(); + if(typeParameters.length > 0) { + val = val.createSpecialization(typeParameters); + } + return val; } @Override @@ -158,10 +146,6 @@ public class EConstant extends Expression { public Expression resolveAsPattern(TranslationContext context) { return this; } - - @Override - public void removeFreeVariables(THashSet vars) { - } @Override public Expression replace(ReplaceContext context) { @@ -207,7 +191,7 @@ public class EConstant extends Expression { context.recursiveReferences.add(placeholder); return placeholder; } - else if(context.isInPattern()) { + else if(context.isInPattern() && value.getValue() != DynamicConstructor.INSTANCE /* HACK!! */) { /* This is little hackish code that handles the following kind of constructors: * data Thunk a = Thunk s (a -> s) * in @@ -234,19 +218,10 @@ public class EConstant extends Expression { else return applyPUnit(context); } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } @Override public boolean isEffectful() { - return false; - } - - @Override - public void collectEffects(THashSet effects) { + return false; } @Override @@ -264,10 +239,6 @@ public class EConstant extends Expression { public Precedence getPrecedence() { return value.getPrecedence(); } - - @Override - public void forVariables(VariableProcedure procedure) { - } @Override public boolean isPattern(int arity) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEnforce.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEnforce.java index 53d9037e2..8e1adf784 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEnforce.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEnforce.java @@ -9,18 +9,12 @@ import org.simantics.scl.compiler.elaboration.query.QExists; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EEnforce extends SimplifiableExpression { - Query query; + public Query query; public EEnforce(Query query) { this.query = query; @@ -30,23 +24,6 @@ public class EEnforce extends SimplifiableExpression { return query; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - query.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - query.collectVars(allVars, vars); - } - - @Override - public void collectEffects(THashSet effects) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects."); - } - @Override protected void updateType() throws MatchException { setType(Types.tupleConstructor(0)); @@ -63,11 +40,6 @@ public class EEnforce extends SimplifiableExpression { return query.generateEnforce(new EnforcingContext(context)); } - @Override - public void collectFreeVariables(THashSet vars) { - query.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { /*query = query.simplify(context); @@ -84,11 +56,6 @@ public class EEnforce extends SimplifiableExpression { query = new QExists(variables, query); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } @Override public void setLocationDeep(long loc) { @@ -102,11 +69,6 @@ public class EEnforce extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - query.forVariables(procedure); - } @Override public Expression replace(ReplaceContext context) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEquations.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEquations.java index 3d3132cf9..7773a5346 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEquations.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEquations.java @@ -6,15 +6,10 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.equation.Equation; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EEquations extends SimplifiableExpression { public Equation[] equations; @@ -50,50 +45,11 @@ public class EEquations extends SimplifiableExpression { return transformer.transform(this); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - for(Equation equation : equations) - equation.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - for(Equation equation : equations) - equation.collectVars(allVars, vars); - } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Equation equation : equations) - equation.forVariables(procedure); - } - @Override protected void updateType() throws MatchException { setType(Types.UNIT); } - @Override - public void collectFreeVariables(THashSet vars) { - for(Equation equation : equations) - equation.collectFreeVariables(vars); - } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - if(decorator.decorateSubstructure(this)) { - for(Equation equation : equations) - equation.decorate(decorator); - } - return this; - } - - @Override - public void collectEffects(THashSet effects) { - for(Equation equation : equations) - equation.collectEffects(effects); - } - @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EError.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EError.java index b329beb19..997a5723b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EError.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EError.java @@ -8,16 +8,11 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EError extends Expression { public EError(long loc, Type type) { @@ -25,33 +20,21 @@ public class EError extends Expression { setType(type); } - public EError() { + public EError() { } public EError(long loc) { this(loc, Types.metaVar(Kinds.STAR)); } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - - @Override - protected void updateType() throws MatchException { - setType(Types.metaVar(Kinds.STAR)); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - throw new UnsupportedOperationException(); + @Override + protected void updateType() throws MatchException { + setType(Types.metaVar(Kinds.STAR)); } @Override - public void collectFreeVariables(THashSet vars) { + public IVal toVal(CompilationContext context, CodeWriter w) { + throw new UnsupportedOperationException(); } @Override @@ -68,15 +51,6 @@ public class EError extends Expression { public Expression inferType(TypingContext context) { return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return this; - } - - @Override - public void collectEffects(THashSet effects) { - } @Override public void setLocationDeep(long loc) { @@ -93,10 +67,6 @@ public class EError extends Expression { public Expression replace(ReplaceContext context) { return this; } - - @Override - public void forVariables(VariableProcedure procedure) { - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EExternalConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EExternalConstant.java index 4777b2dfb..788483dbe 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EExternalConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EExternalConstant.java @@ -8,12 +8,10 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; -import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IConstant; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; @@ -21,10 +19,6 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EExternalConstant extends Expression { Object value; @@ -37,34 +31,21 @@ public class EExternalConstant extends Expression { return value; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - - public void toString(StringBuilder b, TypeUnparsingContext tuc) { + public void toString(StringBuilder b, TypeUnparsingContext tuc) { b.append(value); } - @Override - protected void updateType() throws MatchException { - throw new InternalCompilerError("EExternalConstants must have explicitly defined type."); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - ModuleWriter mw = w.getModuleWriter(); - return mw.getExternalConstant(value, getType()); + @Override + protected void updateType() throws MatchException { + throw new InternalCompilerError("EExternalConstants must have explicitly defined type."); } @Override - public void collectFreeVariables(THashSet vars) { + public IVal toVal(CompilationContext context, CodeWriter w) { + ModuleWriter mw = w.getModuleWriter(); + return mw.getExternalConstant(value, getType()); } - @Override public Expression simplify(SimplificationContext context) { return this; @@ -90,23 +71,10 @@ public class EExternalConstant extends Expression { return new EExternalConstant(value, getType().replace(context.tvarMap)); } - @Override - public void removeFreeVariables(THashSet vars) { - } - @Override public Expression inferType(TypingContext context) { return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - } @Override public void setLocationDeep(long loc) { @@ -123,10 +91,6 @@ public class EExternalConstant extends Expression { public IExpression toIExpression(ExpressionInterpretationContext context) { return new IConstant(value); } - - @Override - public void forVariables(VariableProcedure procedure) { - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EFieldAccess.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EFieldAccess.java index a8d117f5d..04a5840f5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EFieldAccess.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EFieldAccess.java @@ -11,22 +11,17 @@ import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous.Alternative import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor; import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.header.ModuleHeader; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EFieldAccess extends SimplifiableExpression { private static final Type VARIABLE = Types.con("Simantics/Variables", "Variable"); - Expression parent; - FieldAccessor accessor; + public Expression parent; + public FieldAccessor accessor; boolean lastAccessor = true; public EFieldAccess(Expression parent, FieldAccessor accessor) { @@ -36,20 +31,6 @@ public class EFieldAccess extends SimplifiableExpression { ((EFieldAccess)parent).lastAccessor = false; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - parent.collectRefs(allRefs, refs); - accessor.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - parent.collectVars(allVars, vars); - accessor.collectVars(allVars, vars); - } - private boolean returnsValue() { return accessor.accessSeparator == '#' && !accessor.isVariableId(); } @@ -120,12 +101,6 @@ public class EFieldAccess extends SimplifiableExpression { return this; } - @Override - public void collectFreeVariables(THashSet vars) { - parent.collectFreeVariables(vars); - accessor.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { // Simplify subexpressions @@ -166,17 +141,6 @@ public class EFieldAccess extends SimplifiableExpression { accessor.resolve(context); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - // FIXME - effects.add(Types.READ_GRAPH); - } @Override public void setLocationDeep(long loc) { @@ -191,12 +155,6 @@ public class EFieldAccess extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - parent.forVariables(procedure); - accessor.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EGetConstraint.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EGetConstraint.java index cd34db4b5..24ff0a149 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EGetConstraint.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EGetConstraint.java @@ -4,35 +4,17 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.TPred; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EGetConstraint extends SimplifiableExpression { TPred constraint; - EVariable evidence; + public EVariable evidence; public EGetConstraint(long loc, TPred constraint) { super(loc); this.constraint = constraint; } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - if(evidence != null) - evidence.collectVars(allVars, vars); - } @Override public Expression inferType(TypingContext context) { @@ -49,12 +31,6 @@ public class EGetConstraint extends SimplifiableExpression { setType(constraint); } - @Override - public void collectFreeVariables(THashSet vars) { - if(evidence != null) - evidence.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { return evidence.simplify(context); @@ -65,15 +41,6 @@ public class EGetConstraint extends SimplifiableExpression { return this; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -87,11 +54,6 @@ public class EGetConstraint extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - evidence.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java index 661de4261..fe6216fe1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java @@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IConstant; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.IIf; @@ -18,10 +17,6 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.runtime.tuple.Tuple0; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EIf extends Expression { public Expression condition; public Expression then_; @@ -40,29 +35,13 @@ public class EIf extends Expression { this.else_ = else_; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - condition.collectRefs(allRefs, refs); - then_.collectRefs(allRefs, refs); - if(else_ != null) - else_.collectRefs(allRefs, refs); + @Override + protected void updateType() throws MatchException { + setType(then_.getType()); } - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - condition.collectVars(allVars, vars); - then_.collectVars(allVars, vars); - if(else_ != null) - else_.collectVars(allVars, vars); - } - - @Override - protected void updateType() throws MatchException { - setType(then_.getType()); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { + @Override + public IVal toVal(CompilationContext context, CodeWriter w) { IVal conditionVal = condition.toVal(context, w); CodeWriter joinPoint = w.createBlock(getType()); CodeWriter thenBlock = w.createBlock(); @@ -83,14 +62,6 @@ public class EIf extends Expression { return w.getParameters()[0]; } - @Override - public void collectFreeVariables(THashSet vars) { - condition.collectFreeVariables(vars); - then_.collectFreeVariables(vars); - if(else_ != null) - else_.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { condition = condition.simplify(context); @@ -136,27 +107,10 @@ public class EIf extends Expression { return this; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - condition = condition.decorate(decorator); - then_ = then_.decorate(decorator); - if(else_ != null) - else_ = else_.decorate(decorator); - return decorator.decorate(this); - } - @Override public boolean isEffectful() { return condition.isEffectful() || then_.isEffectful() || (else_ != null && else_.isEffectful()); } - - @Override - public void collectEffects(THashSet effects) { - condition.collectEffects(effects); - then_.collectEffects(effects); - if(else_ != null) - else_.collectEffects(effects); - } @Override public void setLocationDeep(long loc) { @@ -180,13 +134,6 @@ public class EIf extends Expression { else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE)); } - @Override - public void forVariables(VariableProcedure procedure) { - condition.forVariables(procedure); - then_.forVariables(procedure); - if(else_ != null) - else_.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral.java index 0fbb6a506..dc265934a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral.java @@ -12,32 +12,17 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EIntegerLiteral extends SimplifiableExpression { public String value; - EVariable constraint; + public EVariable constraint; public EIntegerLiteral(String value) { this.value = value; } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } public String getValue() { return value; @@ -80,10 +65,6 @@ public class EIntegerLiteral extends SimplifiableExpression { throw new InternalCompilerError(); } - @Override - public void collectFreeVariables(THashSet vars) { - } - @Override public Expression simplify(SimplificationContext context) { try { @@ -118,20 +99,11 @@ public class EIntegerLiteral extends SimplifiableExpression { copy.constraint = (EVariable)constraint.replace(context); return copy; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } @Override public boolean isEffectful() { return false; } - - @Override - public void collectEffects(THashSet effects) { - } @Override public void setLocationDeep(long loc) { @@ -146,12 +118,6 @@ public class EIntegerLiteral extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - if(constraint != null) - constraint.forVariables(procedure); - } @Override public boolean isPattern(int arity) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambda.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambda.java index 67a7e1476..ccf86bbf5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambda.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambda.java @@ -5,7 +5,6 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; @@ -13,10 +12,6 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.MultiFunction; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ELambda extends SimplifiableExpression { public Case[] cases; Type effect = Types.NO_EFFECTS; @@ -38,20 +33,8 @@ public class ELambda extends SimplifiableExpression { this(loc, new Case(new Expression[] {pat}, exp)); } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - for(Case case_ : cases) - case_.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(Case case_ : cases) - case_.collectVars(allVars, vars); - } - - public Expression decomposeMatching() { - Expression[] patterns = cases[0].patterns; + public Expression decomposeMatching() { + Expression[] patterns = cases[0].patterns; int arity = patterns.length; // Simple cases @@ -104,12 +87,6 @@ public class ELambda extends SimplifiableExpression { return decomposeMatching().simplify(context); } - @Override - public void collectFreeVariables(THashSet vars) { - for(Case case_ : cases) - case_.collectFreeVariables(vars); - } - @Override public Expression resolve(TranslationContext context) { for(Case case_ : cases) @@ -173,39 +150,16 @@ public class ELambda extends SimplifiableExpression { context.popEffectUpperBound(); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - if(decorator.decorateSubstructure(this)) - for(Case case_ : cases) - case_.decorate(decorator); - return decorator.decorate(this); - } @Override public boolean isEffectful() { return false; } - - @Override - public void collectEffects(THashSet effects) { - for(Case case_ : cases) { - for(Expression pattern : case_.patterns) - pattern.collectEffects(effects); - case_.value.collectEffects(effects); - } - } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Case case_ : cases) - case_.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambdaType.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambdaType.java index 23733bac6..73e38397d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambdaType.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambdaType.java @@ -9,18 +9,12 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; import org.simantics.scl.compiler.types.TVar; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ELambdaType extends Expression { public TVar[] parameters; public Expression value; @@ -31,31 +25,16 @@ public class ELambdaType extends Expression { this.value = value; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - value.collectRefs(allRefs, refs); + @Override + protected void updateType() throws MatchException { + setType(Types.forAll(parameters, value.getType())); } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - } - - @Override - protected void updateType() throws MatchException { - setType(Types.forAll(parameters, value.getType())); - } - @Override + @Override public IVal toVal(CompilationContext context, CodeWriter w) { return lambdaToVal(context, w); } - @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { value = value.simplify(context); @@ -93,16 +72,6 @@ public class ELambdaType extends Expression { throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + "."); } - @Override - public Expression decorate(ExpressionDecorator decorator) { - value = value.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -115,11 +84,6 @@ public class ELambdaType extends Expression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELet.java index 2b9e8e2c0..23c5b0be2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELet.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELet.java @@ -14,7 +14,6 @@ import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.codegen.writer.RecursiveDefinitionWriter; import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; @@ -22,9 +21,11 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; +/** + * Generated maily from EPreLet + */ public class ELet extends Expression { public Assignment[] assignments; public Expression in; @@ -34,21 +35,6 @@ public class ELet extends Expression { this.assignments = assignments; this.in = in; } - - @Override - public void collectRefs(final TObjectIntHashMap allRefs, final TIntHashSet refs) { - for(Assignment assign : assignments) - assign.value.collectRefs(allRefs, refs); - in.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(Assignment assign : assignments) - assign.value.collectVars(allVars, vars); - in.collectVars(allVars, vars); - } @Override protected void updateType() throws MatchException { @@ -123,15 +109,6 @@ public class ELet extends Expression { return result; } - @Override - public void collectFreeVariables(THashSet vars) { - in.collectFreeVariables(vars); - for(Assignment assign : assignments) - assign.value.collectFreeVariables(vars); - for(Assignment assign : assignments) - assign.pattern.removeFreeVariables(vars); - } - @Override public Expression resolve(TranslationContext context) { throw new InternalCompilerError("ELet should be already resolved."); @@ -209,23 +186,6 @@ public class ELet extends Expression { in = in.checkIgnoredType(context); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - in = in.decorate(decorator); - for(Assignment assignment : assignments) - assignment.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - for(Assignment assignment : assignments) { - assignment.pattern.collectEffects(effects); - assignment.value.collectEffects(effects); - } - in.collectEffects(effects); - } @Override public void setLocationDeep(long loc) { @@ -241,13 +201,6 @@ public class ELet extends Expression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Assignment assignment : assignments) - assignment.forVariables(procedure); - in.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListComprehension.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListComprehension.java index 860bc7f8c..78f7ce115 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListComprehension.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListComprehension.java @@ -6,15 +6,10 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.list.CompiledQualifier; import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EListComprehension extends SimplifiableExpression { public Expression head; @@ -31,20 +26,6 @@ public class EListComprehension extends SimplifiableExpression { this.head = head; this.qualifier = qualifier; } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - head.collectRefs(allRefs, refs); - qualifier.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - head.collectVars(allVars, vars); - qualifier.collectVars(allVars, vars); - } @Override public Expression checkBasicType(TypingContext context, Type requiredType) { @@ -65,12 +46,6 @@ public class EListComprehension extends SimplifiableExpression { setType(Types.list(head.getType())); } - @Override - public void collectFreeVariables(THashSet vars) { - head.collectFreeVariables(vars); - qualifier.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { context.pushLocation(location); @@ -101,19 +76,6 @@ public class EListComprehension extends SimplifiableExpression { return this; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - head = head.decorate(decorator); - qualifier.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - head.collectEffects(effects); - qualifier.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -127,12 +89,6 @@ public class EListComprehension extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - head.forVariables(procedure); - qualifier.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListLiteral.java index b1075a949..0f9ae5a15 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListLiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListLiteral.java @@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.java.Builtins; import org.simantics.scl.compiler.elaboration.java.ListConstructor; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.utils.Constants; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.IListLiteral; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; @@ -16,13 +15,9 @@ import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EListLiteral extends SimplifiableExpression { - Expression[] components; + public Expression[] components; Type componentType; public EListLiteral(Expression[] components) { @@ -38,26 +33,6 @@ public class EListLiteral extends SimplifiableExpression { return components; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - for(Expression component : components) - component.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(Expression component : components) - component.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - for(Expression component : components) - component.collectFreeVariables(vars); - } - @Override public Expression simplify(SimplificationContext context) { context.pushLocation(location); @@ -114,19 +89,6 @@ public class EListLiteral extends SimplifiableExpression { return this; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - for(int i=0;i effects) { - for(Expression component : components) - component.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -148,12 +110,6 @@ public class EListLiteral extends SimplifiableExpression { componentExpressions[i] = components[i].toIExpression(target); return new IListLiteral(componentExpressions); } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Expression component : components) - component.forVariables(procedure); - } @Override public Expression replace(ReplaceContext context) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELiteral.java index b11c0d667..bef28f20f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELiteral.java @@ -1,6 +1,8 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.constants.Constant; @@ -11,18 +13,12 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IConstant; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ELiteral extends Expression { Constant value; @@ -39,34 +35,26 @@ public class ELiteral extends Expression { public Constant getValue() { return value; } - - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { + + @Override + public Set getFreeVariables() { + return Collections.emptySet(); } - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - - public void toString(StringBuilder b, TypeUnparsingContext tuc) { + public void toString(StringBuilder b, TypeUnparsingContext tuc) { b.append(value); } - - @Override - protected void updateType() throws MatchException { - setType(value.getType()); - } - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - return value; + @Override + protected void updateType() throws MatchException { + setType(value.getType()); } @Override - public void collectFreeVariables(THashSet vars) { + public IVal toVal(CompilationContext context, CodeWriter w) { + return value; } - @Override public Expression simplify(SimplificationContext context) { return this; @@ -92,10 +80,6 @@ public class ELiteral extends Expression { return new ELiteral(value); } - @Override - public void removeFreeVariables(THashSet vars) { - } - @Override public IExpression toIExpression(ExpressionInterpretationContext target) { return new IConstant(value.realizeValue(target.localClassBuilder)); @@ -105,15 +89,6 @@ public class ELiteral extends Expression { public Expression inferType(TypingContext context) { return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - } @Override public void setLocationDeep(long loc) { @@ -125,10 +100,6 @@ public class ELiteral extends Expression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - } @Override public boolean isPattern(int arity) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EMatch.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EMatch.java index eef72f9de..279815ecf 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EMatch.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EMatch.java @@ -13,15 +13,10 @@ import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.elaboration.matching.PatternMatchingCompiler; import org.simantics.scl.compiler.internal.elaboration.matching.Row; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EMatch extends Expression { public Expression[] scrutinee; @@ -42,51 +37,27 @@ public class EMatch extends Expression { this.cases = cases; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - for(Expression s : scrutinee) - s.collectRefs(allRefs, refs); - for(Case case_ : cases) - case_.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(Expression s : scrutinee) - s.collectVars(allVars, vars); - for(Case case_ : cases) - case_.collectVars(allVars, vars); - } - - @Override - protected void updateType() { - setType(cases[0].value.getType()); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - ArrayList rows = new ArrayList(cases.length); - for(Case case_ : cases) - rows.add(new Row(case_.patterns, case_.value)); - - IVal[] scrutineeVals = new IVal[scrutinee.length]; - for(int i=0;i vars) { - for(Expression s : scrutinee) - s.collectFreeVariables(vars); + public IVal toVal(CompilationContext context, CodeWriter w) { + ArrayList rows = new ArrayList(cases.length); for(Case case_ : cases) - case_.collectFreeVariables(vars); + rows.add(new Row(case_.patterns, case_.value)); + + IVal[] scrutineeVals = new IVal[scrutinee.length]; + for(int i=0;i effects) { - for(Expression s : scrutinee) - s.collectEffects(effects); - for(Case case_ : cases) { - for(Expression pattern : case_.patterns) - pattern.collectEffects(effects); - case_.value.collectEffects(effects); - } - } @Override public void accept(ExpressionVisitor visitor) { @@ -196,14 +147,6 @@ public class EMatch extends Expression { public Case[] getCases() { return cases; } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Expression s : scrutinee) - s.forVariables(procedure); - for(Case case_ : cases) - case_.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPlaceholder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPlaceholder.java index bd03b30b9..feecc905c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPlaceholder.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPlaceholder.java @@ -2,7 +2,6 @@ package org.simantics.scl.compiler.elaboration.expressions; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; public class EPlaceholder extends DecoratingExpression { public EPlaceholder(long loc, Expression expression) { @@ -33,9 +32,4 @@ public class EPlaceholder extends DecoratingExpression { public Expression resolveAsPattern(TranslationContext context) { return expression.resolveAsPattern(context); } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return expression.decorate(decorator); - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java new file mode 100644 index 000000000..318a407f5 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java @@ -0,0 +1,20 @@ +package org.simantics.scl.compiler.elaboration.expressions; + +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRQueryTranslationMode; +import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; + +public class EPreCHRSelect extends ASTExpression { + CHRAstQuery query; + Expression expression; + + public EPreCHRSelect(CHRAstQuery query, Expression expression) { + this.query = query; + this.expression = expression; + } + + @Override + public Expression resolve(TranslationContext context) { + return new ECHRSelect(expression, query.translate(context, CHRQueryTranslationMode.QUERY_HEAD)).resolve(context); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java index 035a2cadc..1578928aa 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java @@ -13,10 +13,13 @@ import org.simantics.scl.compiler.errors.Locations; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectObjectProcedure; +/** + * Generated mainly from EBlock + */ public class EPreLet extends ASTExpression { - List assignments; - Expression in; + public List assignments; + public Expression in; public EPreLet(List assignments, Expression in) { this.assignments = assignments; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java index 41880a022..c287f3ba1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java @@ -10,8 +10,8 @@ import gnu.trove.map.hash.THashMap; public class EPreRuleset extends ASTExpression { - RuleStatement[] statements; - Expression in; + public RuleStatement[] statements; + public Expression in; public EPreRuleset(RuleStatement[] statements, Expression in) { this.statements = statements; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java index 2f85269ac..90cc94bef 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java @@ -11,33 +11,18 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ERealLiteral extends SimplifiableExpression { public String value; - EVariable constraint; + public EVariable constraint; public ERealLiteral(String value) { this.value = value; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - private Expression tryToConvertToPrimitive(ErrorLog errorLog, Type requiredType) { if(requiredType.equals(Types.DOUBLE)) return new ELiteral(new DoubleConstant(Double.parseDouble(value))); @@ -74,10 +59,6 @@ public class ERealLiteral extends SimplifiableExpression { protected void updateType() throws MatchException { throw new InternalCompilerError("TODO"); } - - @Override - public void collectFreeVariables(THashSet vars) { - } @Override public Expression simplify(SimplificationContext context) { @@ -108,15 +89,6 @@ public class ERealLiteral extends SimplifiableExpression { return copy; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -134,12 +106,6 @@ public class ERealLiteral extends SimplifiableExpression { public String getValue() { return value; } - - @Override - public void forVariables(VariableProcedure procedure) { - if(constraint != null) - constraint.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERuleset.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERuleset.java index e784813d6..9663a2a72 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERuleset.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERuleset.java @@ -32,7 +32,6 @@ import org.simantics.scl.compiler.elaboration.query.compilation.DerivateExceptio import org.simantics.scl.compiler.elaboration.relations.LocalRelation; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.elaboration.utils.ForcedClosure; import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; import org.simantics.scl.compiler.top.SCLCompilerConfiguration; @@ -44,13 +43,12 @@ import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.impl.Constants; 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 ERuleset extends SimplifiableExpression { LocalRelation[] relations; - DatalogRule[] rules; - Expression in; + public DatalogRule[] rules; + public Expression in; public ERuleset(LocalRelation[] relations, DatalogRule[] rules, Expression in) { this.relations = relations; @@ -95,12 +93,6 @@ public class ERuleset extends SimplifiableExpression { visitor.visit(this); return b.toString(); } - - public void forVariables(VariableProcedure procedure) { - for(Expression headParameter : headParameters) - headParameter.forVariables(procedure); - body.forVariables(procedure); - } } private void checkRuleTypes(TypingContext context) { @@ -137,50 +129,6 @@ public class ERuleset extends SimplifiableExpression { return compile(context); } - @Override - public void collectFreeVariables(THashSet vars) { - for(DatalogRule rule : rules) { - for(Expression parameter : rule.headParameters) - parameter.collectFreeVariables(vars); - rule.body.collectFreeVariables(vars); - for(Variable var : rule.variables) - vars.remove(var); - } - in.collectFreeVariables(vars); - } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - for(DatalogRule rule : rules) { - for(Expression parameter : rule.headParameters) - parameter.collectRefs(allRefs, refs); - rule.body.collectRefs(allRefs, refs); - } - in.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(DatalogRule rule : rules) { - for(Expression parameter : rule.headParameters) - parameter.collectVars(allVars, vars); - rule.body.collectVars(allVars, vars); - } - in.collectVars(allVars, vars); - } - - @Override - public void collectEffects(THashSet effects) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects."); - } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - @Override public Expression resolve(TranslationContext context) { throw new InternalCompilerError(); @@ -406,13 +354,6 @@ public class ERuleset extends SimplifiableExpression { public Expression getIn() { return in; } - - @Override - public void forVariables(VariableProcedure procedure) { - for(DatalogRule rule : rules) - rule.forVariables(procedure); - in.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java index 7316fe307..e7014a865 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java @@ -20,25 +20,20 @@ import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilation import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationMode; import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.parser.SCLTerminals; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ESelect extends SimplifiableExpression { private final Type ARRAY_LIST = Types.con("ArrayList", "T"); int selectVariant; - Expression expression; - Query query; - Variable[] variables; + public Expression expression; + public Query query; + public Variable[] variables; public ESelect(int selectVariant, Expression expression, Query query) { this.selectVariant = selectVariant; @@ -46,25 +41,6 @@ public class ESelect extends SimplifiableExpression { this.query = query; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - expression.collectRefs(allRefs, refs); - query.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - expression.collectVars(allVars, vars); - query.collectVars(allVars, vars); - } - - @Override - public void collectEffects(THashSet effects) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects."); - } - @Override protected void updateType() throws MatchException { setType(selectVariant==SCLTerminals.SELECT_FIRST @@ -141,14 +117,6 @@ public class ESelect extends SimplifiableExpression { return loc(location, result); } - @Override - public void collectFreeVariables(THashSet vars) { - expression.collectFreeVariables(vars); - query.collectFreeVariables(vars); - for(Variable variable : variables) - vars.remove(variable); - } - @Override public Expression resolve(TranslationContext context) { context.pushExistentialFrame(); @@ -157,11 +125,6 @@ public class ESelect extends SimplifiableExpression { variables = context.popExistentialFrame(); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } @Override public void setLocationDeep(long loc) { @@ -176,12 +139,6 @@ public class ESelect extends SimplifiableExpression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - expression.forVariables(procedure); - query.forVariables(procedure); - } @Override public Expression simplify(SimplificationContext context) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java index 2e5d4c364..833e3e9e3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java @@ -1,6 +1,7 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; +import java.util.Set; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.compilation.CompilationContext; @@ -11,7 +12,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.ILambda; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; @@ -23,10 +23,6 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.MultiFunction; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ESimpleLambda extends Expression { public Variable parameter; public Expression value; @@ -56,36 +52,20 @@ public class ESimpleLambda extends Expression { this.effect = effect; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - value.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - } - - public Expression decomposeMatching() { + public Expression decomposeMatching() { value = value.decomposeMatching(); return this; } - @Override - protected void updateType() throws MatchException { - setType(Types.functionE(Types.canonical(parameter.type), - effect, value.getType())); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - return lambdaToVal(context, w); + @Override + protected void updateType() throws MatchException { + setType(Types.functionE(Types.canonical(parameter.type), + effect, value.getType())); } @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - vars.remove(parameter); + public IVal toVal(CompilationContext context, CodeWriter w) { + return lambdaToVal(context, w); } @Override @@ -148,7 +128,7 @@ public class ESimpleLambda extends Expression { // Free variables; ExpressionInterpretationContext innerContext = context.createNewContext(); - THashSet freeVariables = cur.getFreeVariables(); + Set freeVariables = cur.getFreeVariables(); for(Variable parameter : parameters) freeVariables.remove(parameter); int i=0; @@ -198,22 +178,11 @@ public class ESimpleLambda extends Expression { return this; } - @Override - public Expression decorate(ExpressionDecorator decorator) { - if(decorator.decorateSubstructure(this)) - value = value.decorate(decorator); - return decorator.decorate(this); - } - @Override public boolean isEffectful() { return false; } - @Override - public void collectEffects(THashSet effects) { - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -234,11 +203,6 @@ public class ESimpleLambda extends Expression { public Variable getParameter() { return parameter; } - - @Override - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java index e8fd9cf94..aedb05d4b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java @@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.ILet; import org.simantics.scl.compiler.internal.interpreted.ISeq; @@ -16,14 +15,10 @@ import org.simantics.scl.compiler.top.ExpressionInterpretationContext; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ESimpleLet extends Expression { - Variable variable; // may be null - Expression value; - Expression in; + public Variable variable; // may be null + public Expression value; + public Expression in; public ESimpleLet(Variable variable, Expression value, Expression in) { if(value == null) @@ -46,36 +41,17 @@ public class ESimpleLet extends Expression { this.in = in; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - value.collectRefs(allRefs, refs); - in.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - in.collectVars(allVars, vars); - } - @Override protected void updateType() throws MatchException { setType(in.getType()); } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - IVal valueVal = value.toVal(context, w); - if(variable != null) - variable.setVal(valueVal); - return in.toVal(context, w); - } @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - in.collectFreeVariables(vars); - vars.remove(variable); + public IVal toVal(CompilationContext context, CodeWriter w) { + IVal valueVal = value.toVal(context, w); + if(variable != null) + variable.setVal(valueVal); + return in.toVal(context, w); } @Override @@ -175,19 +151,6 @@ public class ESimpleLet extends Expression { in = in.checkIgnoredType(context); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - value = value.decorate(decorator); - in = in.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - value.collectEffects(effects); - in.collectEffects(effects); - } @Override public void accept(ExpressionVisitor visitor) { @@ -206,12 +169,6 @@ public class ESimpleLet extends Expression { return in; } - @Override - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - in.forVariables(procedure); - } - @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java index 65b3f9b2f..b96907ea3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java @@ -10,16 +10,10 @@ import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.rules.TransformationRule; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.elaboration.transformations.TransformationBuilder; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.top.SCLCompilerConfiguration; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ETransformation extends SimplifiableExpression { public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object(); @@ -31,32 +25,10 @@ public class ETransformation extends SimplifiableExpression { this.seed = seed; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - { - int ref = allRefs.get(TRANSFORMATION_RULES_TYPECHECKED); - if(ref >= 0) - refs.add(ref); - } - seed.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - seed.collectVars(allVars, vars); - } - @Override protected void updateType() throws MatchException { setType(Types.UNIT); } - - @Override - public void collectFreeVariables(THashSet vars) { - seed.collectFreeVariables(vars); - } @Override public Expression inferType(TypingContext context) { @@ -102,26 +74,10 @@ public class ETransformation extends SimplifiableExpression { } } - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - effects.add(Types.PROC); - //seed.collectEffects(Query.RW, effects); // FIXME - } - @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - seed.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java index 654b4ef1f..713342ed5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java @@ -4,17 +4,12 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.types.TypeAst; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.exceptions.MatchException; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ETypeAnnotation extends SimplifiableExpression { - Expression value; + public Expression value; Type type; TypeAst typeAst; @@ -29,24 +24,9 @@ public class ETypeAnnotation extends SimplifiableExpression { this.type = type; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - value.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - } - - @Override - protected void updateType() throws MatchException { - setType(type); - } - @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); + protected void updateType() throws MatchException { + setType(type); } @Override @@ -72,17 +52,6 @@ public class ETypeAnnotation extends SimplifiableExpression { public Expression inferType(TypingContext context) { return value.checkType(context, type); } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - value = value.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - value.collectEffects(effects); - } @Override public void setLocationDeep(long loc) { @@ -100,11 +69,6 @@ public class ETypeAnnotation extends SimplifiableExpression { public Expression getValue() { return value; } - - @Override - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - } @Override public Expression accept(ExpressionTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java index 5311de2f1..7fe0e0a92 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java @@ -1,6 +1,8 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.compilation.CompilationContext; @@ -11,7 +13,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.interpreted.IVariable; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; @@ -21,14 +22,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EVariable extends Expression { public static final EVariable[] EMPTY_ARRAY = new EVariable[0]; - Variable variable; + public Variable variable; public EVariable(Variable variable) { this.variable = variable; @@ -47,34 +44,26 @@ public class EVariable extends Expression { this.variable = variable; } - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - int id = allVars.get(variable); - if(id >= 0) - vars.add(id); - } + @Override + public Set getFreeVariables() { + if(variable == null) + return Collections.emptySet(); + else + return Collections.singleton(variable); + } - public void toString(StringBuilder b, TypeUnparsingContext tuc) { + public void toString(StringBuilder b, TypeUnparsingContext tuc) { b.append(variable == null ? "???" : variable.toString()); } - @Override - protected void updateType() throws MatchException { - setType(variable.getType()); - } - - @Override - public IVal toVal(CompilationContext context, CodeWriter w) { - return variable.getVal(); + @Override + protected void updateType() throws MatchException { + setType(variable.getType()); } @Override - public void collectFreeVariables(THashSet vars) { - vars.add(variable); + public IVal toVal(CompilationContext context, CodeWriter w) { + return variable.getVal(); } @Override @@ -96,11 +85,6 @@ public class EVariable extends Expression { ArrayList parameters) { } - @Override - public void removeFreeVariables(THashSet vars) { - vars.remove(variable); - } - @Override public Expression resolveAsPattern(TranslationContext context) { return this; @@ -162,20 +146,11 @@ public class EVariable extends Expression { return context.subsume(this, requiredType); } - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } - @Override public boolean isEffectful() { return false; } - @Override - public void collectEffects(THashSet effects) { - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) @@ -186,12 +161,6 @@ public class EVariable extends Expression { public void accept(ExpressionVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - if(variable != null) - procedure.execute(location, variable); - } @Override public boolean isPattern(int arity) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java index a08ed3923..4957f7c85 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java @@ -8,16 +8,10 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.util.MultiFunction; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EViewPattern extends Expression { public Expression expression; public Expression pattern; @@ -26,24 +20,6 @@ public class EViewPattern extends Expression { this.expression = expression; this.pattern = pattern; } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - expression.collectRefs(allRefs, refs); - pattern.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - expression.collectVars(allVars, vars); - pattern.collectVars(allVars, vars); - } - - @Override - public void forVariables(VariableProcedure procedure) { - expression.forVariables(procedure); - pattern.forVariables(procedure); - } @Override public Expression inferType(TypingContext context) { @@ -73,17 +49,6 @@ public class EViewPattern extends Expression { throw new InternalCompilerError(location, "EViewPattern.toVal should not be invoked."); } - @Override - public void collectFreeVariables(THashSet vars) { - throw new InternalCompilerError(location, "Cannot collect free variables for a pattern."); - } - - @Override - public void removeFreeVariables(THashSet vars) { - expression.collectFreeVariables(vars); - pattern.removeFreeVariables(vars); - } - @Override public Expression resolve(TranslationContext context) { context.getErrorLog().log("View pattern cannot occur only in patterns. Maybe you are missing '\\' in front of a lambda experssion?"); @@ -106,17 +71,6 @@ public class EViewPattern extends Expression { } } - @Override - public Expression decorate(ExpressionDecorator decorator) { - expression = expression.decorate(decorator); - return this; - } - - @Override - public void collectEffects(THashSet effects) { - expression.collectEffects(effects); - } - @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java index bf47759de..df6d56888 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java @@ -1,6 +1,5 @@ package org.simantics.scl.compiler.elaboration.expressions; -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -11,22 +10,17 @@ import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilation import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationMode; import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class EWhen extends SimplifiableExpression { public Query query; public Expression action; - Variable[] variables; + public Variable[] variables; public EWhen(Query query, Expression action) { this.query = query; @@ -44,25 +38,6 @@ public class EWhen extends SimplifiableExpression { this.variables = variables; } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - query.collectRefs(allRefs, refs); - action.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - query.collectVars(allVars, vars); - action.collectVars(allVars, vars); - } - - @Override - public void collectEffects(THashSet effects) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects."); - } - @Override protected void updateType() throws MatchException { setType(Types.UNIT); @@ -97,14 +72,6 @@ public class EWhen extends SimplifiableExpression { } } - @Override - public void collectFreeVariables(THashSet vars) { - action.collectFreeVariables(vars); - query.collectFreeVariables(vars); - for(Variable var : variables) - vars.remove(var); - } - @Override public Expression resolve(TranslationContext context) { context.pushExistentialFrame(); @@ -113,11 +80,6 @@ public class EWhen extends SimplifiableExpression { variables = context.popExistentialFrame(); return this; } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - return decorator.decorate(this); - } @Override public Expression replace(ReplaceContext context) { @@ -155,12 +117,6 @@ public class EWhen extends SimplifiableExpression { public Expression getAction() { return action; } - - @Override - public void forVariables(VariableProcedure procedure) { - query.forVariables(procedure); - action.forVariables(procedure); - } @Override public Expression simplify(SimplificationContext context) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java index 2b75f61cd..3a2f845fe 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java @@ -1,6 +1,7 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; +import java.util.Set; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.precedence.Precedence; @@ -14,12 +15,17 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException; import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType; import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs; import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectEffectsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectFreeVariablesVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectVarsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor; import org.simantics.scl.compiler.elaboration.query.QAtom; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.parsing.Symbol; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; @@ -34,7 +40,6 @@ import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Typed; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public abstract class Expression extends Symbol implements Typed { @@ -56,10 +61,10 @@ public abstract class Expression extends Symbol implements Typed { try { updateType(); } catch (MatchException e) { - throw new InternalCompilerError(e); + throw new InternalCompilerError(location, e); } if(type == null) - throw new InternalCompilerError(getClass().getSimpleName() + + throw new InternalCompilerError(location, getClass().getSimpleName() + ".updateType couldn't compute its type."); } return type; @@ -103,23 +108,23 @@ public abstract class Expression extends Symbol implements Typed { expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT)); return expression; } - - /** - * Checks the type of the expression against the given type. Adds type - * applications and lambdas if needed. - */ - public final Expression checkType(TypingContext context, Type requiredType) { - //System.out.println("checkType: " + this + " :: " + requiredType); - if(!context.isInPattern()) { - requiredType = Types.canonical(requiredType); - if(requiredType instanceof TForAll) { + + /** + * Checks the type of the expression against the given type. Adds type + * applications and lambdas if needed. + */ + public final Expression checkType(TypingContext context, Type requiredType) { + //System.out.println("checkType: " + this + " :: " + requiredType); + if(!context.isInPattern()) { + requiredType = Types.canonical(requiredType); + if(requiredType instanceof TForAll) { TForAll forAll = (TForAll)requiredType; TVar var = forAll.var; TVar newVar = Types.var(var.getKind()); requiredType = Types.canonical(forAll.type).replace(var, newVar); return new ELambdaType(new TVar[] {newVar}, checkType(context, requiredType)); } - while(requiredType instanceof TFun) { + while(requiredType instanceof TFun) { TFun fun = (TFun)requiredType; if(fun.domain instanceof TPred) { // No need to canonicalize ArrayList constraints = new ArrayList(2); @@ -143,7 +148,7 @@ public abstract class Expression extends Symbol implements Typed { context.pushEffectUpperBound(location, fun.effect); Expression expr = checkType(context, fun.range); context.popEffectUpperBound(); - + // Wrap Variable var = new Variable("punit", Types.PUNIT); return new ESimpleLambda(location, var, fun.effect, expr); @@ -151,15 +156,23 @@ public abstract class Expression extends Symbol implements Typed { else break; } - } - return checkBasicType(context, requiredType); - } + } + return checkBasicType(context, requiredType); + } - public abstract void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs); - public abstract void collectVars(TObjectIntHashMap allVars, TIntHashSet vars); - public abstract void forVariables(VariableProcedure procedure); - - public Expression decomposeMatching() { + public final void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { + accept(new CollectRefsVisitor(allRefs, refs)); + } + + public final void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { + accept(new CollectVarsVisitor(allVars, vars)); + } + + public final void forVariableUses(VariableProcedure procedure) { + accept(new ForVariablesUsesVisitor(procedure)); + } + + public Expression decomposeMatching() { return this; } @@ -204,8 +217,6 @@ public abstract class Expression extends Symbol implements Typed { return new ELambdaType(vars, this); } - public abstract void collectFreeVariables(THashSet vars); - public Expression simplify(SimplificationContext context) { System.out.println("#############################"); System.out.println(this); @@ -231,32 +242,31 @@ public abstract class Expression extends Symbol implements Typed { public void getParameters(TranslationContext translationContext, ArrayList parameters) { - throw new InternalCompilerError("Class " + getClass().getSimpleName() + " does not support getParameters."); + throw new InternalCompilerError(location, "Class " + getClass().getSimpleName() + " does not support getParameters."); } public Expression resolveAsPattern(TranslationContext context) { context.getErrorLog().log(location, "Pattern was expected here."); return new EError(); } - - public void removeFreeVariables(THashSet vars) { - throw new InternalCompilerError(getClass().getSimpleName() + " is not a pattern."); - } public Expression checkTypeAsPattern(TypingContext context, Type requiredType) { if(context.isInPattern()) - throw new InternalCompilerError("Already in a pattern."); + throw new InternalCompilerError(location, "Already in a pattern."); context.setInPattern(true); Expression expression = checkType(context, requiredType); context.setInPattern(false); return expression; } - public THashSet getFreeVariables() { - THashSet result = new THashSet(); - collectFreeVariables(result); - return result; - } + /** + * Used during simplification and in toIExpression + */ + public Set getFreeVariables() { + CollectFreeVariablesVisitor visitor = new CollectFreeVariablesVisitor(); + accept(visitor); + return visitor.getFreeVariables(); + } public static Expression[] concat(Expression[] a, Expression[] b) { if(a.length == 0) @@ -272,7 +282,7 @@ public abstract class Expression extends Symbol implements Typed { } public Expression replace(ReplaceContext context) { - throw new InternalCompilerError(getClass().getSimpleName() + " does not support replace."); + throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support replace."); } public static Expression[] replace(ReplaceContext context, Expression[] expressions) { @@ -328,8 +338,6 @@ public abstract class Expression extends Symbol implements Typed { public Expression applyType(Type type) { return new EApplyType(location, this, type); } - - public abstract Expression decorate(ExpressionDecorator decorator); public boolean isEffectful() { return true; @@ -343,12 +351,10 @@ public abstract class Expression extends Symbol implements Typed { return false; } - public abstract void collectEffects(THashSet effects); - public Type getEffect() { - THashSet effects = new THashSet(); - collectEffects(effects); - return Types.union(effects.toArray(new Type[effects.size()])); + CollectEffectsVisitor visitor = new CollectEffectsVisitor(); + accept(visitor); + return visitor.getCombinedEffect(); } public abstract void accept(ExpressionVisitor visitor); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java index 4cf513c54..c0c329ba3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java @@ -9,6 +9,7 @@ public interface ExpressionTransformer { Expression transform(EBinary expression); Expression transform(EBind expression); Expression transform(EBlock expression); + Expression transform(ECHRSelect expression); Expression transform(ECHRRuleset expression); Expression transform(ECHRRulesetConstructor expression); Expression transform(EConstant expression); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionVisitor.java index ad32098ba..7dbcf69e2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionVisitor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionVisitor.java @@ -2,12 +2,14 @@ package org.simantics.scl.compiler.elaboration.expressions; public interface ExpressionVisitor { + void visit(EAmbiguous eAmbiguous); void visit(EApply expression); void visit(EApplyType expression); void visit(EAsPattern expression); void visit(EBinary expression); void visit(EBind expression); void visit(EBlock expression); + void visit(ECHRSelect expression); void visit(ECHRRuleset expression); void visit(ECHRRulesetConstructor expression); void visit(EConstant expression); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpression.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpression.java index 9791b068a..f1e62b2f7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpression.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpression.java @@ -2,7 +2,6 @@ package org.simantics.scl.compiler.elaboration.expressions; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.Symbol; public class GuardedExpression extends Symbol { @@ -20,12 +19,6 @@ public class GuardedExpression extends Symbol { value.replace(context)); } - public void decorate(ExpressionDecorator decorator) { - for(int i=0;i allRefs, - TIntHashSet refs) { - for(GuardedExpression expression : expressions) { - for(Expression guard : expression.guards) - guard.collectRefs(allRefs, refs); - expression.value.collectRefs(allRefs, refs); - } - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(GuardedExpression expression : expressions) { - for(Expression guard : expression.guards) - guard.collectVars(allVars, vars); - expression.value.collectVars(allVars, vars); - } - } - @Override protected void updateType() throws MatchException { setType(expressions[0].value.getType()); @@ -63,15 +38,6 @@ public class GuardedExpressionGroup extends Expression { //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation."); } - @Override - public void collectFreeVariables(THashSet vars) { - for(GuardedExpression expression : expressions) { - for(Expression guard : expression.guards) - guard.collectFreeVariables(vars); - expression.value.collectFreeVariables(vars); - } - } - @Override public Expression simplify(SimplificationContext context) { for(GuardedExpression expression : expressions) { @@ -137,22 +103,6 @@ public class GuardedExpressionGroup extends Expression { newExpressions[i] = expressions[i].replace(context); return new GuardedExpressionGroup(newExpressions); } - - @Override - public Expression decorate(ExpressionDecorator decorator) { - for(GuardedExpression expression : expressions) - expression.decorate(decorator); - return decorator.decorate(this); - } - - @Override - public void collectEffects(THashSet effects) { - for(GuardedExpression ge : expressions) { - for(Expression guard : ge.guards) - guard.collectEffects(effects); - ge.value.collectEffects(effects); - } - } @Override public void setLocationDeep(long loc) { @@ -168,12 +118,6 @@ public class GuardedExpressionGroup extends Expression { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - for(GuardedExpression expression : expressions) - expression.forVariables(procedure); - } - @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java index e3a1333c0..3df40521a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java @@ -4,16 +4,9 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.Types; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ExpressionAccessor extends FieldAccessor { public Expression fieldName; @@ -22,28 +15,6 @@ public class ExpressionAccessor extends FieldAccessor { this.fieldName = fieldName; } - @Override - public void collectFreeVariables(THashSet vars) { - fieldName.collectFreeVariables(vars); - } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - fieldName.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - fieldName.collectVars(allVars, vars); - } - - @Override - public void decorate(ExpressionDecorator decorator) { - fieldName = fieldName.decorate(decorator); - } - @Override public void resolve(TranslationContext context) { fieldName = fieldName.resolve(context); @@ -76,9 +47,4 @@ public class ExpressionAccessor extends FieldAccessor { public void accept(FieldAccessorVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - fieldName.forVariables(procedure); - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java index ce56da39f..de02aa695 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java @@ -4,15 +4,8 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.Symbol; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public abstract class FieldAccessor extends Symbol { public char accessSeparator; @@ -20,27 +13,13 @@ public abstract class FieldAccessor extends Symbol { this.accessSeparator = accessSeparator; } - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - } - - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - } - - public void collectFreeVariables(THashSet vars) { - } - public void simplify(SimplificationContext context) { } public void resolve(TranslationContext context) { } - public void decorate(ExpressionDecorator decorator) { - } - - public void checkType(TypingContext context) { + public void checkType(TypingContext context) { } public abstract Expression asExpression(); @@ -52,6 +31,4 @@ public abstract class FieldAccessor extends Symbol { public abstract void setLocationDeep(long loc); public abstract void accept(FieldAccessorVisitor visitor); - - public abstract void forVariables(VariableProcedure procedure); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/IdAccessor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/IdAccessor.java index 9cb37e58f..920a81606 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/IdAccessor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/IdAccessor.java @@ -3,7 +3,6 @@ package org.simantics.scl.compiler.elaboration.expressions.accessor; import org.simantics.scl.compiler.constants.StringConstant; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; public class IdAccessor extends FieldAccessor { @@ -34,8 +33,4 @@ public class IdAccessor extends FieldAccessor { public void accept(FieldAccessorVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/StringAccessor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/StringAccessor.java index d08a4383f..ac038d12c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/StringAccessor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/StringAccessor.java @@ -3,7 +3,6 @@ package org.simantics.scl.compiler.elaboration.expressions.accessor; import org.simantics.scl.compiler.constants.StringConstant; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; public class StringAccessor extends FieldAccessor { @@ -29,8 +28,4 @@ public class StringAccessor extends FieldAccessor { public void accept(FieldAccessorVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java index d58f9c360..0c41b513a 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java @@ -1,17 +1,17 @@ package org.simantics.scl.compiler.elaboration.expressions.block; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery; import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier; import org.simantics.scl.compiler.errors.Locations; public class CHRStatement extends Statement { - public ListQualifier[] head; - public ListQualifier[] body; + public CHRAstQuery head; + public CHRAstQuery body; - public CHRStatement(ListQualifier[] head, ListQualifier[] body) { + public CHRStatement(CHRAstQuery head, CHRAstQuery body) { this.head = head; this.body = body; } @@ -23,13 +23,8 @@ public class CHRStatement extends Statement { @Override public void setLocationDeep(long loc) { - if(location == Locations.NO_LOCATION) { + if(location == Locations.NO_LOCATION) location = loc; - for(ListQualifier lq : head) - lq.setLocationDeep(loc); - for(ListQualifier lq : body) - lq.setLocationDeep(loc); - } } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java index 89de0ebc3..cddcffc77 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java @@ -1,5 +1,7 @@ package org.simantics.scl.compiler.elaboration.expressions.list; +import java.util.Set; + import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -7,14 +9,7 @@ import org.simantics.scl.compiler.elaboration.expressions.Case; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; public class ListAssignment extends ListQualifier { public Expression pattern; @@ -31,30 +26,12 @@ public class ListAssignment extends ListQualifier { pattern.checkTypeAsPattern(context, value.getType()); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - value.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - pattern.collectFreeVariables(vars); - } - @Override public CompiledQualifier compile(SimplificationContext context) { if(pattern instanceof EVariable) return new CompiledQualifier(context.singletonList(value), pattern); else { - THashSet variables = pattern.getFreeVariables(); + Set variables = pattern.getFreeVariables(); Variable[] variableArray = variables.toArray(new Variable[variables.size()]); Expression[] variableExps = new Expression[variableArray.length]; for(int i=0;i effects) { - pattern.collectEffects(effects); - value.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -106,11 +71,6 @@ public class ListAssignment extends ListQualifier { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - } - @Override public ListQualifier accept(ListQualifierTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java index 7f480d8df..e0401e6dc 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java @@ -1,5 +1,7 @@ package org.simantics.scl.compiler.elaboration.expressions.list; +import java.util.Set; + import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; @@ -7,18 +9,11 @@ import org.simantics.scl.compiler.elaboration.expressions.Case; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.TMetaVar; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ListGenerator extends ListQualifier { public Expression pattern; public Expression value; @@ -35,30 +30,12 @@ public class ListGenerator extends ListQualifier { pattern.checkTypeAsPattern(context, componentType); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - value.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - value.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - value.collectFreeVariables(vars); - pattern.collectFreeVariables(vars); - } - @Override public CompiledQualifier compile(SimplificationContext context) { if(pattern instanceof EVariable) return new CompiledQualifier(value, pattern); else { - THashSet variables = pattern.getFreeVariables(); + Set variables = pattern.getFreeVariables(); Variable[] variableArray = variables.toArray(new Variable[variables.size()]); Expression[] variableExps = new Expression[variableArray.length]; for(int i=0;i effects) { - pattern.collectEffects(effects); - value.collectEffects(effects); - } - + @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -112,11 +77,6 @@ public class ListGenerator extends ListQualifier { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - value.forVariables(procedure); - } - @Override public ListQualifier accept(ListQualifierTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java index fdd159235..e5e8ee9d4 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java @@ -4,17 +4,9 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ListGuard extends ListQualifier { public Expression condition; @@ -27,23 +19,6 @@ public class ListGuard extends ListQualifier { condition.checkType(context, Types.BOOLEAN); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - condition.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - condition.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - condition.collectFreeVariables(vars); - } - @Override public CompiledQualifier compile(SimplificationContext context) { return new CompiledQualifier( @@ -53,19 +28,9 @@ public class ListGuard extends ListQualifier { @Override public void resolve(TranslationContext context) { - condition = condition.resolve(context); + condition = condition.resolve(context); } - @Override - public void decorate(ExpressionDecorator decorator) { - condition = condition.decorate(decorator); - } - - @Override - public void collectEffects(THashSet effects) { - condition.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -79,11 +44,6 @@ public class ListGuard extends ListQualifier { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - condition.forVariables(procedure); - } - @Override public ListQualifier accept(ListQualifierTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java index 67d20374e..69818ef01 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java @@ -3,29 +3,18 @@ package org.simantics.scl.compiler.elaboration.expressions.list; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.parsing.Symbol; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; public abstract class ListQualifier extends Symbol { public abstract void checkType(TypingContext context); - public abstract void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs); - public abstract void collectVars(TObjectIntHashMap allVars, TIntHashSet vars); - public abstract void collectFreeVariables(THashSet vars); + /** + * Called in simplification. + */ public abstract CompiledQualifier compile(SimplificationContext context); public abstract void resolve(TranslationContext context); - public abstract void decorate(ExpressionDecorator decorator); - public abstract void collectEffects(THashSet effects); public abstract void setLocationDeep(long loc); public abstract void accept(ListQualifierVisitor visitor); public abstract ListQualifier accept(ListQualifierTransformer transformer); - public abstract void forVariables(VariableProcedure procedure); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java index 16fc84f89..f1126121f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java @@ -5,14 +5,7 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; -import org.simantics.scl.compiler.types.Type; - -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; public class ListSeq extends ListQualifier { public ListQualifier a; @@ -28,26 +21,6 @@ public class ListSeq extends ListQualifier { a.checkType(context); b.checkType(context); } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - a.collectRefs(allRefs, refs); - b.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - a.collectVars(allVars, vars); - b.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - b.collectFreeVariables(vars); - a.collectFreeVariables(vars); - } @Override public CompiledQualifier compile(SimplificationContext context) { @@ -76,18 +49,6 @@ public class ListSeq extends ListQualifier { b.resolve(context); } - @Override - public void decorate(ExpressionDecorator decorator) { - a.decorate(decorator); - b.decorate(decorator); - } - - @Override - public void collectEffects(THashSet effects) { - a.collectEffects(effects); - b.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -102,12 +63,6 @@ public class ListSeq extends ListQualifier { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - a.forVariables(procedure); - b.forVariables(procedure); - } - @Override public ListQualifier accept(ListQualifierTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java index f8f3c3dd9..df1d1f2b0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java @@ -4,20 +4,13 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.TMetaVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.UnificationException; import org.simantics.scl.compiler.types.kinds.Kinds; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class ListThen extends ListQualifier { public ListQualifier left; public Expression transformer; @@ -49,32 +42,6 @@ public class ListThen extends ListQualifier { } } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - left.collectRefs(allRefs, refs); - transformer.collectRefs(allRefs, refs); - if(by != null) - by.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - left.collectVars(allVars, vars); - transformer.collectVars(allVars, vars); - if(by != null) - by.collectVars(allVars, vars); - } - - @Override - public void collectFreeVariables(THashSet vars) { - left.collectFreeVariables(vars); - transformer.collectFreeVariables(vars); - if(by != null) - by.collectFreeVariables(vars); - } - @Override public CompiledQualifier compile(SimplificationContext context) { CompiledQualifier q = left.compile(context); @@ -100,22 +67,6 @@ public class ListThen extends ListQualifier { by = by.resolve(context); } - @Override - public void decorate(ExpressionDecorator decorator) { - transformer = transformer.decorate(decorator); - if(by != null) - by = by.decorate(decorator); - left.decorate(decorator); - } - - @Override - public void collectEffects(THashSet effects) { - left.collectEffects(effects); - transformer.collectEffects(effects); - if(by != null) - by.collectEffects(effects); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -131,14 +82,6 @@ public class ListThen extends ListQualifier { public void accept(ListQualifierVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - left.forVariables(procedure); - transformer.forVariables(procedure); - if(by != null) - by.forVariables(procedure); - } @Override public ListQualifier accept(ListQualifierTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java index 3f6da74cb..b1a05d70e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java @@ -8,6 +8,7 @@ import org.simantics.scl.compiler.elaboration.chr.CHRRule; import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; import org.simantics.scl.compiler.elaboration.expressions.Assignment; import org.simantics.scl.compiler.elaboration.expressions.Case; +import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EApplyType; import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; @@ -16,6 +17,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EBind; import org.simantics.scl.compiler.elaboration.expressions.EBlock; import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset; import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor; +import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect; import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint; import org.simantics.scl.compiler.elaboration.expressions.EEnforce; @@ -329,7 +331,12 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito public void visit(ESelect expression) { b.append("ESelect"); } - + + @Override + public void visit(ECHRSelect expression) { + b.append("ECHRSelect"); + } + @Override public void visit(ESimpleLambda expression) { b.append('\\'); @@ -606,4 +613,9 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito } b.append('"'); } + + @Override + public void visit(EAmbiguous eAmbiguous) { + b.append("EAmbigious"); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/records/FieldAssignment.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/records/FieldAssignment.java index a26cd857b..af84130f8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/records/FieldAssignment.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/records/FieldAssignment.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.elaboration.expressions.records; +import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.internal.parsing.Symbol; @@ -11,4 +12,8 @@ public class FieldAssignment extends Symbol { this.name = name; this.value = value; } + + public FieldAssignment replace(ReplaceContext context) { + return new FieldAssignment(name, value == null ? null : value.replace(context)); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectEffectsVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectEffectsVisitor.java new file mode 100644 index 000000000..10190d5a4 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectEffectsVisitor.java @@ -0,0 +1,71 @@ +package org.simantics.scl.compiler.elaboration.expressions.visitors; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.CHRRule; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect; +import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess; +import org.simantics.scl.compiler.elaboration.expressions.ELambda; +import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; +import org.simantics.scl.compiler.elaboration.expressions.ETransformation; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; + +import gnu.trove.set.hash.THashSet; + +public class CollectEffectsVisitor extends StandardExpressionVisitor { + public final THashSet effects = new THashSet(); + + @Override + public void visit(EApply expression) { + effects.add(expression.effect); + super.visit(expression); + } + + @Override + public void visit(CHRRule rule) { + for(CHRLiteral literal : rule.head.literals) { + super.visit(literal); + literal.relation.collectQueryEffects(effects); + } + for(CHRLiteral literal : rule.body.literals) { + super.visit(literal); + literal.relation.collectEnforceEffects(effects); + } + } + + @Override + public void visit(ECHRSelect expression) { + for(CHRLiteral literal : expression.query.literals) { + super.visit(literal); + literal.relation.collectQueryEffects(effects); + } + expression.expression.accept(this); + } + + @Override + public void visit(EFieldAccess expression) { + // FIXME + effects.add(Types.READ_GRAPH); + super.visit(expression); + } + + @Override + public void visit(ETransformation expression) { + // FIXME + effects.add(Types.PROC); + super.visit(expression); + } + + @Override + public void visit(ELambda expression) { + } + + @Override + public void visit(ESimpleLambda expression) { + } + + public Type getCombinedEffect() { + return Types.union(effects.toArray(new Type[effects.size()])); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java new file mode 100644 index 000000000..04f6791ac --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java @@ -0,0 +1,184 @@ +package org.simantics.scl.compiler.elaboration.expressions.visitors; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.CHRQuery; +import org.simantics.scl.compiler.elaboration.chr.CHRRule; +import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation; +import org.simantics.scl.compiler.elaboration.expressions.Assignment; +import org.simantics.scl.compiler.elaboration.expressions.Case; +import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; +import org.simantics.scl.compiler.elaboration.expressions.EBind; +import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect; +import org.simantics.scl.compiler.elaboration.expressions.ELet; +import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule; +import org.simantics.scl.compiler.elaboration.expressions.ESelect; +import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; +import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.EViewPattern; +import org.simantics.scl.compiler.elaboration.expressions.EWhen; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment; +import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator; +import org.simantics.scl.compiler.elaboration.query.QExists; + +import gnu.trove.set.hash.THashSet; + +public class CollectFreeVariablesVisitor extends StandardExpressionVisitor { + private THashSet freeVariables = new THashSet(); + + private StandardExpressionVisitor collectBoundVariablesVisitor = new StandardExpressionVisitor() { + @Override + public void visit(EVariable expression) { + if(expression.variable != null) + freeVariables.remove(expression.variable); + } + + + @Override + public void visit(EAsPattern expression) { + freeVariables.remove(expression.var); + expression.pattern.accept(this); + } + + @Override + public void visit(EViewPattern expression) { + expression.expression.accept(CollectFreeVariablesVisitor.this); + expression.pattern.accept(this); + } + }; + + @Override + public void visit(EVariable expression) { + if(expression.variable != null) + freeVariables.add(expression.variable); + } + + @Override + public void visit(EBind expression) { + if(expression.monadEvidence != null) + visit(expression.monadEvidence); + expression.in.accept(this); + expression.value.accept(this); + expression.pattern.accept(collectBoundVariablesVisitor); + } + + @Override + public void visit(Assignment assignment) { + assignment.value.accept(this); + assignment.pattern.accept(collectBoundVariablesVisitor); + } + + @Override + public void visit(ELet expression) { + expression.in.accept(this); + for(int i=expression.assignments.length-1;i>=0;--i) + visit(expression.assignments[i]); + } + + @Override + public void visit(Case case_) { + case_.value.accept(this); + for(Expression pattern : case_.patterns) + pattern.accept(collectBoundVariablesVisitor); + } + + @Override + public void visit(ESimpleLambda expression) { + expression.value.accept(this); + freeVariables.remove(expression.parameter); + } + + @Override + public void visit(ESimpleLet expression) { + expression.in.accept(this); + expression.value.accept(this); + freeVariables.remove(expression.variable); + } + + @Override + public void visit(ECHRSelect expression) { + expression.expression.accept(this); + visit(expression.query); + for(Variable variable : expression.existentialVariables) + freeVariables.remove(variable); + } + + @Override + public void visit(ESelect expression) { + expression.expression.accept(this); + expression.query.accept(this); + for(Variable variable : expression.variables) + freeVariables.remove(variable); + } + + @Override + public void visit(EWhen expression) { + expression.action.accept(this); + expression.query.accept(this); + for(Variable variable : expression.variables) + freeVariables.remove(variable); + } + + @Override + public void visit(DatalogRule rule) { + for(Expression parameter : rule.headParameters) + parameter.accept(this); + rule.body.accept(this); + for(Variable variable : rule.variables) + freeVariables.remove(variable); + } + + @Override + public void visit(ListGenerator qualifier) { + qualifier.pattern.accept(collectBoundVariablesVisitor); + qualifier.value.accept(this); + } + + @Override + public void visit(ListAssignment qualifier) { + qualifier.pattern.accept(collectBoundVariablesVisitor); + qualifier.value.accept(this); + } + + @Override + public void visit(CHRLiteral literal) { + if(literal.relation == SpecialCHRRelation.ASSIGN) { + literal.parameters[0].accept(collectBoundVariablesVisitor); + literal.parameters[1].accept(this); + } + else { + for(Expression parameter : literal.parameters) + parameter.accept(this); + if(literal.typeConstraintEvidenceParameters != null) + for(Expression parameter : literal.typeConstraintEvidenceParameters) + parameter.accept(this); + } + } + + @Override + public void visit(CHRQuery query) { + for(int i=query.literals.length-1;i>=0;--i) { + visit(query.literals[i]); + } + } + + @Override + public void visit(CHRRule rule) { + super.visit(rule); + for(Variable variable : rule.existentialVariables) + freeVariables.remove(variable); + } + + @Override + public void visit(QExists query) { + query.query.accept(this); + for(Variable variable : query.variables) + freeVariables.remove(variable); + } + + public THashSet getFreeVariables() { + return freeVariables; + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectRefsVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectRefsVisitor.java new file mode 100644 index 000000000..5445f0892 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectRefsVisitor.java @@ -0,0 +1,55 @@ +package org.simantics.scl.compiler.elaboration.expressions.visitors; + +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.ETransformation; +import org.simantics.scl.compiler.elaboration.query.QAtom; +import org.simantics.scl.compiler.elaboration.relations.CompositeRelation; +import org.simantics.scl.compiler.elaboration.relations.SCLRelation; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.TIntHashSet; + +public class CollectRefsVisitor extends StandardExpressionVisitor { + private final TObjectIntHashMap allRefs; + private final TIntHashSet refs; + + public CollectRefsVisitor(TObjectIntHashMap allRefs, TIntHashSet refs) { + this.allRefs = allRefs; + this.refs = refs; + } + + @Override + public void visit(ETransformation expression) { + { + int ref = allRefs.get(ETransformation.TRANSFORMATION_RULES_TYPECHECKED); + if(ref >= 0) + refs.add(ref); + } + super.visit(expression); + } + + @Override + public void visit(EConstant expression) { + int id = allRefs.get(expression.value); + if(id >= 0) + refs.add(id); + } + + @Override + public void visit(QAtom query) { + collectRelationRefs(query.relation); + super.visit(query); + } + + private void collectRelationRefs(SCLRelation relation) { + if(relation instanceof CompositeRelation) { + for(SCLRelation subrelation : ((CompositeRelation) relation).getSubrelations()) + collectRelationRefs(subrelation); + } + else { + int id = allRefs.get(relation); + if(id >= 0) + refs.add(id); + } + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectVarsVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectVarsVisitor.java new file mode 100644 index 000000000..7c4bee0f1 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectVarsVisitor.java @@ -0,0 +1,35 @@ +package org.simantics.scl.compiler.elaboration.expressions.visitors; + +import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.Variable; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.TIntHashSet; + +public class CollectVarsVisitor extends StandardExpressionVisitor { + private final TObjectIntHashMap allVars; + private final TIntHashSet vars; + + public CollectVarsVisitor(TObjectIntHashMap allVars, TIntHashSet vars) { + this.allVars = allVars; + this.vars = vars; + } + + @Override + public void visit(EVariable expression) { + if(expression.variable != null) { + int id = allVars.get(expression.variable); + if(id >= 0) + vars.add(id); + } + } + + @Override + public void visit(EAsPattern expression) { + int id = allVars.get(expression.var); + if(id >= 0) + vars.add(id); + expression.pattern.accept(this); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/ForVariablesUsesVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/ForVariablesUsesVisitor.java new file mode 100644 index 000000000..57befad98 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/ForVariablesUsesVisitor.java @@ -0,0 +1,24 @@ +package org.simantics.scl.compiler.elaboration.expressions.visitors; + +import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; + +public class ForVariablesUsesVisitor extends StandardExpressionVisitor { + VariableProcedure procedure; + + public ForVariablesUsesVisitor(VariableProcedure procedure) { + this.procedure = procedure; + } + + @Override + public void visit(EVariable expression) { + if(expression.variable != null) + procedure.execute(expression.location, expression.variable); + } + @Override + public void visit(EAsPattern expression) { + expression.pattern.accept(this); + procedure.execute(expression.eVar.location, expression.var); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/StandardExpressionTransformer.java similarity index 74% rename from bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java rename to bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/StandardExpressionTransformer.java index 1bd0d22c4..2a0ff5a06 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/StandardExpressionTransformer.java @@ -1,12 +1,72 @@ -package org.simantics.scl.compiler.elaboration.expressions; +package org.simantics.scl.compiler.elaboration.expressions.visitors; import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.CHRQuery; import org.simantics.scl.compiler.elaboration.chr.CHRRule; import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstNegation; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQueryVisitor; import org.simantics.scl.compiler.elaboration.equation.EqBasic; import org.simantics.scl.compiler.elaboration.equation.EqGuard; import org.simantics.scl.compiler.elaboration.equation.Equation; import org.simantics.scl.compiler.elaboration.equation.EquationVisitor; +import org.simantics.scl.compiler.elaboration.expressions.Assignment; +import org.simantics.scl.compiler.elaboration.expressions.Case; +import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous; +import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.EApplyType; +import org.simantics.scl.compiler.elaboration.expressions.EAsPattern; +import org.simantics.scl.compiler.elaboration.expressions.EBinary; +import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide; +import org.simantics.scl.compiler.elaboration.expressions.EBind; +import org.simantics.scl.compiler.elaboration.expressions.EBlock; +import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset; +import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor; +import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect; +import org.simantics.scl.compiler.elaboration.expressions.EConstant; +import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint; +import org.simantics.scl.compiler.elaboration.expressions.EEnforce; +import org.simantics.scl.compiler.elaboration.expressions.EEquations; +import org.simantics.scl.compiler.elaboration.expressions.EError; +import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant; +import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess; +import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint; +import org.simantics.scl.compiler.elaboration.expressions.EIf; +import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral; +import org.simantics.scl.compiler.elaboration.expressions.ELambda; +import org.simantics.scl.compiler.elaboration.expressions.ELambdaType; +import org.simantics.scl.compiler.elaboration.expressions.ELet; +import org.simantics.scl.compiler.elaboration.expressions.EListComprehension; +import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; +import org.simantics.scl.compiler.elaboration.expressions.ELiteral; +import org.simantics.scl.compiler.elaboration.expressions.EMatch; +import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder; +import org.simantics.scl.compiler.elaboration.expressions.EPreLet; +import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset; +import org.simantics.scl.compiler.elaboration.expressions.ERange; +import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral; +import org.simantics.scl.compiler.elaboration.expressions.ERecord; +import org.simantics.scl.compiler.elaboration.expressions.ERuleset; +import org.simantics.scl.compiler.elaboration.expressions.ESelect; +import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; +import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet; +import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral; +import org.simantics.scl.compiler.elaboration.expressions.ETransformation; +import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation; +import org.simantics.scl.compiler.elaboration.expressions.EVar; +import org.simantics.scl.compiler.elaboration.expressions.EVariable; +import org.simantics.scl.compiler.elaboration.expressions.EViewPattern; +import org.simantics.scl.compiler.elaboration.expressions.EWhen; +import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.expressions.ExpressionTransformer; +import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression; +import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup; +import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor; import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement; import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement; @@ -40,10 +100,12 @@ import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; public class StandardExpressionTransformer implements ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor, -EquationVisitor { +EquationVisitor, CHRAstQueryVisitor { @Override public Expression transform(EAmbiguous expression) { + if(expression.resolvedExpression != null) + expression.resolvedExpression = expression.resolvedExpression.accept(this); return expression; } @@ -125,14 +187,16 @@ EquationVisitor { statement.value = statement.value.accept(this); } + public void transform(CHRQuery query) { + for(CHRLiteral lit : query.literals) + for(int i=0;i Dynamic + */ +public class DynamicConstructor extends FunctionValue { + private static final TVar A = Types.var(Kinds.STAR); + public static final DynamicConstructor INSTANCE = new DynamicConstructor(); + + private DynamicConstructor() { + super(new TVar[] {A}, Types.NO_EFFECTS, Types.DYNAMIC, A); + } + + @Override + public Type applyExact(MethodBuilder mb, Val[] parameters) { + mb.pushBoxed(parameters[0]); + return Types.DYNAMIC; + } + + @Override + public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) { + Type expectedType = success.getParameterType(0); + TypeDesc expectedTypeDesc = mb.getJavaTypeTranslator().toTypeDesc(expectedType); + TypeDesc expectedObjectTypeDesc = expectedTypeDesc.toObjectType(); + LocalVariable cachedParameter = mb.cacheValue(parameter, Types.DYNAMIC); + mb.loadLocal(cachedParameter); + mb.instanceOf(expectedObjectTypeDesc); + mb.ifZeroComparisonBranch(failure, "=="); + + mb.loadLocal(cachedParameter); + mb.checkCast(expectedObjectTypeDesc); + mb.unbox(expectedType); + LocalVariable casted = mb.createLocalVariable("dynamicContent", expectedTypeDesc); + mb.storeLocal(casted); + mb.jump(success, new LocalVariableConstant(expectedType, casted)); + } +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/EqRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/EqRelation.java index 7116ed9f1..316506a5c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/EqRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/EqRelation.java @@ -75,5 +75,14 @@ public class EqRelation extends AbstractRelation { public String toString() { return "="; } - + + @Override + public Type getEnforceEffect() { + return Types.NO_EFFECTS; + } + + @Override + public Type getQueryEffect() { + return Types.NO_EFFECTS; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ExecuteRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ExecuteRelation.java index 10f36193e..5537f71ab 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ExecuteRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ExecuteRelation.java @@ -70,5 +70,14 @@ public class ExecuteRelation extends AbstractRelation { public String toString() { return "Execute"; } - + + @Override + public Type getEnforceEffect() { + return Types.NO_EFFECTS; + } + + @Override + public Type getQueryEffect() { + return Types.NO_EFFECTS; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java index e412a1168..aeec9a35b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java @@ -23,7 +23,7 @@ import org.simantics.scl.compiler.types.kinds.Kinds; public class JavaModule extends ConcreteModule { - public static final JavaModule INSTANCE = new JavaModule(); + public static JavaModule INSTANCE = new JavaModule(); public static final String MODULE_NAME = "JavaBuiltin"; @@ -147,6 +147,9 @@ public class JavaModule extends ConcreteModule { result = new EApplyType(result, var); return result; } - + + public static void flush() { + INSTANCE = new JavaModule(); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MemberRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MemberRelation.java index a022d1b37..f43b62b07 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MemberRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MemberRelation.java @@ -80,4 +80,14 @@ public class MemberRelation extends AbstractRelation { public String toString() { return "<-"; } + + @Override + public Type getEnforceEffect() { + return Types.NO_EFFECTS; + } + + @Override + public Type getQueryEffect() { + return Types.NO_EFFECTS; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java index 434f2da6e..b68657a1c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java @@ -261,6 +261,16 @@ public class MinigraphModule extends ConcreteModule { public String toString() { return "Statement"; } + + @Override + public Type getEnforceEffect() { + return GRAPH; + } + + @Override + public Type getQueryEffect() { + return GRAPH; + } }); addEntityType("Resource", new SCLEntityType() { @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java index ef30deb43..89568cb57 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java @@ -80,4 +80,14 @@ public class OptionalRelation extends AbstractRelation { public String toString() { return "Optional"; } + + @Override + public Type getEnforceEffect() { + return Types.NO_EFFECTS; + } + + @Override + public Type getQueryEffect() { + return Types.NO_EFFECTS; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java index 53eb780fd..a3ca43d36 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java @@ -7,27 +7,16 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.EApply; 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.VariableProcedure; import org.simantics.scl.compiler.elaboration.query.pre.QPreExists; import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard; import org.simantics.scl.compiler.errors.Locations; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public abstract class QAbstractCombiner extends Query { public Query[] queries; public QAbstractCombiner(Query[] queries) { this.queries = queries; } - - public void collectFreeVariables(THashSet vars) { - for(Query query : queries) - query.collectFreeVariables(vars); - } @Override public Query resolve(TranslationContext context) { @@ -75,18 +64,6 @@ public abstract class QAbstractCombiner extends Query { query.checkType(context); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - for(Query query : queries) - query.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - for(Query query : queries) - query.collectVars(allVars, vars); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -95,10 +72,4 @@ public abstract class QAbstractCombiner extends Query { query.setLocationDeep(loc); } } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Query query : queries) - query.forVariables(procedure); - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java index e04246e40..d580f2bb0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java @@ -2,24 +2,14 @@ package org.simantics.scl.compiler.elaboration.query; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.errors.Locations; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public abstract class QAbstractModifier extends Query { public Query query; public QAbstractModifier(Query query) { this.query = query; } - - public void collectFreeVariables(THashSet vars) { - query.collectFreeVariables(vars); - } @Override public Query resolve(TranslationContext context) { @@ -32,18 +22,6 @@ public abstract class QAbstractModifier extends Query { query.checkType(context); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - query.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - query.collectVars(allVars, vars); - } - @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { @@ -51,9 +29,4 @@ public abstract class QAbstractModifier extends Query { query.setLocationDeep(loc); } } - - @Override - public void forVariables(VariableProcedure procedure) { - query.forVariables(procedure); - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java index fd7dacb79..5f13bfd7b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java @@ -27,8 +27,6 @@ import org.simantics.scl.compiler.types.Types; import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.TIntObjectHashMap; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public class QAtom extends Query { @@ -47,12 +45,6 @@ public class QAtom extends Query { this.parameters = parameters; } - @Override - public void collectFreeVariables(THashSet vars) { - for(Expression parameter : parameters) - parameter.collectFreeVariables(vars); - } - @Override public void checkType(TypingContext context) { // Type parameters @@ -129,7 +121,7 @@ public class QAtom extends Query { } else { optionalVariableByParameter[i] = -1; - parameter.forVariables(procedure); + parameter.forVariableUses(procedure); } } } @@ -147,34 +139,6 @@ public class QAtom extends Query { } } - private static void collectRefs(SCLRelation relation, TObjectIntHashMap allRefs, - TIntHashSet refs) { - if(relation instanceof CompositeRelation) { - for(SCLRelation subrelation : ((CompositeRelation) relation).getSubrelations()) - collectRefs(subrelation, allRefs, refs); - } - else { - int id = allRefs.get(relation); - if(id >= 0) - refs.add(id); - } - } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - collectRefs(relation, allRefs, refs); - for(Expression parameter : parameters) - parameter.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(Expression parameter : parameters) - parameter.collectVars(allVars, vars); - } - @Override public Query replace(ReplaceContext context) { Type[] newTypeParameters; @@ -250,12 +214,6 @@ public class QAtom extends Query { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - for(Expression parameter : parameters) - parameter.forVariables(procedure); - } - @Override public void splitToPhases(TIntObjectHashMap> result) { int phase = relation.getPhase(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java index 5356eccc2..2f9c0c507 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java @@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException; import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException; @@ -18,10 +17,9 @@ import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; public class QExists extends QAbstractModifier { - Variable[] variables; + public Variable[] variables; public QExists(Variable[] variables, Query query) { super(query); @@ -32,13 +30,6 @@ public class QExists extends QAbstractModifier { this(variables.toArray(new Variable[variables.size()]), query); } - @Override - public void collectFreeVariables(THashSet vars) { - super.collectFreeVariables(vars); - for(Variable variable : variables) - vars.remove(variable); - } - @Override public void checkType(TypingContext context) { for(Variable var : variables) @@ -92,13 +83,6 @@ public class QExists extends QAbstractModifier { visitor.visit(this); } - @Override - public void forVariables(VariableProcedure procedure) { - for(Variable variable : variables) - procedure.execute(location, variable); - super.forVariables(procedure); - } - @Override public Query accept(QueryTransformer transformer) { return transformer.transform(this); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QIf.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QIf.java index 62ff9583c..03bcec3e9 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QIf.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QIf.java @@ -4,17 +4,11 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.Types; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class QIf extends Query { public Expression condition; public Query thenQuery; @@ -25,28 +19,7 @@ public class QIf extends Query { this.thenQuery = thenQuery; this.elseQuery = elseQuery; } - - @Override - public void collectFreeVariables(THashSet vars) { - condition.collectFreeVariables(vars); - thenQuery.collectFreeVariables(vars); - elseQuery.collectFreeVariables(vars); - } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { - condition.collectRefs(allRefs, refs); - thenQuery.collectRefs(allRefs, refs); - elseQuery.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { - condition.collectVars(allVars, vars); - thenQuery.collectVars(allVars, vars); - elseQuery.collectVars(allVars, vars); - } - + @Override public void checkType(TypingContext context) { condition.checkType(context, Types.BOOLEAN); @@ -82,13 +55,6 @@ public class QIf extends Query { public void accept(QueryVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - condition.forVariables(procedure); - elseQuery.forVariables(procedure); - thenQuery.forVariables(procedure); - } @Override public Query accept(QueryTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java index ca9378c89..02061b798 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java @@ -5,18 +5,12 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; -import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException; import org.simantics.scl.compiler.elaboration.rules.MappingRelation; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.types.Type; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - public class QMapping extends Query { public final MappingRelation mappingRelation; public final Expression[] parameters; @@ -26,26 +20,6 @@ public class QMapping extends Query { this.parameters = parameters; } - @Override - public void collectFreeVariables(THashSet vars) { - for(Expression parameter : parameters) - parameter.collectFreeVariables(vars); - } - - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - for(Expression parameter : parameters) - parameter.collectRefs(allRefs, refs); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - for(Expression parameter : parameters) - parameter.collectVars(allVars, vars); - } - @Override public void checkType(TypingContext context) { // Check parameter types @@ -82,12 +56,6 @@ public class QMapping extends Query { public void accept(QueryVisitor visitor) { visitor.visit(this); } - - @Override - public void forVariables(VariableProcedure procedure) { - for(Expression parameter : parameters) - parameter.forVariables(procedure); - } @Override public Query accept(QueryTransformer transformer) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java index 0ac54e22e..58f780754 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java @@ -10,10 +10,13 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.EError; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer; -import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionVisitor; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectVarsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor; import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException; import org.simantics.scl.compiler.elaboration.query.compilation.DynamicProgrammingOrdering; @@ -29,15 +32,11 @@ import org.simantics.scl.compiler.internal.parsing.Symbol; import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public abstract class Query extends Symbol { public static final Query[] EMPTY_ARRAY = new Query[0]; - public abstract void collectFreeVariables(THashSet vars); - public abstract void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs); - public abstract void collectVars(TObjectIntHashMap allVars, TIntHashSet vars); public abstract void checkType(TypingContext context); public Query resolve(TranslationContext context) { @@ -135,8 +134,6 @@ public abstract class Query extends Symbol { }); } - public abstract void forVariables(VariableProcedure procedure); - public TIntObjectHashMap> splitToPhases() { TIntObjectHashMap> result = new TIntObjectHashMap>(2); splitToPhases(result); @@ -156,4 +153,15 @@ public abstract class Query extends Symbol { } public abstract Query accept(QueryTransformer transformer); + + public void forVariables(VariableProcedure procedure) { + accept(new ForVariablesUsesVisitor(procedure)); + } + public void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { + accept(new CollectRefsVisitor(allRefs, refs)); + } + + public void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { + accept(new CollectVarsVisitor(allVars, vars)); + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java index ee96433d3..2f4d14bae 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java @@ -6,17 +6,12 @@ import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Variable; -import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure; import org.simantics.scl.compiler.elaboration.query.QConjunction; import org.simantics.scl.compiler.elaboration.query.QExists; import org.simantics.scl.compiler.elaboration.query.Query; import org.simantics.scl.compiler.elaboration.query.QueryVisitor; import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext; -import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; -import gnu.trove.set.hash.TIntHashSet; - /** * Query classes that may exist before resolving */ @@ -24,11 +19,6 @@ public abstract class PreQuery extends Query { public ArrayList extraVariables = new ArrayList(2); public ArrayList sideQueries = new ArrayList(2); - - @Override - public void collectFreeVariables(THashSet vars) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectFreeVariables."); - } @Override public void checkType(TypingContext context) { @@ -40,18 +30,6 @@ public abstract class PreQuery extends Query { throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectConstraints."); } - @Override - public void collectRefs(TObjectIntHashMap allRefs, - TIntHashSet refs) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectRefs."); - } - - @Override - public void collectVars(TObjectIntHashMap allVars, - TIntHashSet vars) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectVars."); - } - @Override public Query replace(ReplaceContext replaceContext) { throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support replace."); @@ -71,9 +49,4 @@ public abstract class PreQuery extends Query { query = new QExists(extraVariables.toArray(new Variable[extraVariables.size()]), query); return query; } - - @Override - public void forVariables(VariableProcedure procedure) { - throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support forVariables."); - } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java index 96ace3b64..bcdcb4e35 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java @@ -160,4 +160,14 @@ public class ConcreteRelation extends Symbol implements SCLRelation { Expression[] expressions, Expression[] typeConstraintEvidenceParameters) { throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate."); } + + @Override + public Type getEnforceEffect() { + return writingEffect; + } + + @Override + public Type getQueryEffect() { + return sections.get(0).effect; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java index 3fbeef755..0e0016df9 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java @@ -109,4 +109,14 @@ public class LocalRelation extends AbstractRelation { public String toString() { return name; } + + @Override + public Type getEnforceEffect() { + return Types.PROC; + } + + @Override + public Type getQueryEffect() { + return Types.PROC; + } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java index e93ff6e8f..58d69f4d9 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java @@ -63,4 +63,6 @@ public interface SCLRelation { long location, Expression[] parameters, Expression[] typeConstraintEvidenceParameters); + Type getEnforceEffect(); + Type getQueryEffect(); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java index 42eb9530d..03e3a7f27 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java @@ -8,7 +8,6 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.let import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple; import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var; -import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.common.names.Names; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EVariable; @@ -140,4 +139,14 @@ public class TransitiveClosureRelation extends AbstractRelation implements Compo return new SCLRelation[] { baseRelation }; } + @Override + public Type getEnforceEffect() { + return baseRelation.getEnforceEffect(); + } + + @Override + public Type getQueryEffect() { + return baseRelation.getQueryEffect(); + } + } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java index 3be214d2d..2ce0ced5b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java @@ -241,6 +241,8 @@ public class Environments { Namespace childNamespace = namespace.getNamespace(prefix.substring(0, p)); if(childNamespace != null) findValuesForPrefix(childNamespace, prefix.substring(p+1), proc); + else + namespace.findValuesForPrefix(prefix, AcceptAllNamespaceFilter.INSTANCE, proc); } else namespace.findValuesForPrefix(prefix, AcceptAllNamespaceFilter.INSTANCE, proc); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java index 62d5d8c3d..0e61a1644 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java @@ -16,7 +16,7 @@ public class ErrorLog { public void log(CompilationError error) { errors.add(error); - if(error.severity == ErrorSeverity.ERROR) + if(error.severity != ErrorSeverity.WARNING) ++errorCount; } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorSeverity.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorSeverity.java index 9f65cb3e8..101e0f9e5 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorSeverity.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorSeverity.java @@ -1,6 +1,7 @@ package org.simantics.scl.compiler.errors; public enum ErrorSeverity { - ERROR, - WARNING + ERROR, + IMPORT_ERROR, + WARNING } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java index 9ff56eda4..341ba34a7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java @@ -46,8 +46,8 @@ public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstant for(CHRConstraint constraint : ruleset.constraints) if(constraint.nextContainerFieldName != null) storeClassBuilder.addField(Opcodes.ACC_PUBLIC, constraint.nextContainerFieldName, CHRPriorityFactContainer); - if(ruleset.extensible) - storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE); + //if(ruleset.extensible) + // storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE); // Constructors @@ -106,13 +106,16 @@ public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstant } // update context id + mb.loadLocal(importedStore); mb.loadLocal(contextVar); + mb.invokeVirtual("org/simantics/scl/runtime/chr/CHRRuntimeRuleset", "register", TypeDesc.VOID, new TypeDesc[] {CHRContext}); + /*mb.loadLocal(contextVar); mb.loadLocal(contextVar); mb.loadField(CHRContext_name, "currentId", FACT_ID_TYPE); mb.loadLocal(importedStore); mb.loadField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE); mb.invokeStatic("java/lang/Math", "max", FACT_ID_TYPE, new TypeDesc[] {FACT_ID_TYPE, FACT_ID_TYPE}); - mb.storeField(CHRContext_name, "currentId", FACT_ID_TYPE); + mb.storeField(CHRContext_name, "currentId", FACT_ID_TYPE);*/ mb.returnVoid(); mb.finish(); @@ -137,8 +140,11 @@ public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstant // store context id mb.loadLocal(importedStore); mb.loadLocal(contextVar); + mb.invokeVirtual("org/simantics/scl/runtime/chr/CHRRuntimeRuleset", "unregister", TypeDesc.VOID, new TypeDesc[] {CHRContext}); + /*mb.loadLocal(importedStore); + mb.loadLocal(contextVar); mb.loadField(CHRContext_name, "currentId", FACT_ID_TYPE); - mb.storeField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE); + mb.storeField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE);*/ mb.returnVoid(); mb.finish(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java index d9d79737f..210e3ded3 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java @@ -356,6 +356,8 @@ public class LetApply extends LetStatement implements ValRefBinder { SSABlock headBlock = getParent(); SSAFunction thisFunction = headBlock.getParent(); + if(thisFunction == function) + return; /*System.out.println("--- INLINING -------------------------------"); System.out.println(thisFunction); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilder.java index 56b5c8e67..52d19cc54 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilder.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilder.java @@ -4,6 +4,7 @@ import org.cojen.classfile.TypeDesc; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.constants.LocalVariableConstant; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.continuations.ContRef; import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont; @@ -231,6 +232,9 @@ public class MethodBuilder extends MethodBuilderBase { if(!boundVar.generateOnFly) return getLocalVariable(boundVar); } + else if(val instanceof LocalVariableConstant) { + return ((LocalVariableConstant)val).var; + } push(val, type); LocalVariable temp = createLocalVariable(null, getJavaTypeTranslator().toTypeDesc(type)); storeLocal(temp); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java index 12bf42e5b..62b2ec1aa 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java @@ -17,6 +17,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.EViewPattern; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup; +import org.simantics.scl.compiler.elaboration.java.DynamicConstructor; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.elaboration.modules.TypeConstructor; import org.simantics.scl.compiler.internal.codegen.continuations.Branch; @@ -94,7 +95,7 @@ public class PatternMatchingCompiler { if(constructor_ instanceof EConstant) { SCLValue constructor = ((EConstant)constructor_).getValue(); - ExpressionMatrix matrix = matrixMap.get(constructor.getName()); + ExpressionMatrix matrix = constructor.getValue() == DynamicConstructor.INSTANCE ? null : matrixMap.get(constructor.getName()); if(matrix == null) { CodeWriter newW = w.createBlock(Types.getTypes(parameters)); branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation())); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java index 8ca51b275..24a3bfb2e 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java @@ -16,6 +16,7 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EVariable; import org.simantics.scl.compiler.elaboration.expressions.EViewPattern; import org.simantics.scl.compiler.elaboration.expressions.Expression; +import org.simantics.scl.compiler.elaboration.java.DynamicConstructor; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.elaboration.modules.TypeConstructor; import org.simantics.scl.compiler.internal.codegen.continuations.Branch; @@ -93,7 +94,7 @@ public class PatternMatchingCompiler2 { if(constructor_ instanceof EConstant) { SCLValue constructor = ((EConstant)constructor_).getValue(); - ExpressionMatrix matrix = matrixMap.get(constructor.getName()); + ExpressionMatrix matrix = constructor.getValue() == DynamicConstructor.INSTANCE ? null : matrixMap.get(constructor.getName()); if(matrix == null) { CodeWriter newW = w.createBlock(Types.getTypes(parameters)); branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation())); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java index 6f3ff3be9..eed6d8555 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java @@ -46,7 +46,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EWhen; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression; import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup; -import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionTransformer; import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement; import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement; import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement; @@ -57,6 +56,7 @@ import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard; import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier; import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq; import org.simantics.scl.compiler.elaboration.expressions.list.ListThen; +import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionTransformer; import org.simantics.scl.compiler.elaboration.query.QAlternative; import org.simantics.scl.compiler.elaboration.query.QAtom; import org.simantics.scl.compiler.elaboration.query.QConjunction; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java index 6060315c4..50958221c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java @@ -184,7 +184,7 @@ public class TransformationBuilder { } }; for(QMapping mapping : decomposed.targetMappings) - mapping.parameters[0].forVariables(check); + mapping.parameters[0].forVariableUses(check); sourceVariables = sourceVariableList.toArray(new Variable[sourceVariableList.size()]); } @@ -220,7 +220,7 @@ public class TransformationBuilder { } else { PatternAnalyzer analyzer = new PatternAnalyzer(variableSet, mappedVariableUseCount); - expression.forVariables(analyzer); + expression.forVariableUses(analyzer); if(analyzer.containsVariables) semiopenMappings.add(mapping); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java index 75b083f0c..06da23562 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java @@ -186,7 +186,7 @@ public class UnifiableFactory { // Default action final THashSet dependences = new THashSet(); - expression.forVariables(new VariableProcedure() { + expression.forVariableUses(new VariableProcedure() { @Override public void execute(long location, Variable variable) { diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/utils/ExpressionDecorator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/utils/ExpressionDecorator.java deleted file mode 100644 index 77e47d10a..000000000 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/utils/ExpressionDecorator.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.simantics.scl.compiler.internal.elaboration.utils; - -import org.simantics.scl.compiler.elaboration.expressions.Expression; - -public interface ExpressionDecorator { - - Expression decorate(Expression expression); - boolean decorateSubstructure(Expression expression); - -} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar index f7ea1b263..b7bb1924c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar @@ -138,7 +138,7 @@ lexp shift ESCAPED_SYMBOL, shift CHAR, shift LBRACE, shift WHEN, shift ATTACHED_HASH, shift SELECT, shift SELECT_FIRST, shift SELECT_DISTINCT, - shift TRANSFORMATION, shift EQ + shift TRANSFORMATION, shift EQ, shift CHR_SELECT ; faexp @@ -161,6 +161,8 @@ aexp | (DO | MDO) statements # Do | (SELECT | SELECT_FIRST | SELECT_DISTINCT) exp WHERE queryBlock # Select + | CHR_SELECT + exp WHERE verboseChrQuery # CHRSelect | ENFORCE queryBlock # Enforce //| WHEN queryBlock SEMICOLON exp # When | var # Var @@ -204,12 +206,19 @@ statement | INCLUDE ID aexp # LocalInclude ; +verboseChrQuery + = LBRACE chrQuery (SEMICOLON chrQuery)* RBRACE # VerboseCHRConjunction + ; + + chrQuery - = listQualifier (COMMA listQualifier)* # CHRQuery + = chrQueryPart (COMMA chrQueryPart)* # CHRConjunction ; -verboseChrQuery - = LBRACE listQualifier (SEMICOLON listQualifier)* RBRACE # VerboseCHRQuery +chrQueryPart + = exp # CHRAtom + | exp EQUALS exp # CHREquals + | exp BINDS exp # CHRBinds ; listQualifier diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.flex b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.flex index 0f45c2511..1277ffe7b 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.flex +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.flex @@ -100,7 +100,7 @@ char_literal = "'" ([^'\\\ufffd] | "\\" [^\ufffd]) "'" transformation { return sym(supportCHR() ? SCLTerminals.ID : SCLTerminals.TRANSFORMATION); } select{whitespace}first { return sym(SCLTerminals.SELECT_FIRST); } select{whitespace}distinct { return sym(SCLTerminals.SELECT_DISTINCT); } - select { return sym(SCLTerminals.SELECT); } + select { return sym(supportCHR() ? SCLTerminals.CHR_SELECT : SCLTerminals.SELECT); } enforce { return sym(SCLTerminals.ENFORCE); } do { return sym(SCLTerminals.DO); } eq { return sym(options.supportEq ? SCLTerminals.EQ : SCLTerminals.ID); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java index 5944d12e1..e3efc28dd 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java @@ -1276,7 +1276,7 @@ public class SCLLexer { } case 175: break; case 81: - { return sym(SCLTerminals.SELECT); + { return sym(supportCHR() ? SCLTerminals.CHR_SELECT : SCLTerminals.SELECT); } case 176: break; case 82: diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat index 378013be5..3d4d50962 100644 Binary files a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat and b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat differ diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java index fc2242dce..3e857b7f1 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java @@ -13,18 +13,18 @@ public abstract class SCLParser { public static final boolean TRACE = false; private static final int INITIAL_CAPACITY = 16; - private static final int STATE_COUNT = 358; - private static final int TERMINAL_COUNT = 84; + private static final int STATE_COUNT = 362; + private static final int TERMINAL_COUNT = 85; private static final int NONTERMINAL_COUNT = 52; - private static final int PRODUCT_COUNT = 135; + private static final int PRODUCT_COUNT = 138; private static final int[] ACTION_ROW_ID = new int[STATE_COUNT]; private static final int[] ACTION_COLUMN_ID = new int[TERMINAL_COUNT]; - private static final short[] ACTION_TABLE = new short[6944]; - private static final int[] ERROR_TABLE = new int[940]; + private static final short[] ACTION_TABLE = new short[6832]; + private static final int[] ERROR_TABLE = new int[962]; private static final int[] GOTO_ROW_ID = new int[STATE_COUNT]; private static final int[] GOTO_COLUMN_ID = new int[NONTERMINAL_COUNT]; - private static final short[] GOTO_TABLE = new short[1708]; + private static final short[] GOTO_TABLE = new short[1953]; private static final int[] PRODUCT_LHS = new int[PRODUCT_COUNT]; private static final short STATE_MASK = (short)0x0fff; @@ -99,6 +99,7 @@ public abstract class SCLParser { "SELECT_DISTINCT", "TRANSFORMATION", "EQ", + "CHR_SELECT", "ATTACHED_DOT", "IN", "THEN", @@ -156,12 +157,12 @@ public abstract class SCLParser { "accessor", "case", "queryBlock", + "verboseChrQuery", "stringLiteral", "symbolWithoutMinus", "listQualifier", "chrQuery", - "verboseChrQuery", - "constraintSpec", + "chrQueryPart", "caseRhs", "guardedExpArrow", "equation", @@ -395,19 +396,19 @@ public abstract class SCLParser { return parse(0); } public Object parseCommands() { - return parse(342); + return parse(346); } public Object parseImport() { - return parse(350); + return parse(354); } public Object parseType() { - return parse(352); + return parse(356); } public Object parseExp() { - return parse(354); + return parse(358); } public Object parseEquationBlock() { - return parse(356); + return parse(360); } @@ -535,142 +536,148 @@ public abstract class SCLParser { case 59: return reduceSelect(); case 60: - return reduceEnforce(); + return reduceCHRSelect(); case 61: - return reduceVar(); + return reduceEnforce(); case 62: - return reduceHashedId(); + return reduceVar(); case 63: - return reduceBlank(); + return reduceHashedId(); case 64: - return reduceInteger(); + return reduceBlank(); case 65: - return reduceFloat(); + return reduceInteger(); case 66: - return reduceString(); + return reduceFloat(); case 67: - return reduceChar(); + return reduceString(); case 68: - return reduceTuple(); + return reduceChar(); case 69: - return reduceViewPattern(); + return reduceTuple(); case 70: - return reduceRightSection(); + return reduceViewPattern(); case 71: - return reduceLeftSection(); + return reduceRightSection(); case 72: - return reduceListLiteral(); + return reduceLeftSection(); case 73: - return reduceRange(); + return reduceListLiteral(); case 74: - return reduceListComprehension(); + return reduceRange(); case 75: - return reduceAs(); + return reduceListComprehension(); case 76: - return reduceRecord(); + return reduceAs(); case 77: - return reduceTransformation(); + return reduceRecord(); case 78: - return reduceEq(); + return reduceTransformation(); case 79: - return reduceRuleDeclarations(); + return reduceEq(); case 80: - return reduceStatements(); + return reduceRuleDeclarations(); case 81: - return reduceImportShowing(); + return reduceStatements(); case 82: - return reduceImportHiding(); + return reduceImportShowing(); case 83: - return reduceImportValueItem(); + return reduceImportHiding(); case 84: - return reduceFieldDescription(); + return reduceImportValueItem(); case 85: - return reduceGuardedExpEq(); + return reduceFieldDescription(); case 86: - return reduceFundep(); + return reduceGuardedExpEq(); case 87: - return reduceQueryRuleDeclaration(); + return reduceFundep(); case 88: - return reduceAnnotation(); + return reduceQueryRuleDeclaration(); case 89: - return reduceGuardQuery(); + return reduceAnnotation(); case 90: - return reduceEqualsQuery(); + return reduceGuardQuery(); case 91: - return reduceBindQuery(); + return reduceEqualsQuery(); case 92: - return reduceCompositeQuery(); + return reduceBindQuery(); case 93: - return reduceApply(); + return reduceCompositeQuery(); case 94: - return reduceSymbol(); + return reduceApply(); case 95: - return reduceEscapedId(); + return reduceSymbol(); case 96: - return reduceMinus(); + return reduceEscapedId(); case 97: - return reduceLess(); + return reduceMinus(); case 98: - return reduceGreater(); + return reduceLess(); case 99: - return reduceDot(); + return reduceGreater(); case 100: - return reduceFieldAccess(); + return reduceDot(); case 101: - return reduceIdAccessor(); + return reduceFieldAccess(); case 102: - return reduceStringAccessor(); + return reduceIdAccessor(); case 103: - return reduceExpAccessor(); + return reduceStringAccessor(); case 104: - return reduceCase(); + return reduceExpAccessor(); case 105: - return reduceQueryBlock(); + return reduceCase(); case 106: - return reduceStringLiteral(); + return reduceQueryBlock(); case 107: - return reduceSymbol(); + return reduceVerboseCHRConjunction(); case 108: - return reduceEscapedId(); + return reduceStringLiteral(); case 109: - return reduceLess(); + return reduceSymbol(); case 110: - return reduceGreater(); + return reduceEscapedId(); case 111: - return reduceDot(); + return reduceLess(); case 112: - return reduceGuardQualifier(); + return reduceGreater(); case 113: - return reduceLetQualifier(); + return reduceDot(); case 114: - return reduceBindQualifier(); + return reduceGuardQualifier(); case 115: - return reduceThenQualifier(); + return reduceLetQualifier(); case 116: - return reduceCHRQuery(); + return reduceBindQualifier(); case 117: - return reduceVerboseCHRQuery(); + return reduceThenQualifier(); case 118: - return reduceConstraintSpec(); + return reduceCHRConjunction(); case 119: - return reduceSimpleCaseRhs(); + return reduceCHRAtom(); case 120: - return reduceGuardedCaseRhs(); + return reduceCHREquals(); case 121: - return reduceGuardedExpArrow(); + return reduceCHRBinds(); case 122: - return reduceGuardEquation(); + return reduceSimpleCaseRhs(); case 123: - return reduceBasicEquation(); + return reduceGuardedCaseRhs(); case 124: - return reduceEffect(); + return reduceGuardedExpArrow(); case 125: - return reduceJustEtype(); + return reduceGuardEquation(); case 126: - return reduceForAll(); + return reduceBasicEquation(); case 127: - return reduceApplyType(); + return reduceEffect(); case 128: + return reduceJustEtype(); + case 129: + return reduceForAll(); + case 130: + return reduceApplyType(); + case 131: return reduceDummy(); default: @@ -824,7 +831,7 @@ public abstract class SCLParser { */ protected abstract Object reduceVerboseCHRStatement(); /** - * statement ::= CONSTRAINT constructor (WHERE constraintSpec)? + * statement ::= CONSTRAINT constructor */ protected abstract Object reduceConstraintStatement(); /** @@ -931,6 +938,10 @@ public abstract class SCLParser { * aexp ::= (SELECT | SELECT_FIRST | SELECT_DISTINCT) exp WHERE queryBlock */ protected abstract Object reduceSelect(); + /** + * aexp ::= CHR_SELECT exp WHERE verboseChrQuery + */ + protected abstract Object reduceCHRSelect(); /** * aexp ::= ENFORCE queryBlock */ @@ -1111,6 +1122,10 @@ public abstract class SCLParser { * queryBlock ::= LBRACE (query (SEMICOLON (query SEMICOLON)* query)?)? RBRACE */ protected abstract Object reduceQueryBlock(); + /** + * verboseChrQuery ::= LBRACE chrQuery (SEMICOLON chrQuery)* RBRACE + */ + protected abstract Object reduceVerboseCHRConjunction(); /** * stringLiteral ::= BEGIN_STRING (SUSPEND_STRING exp CONTINUE_STRING)* END_STRING */ @@ -1132,17 +1147,21 @@ public abstract class SCLParser { */ protected abstract Object reduceThenQualifier(); /** - * chrQuery ::= (listQualifier COMMA)* listQualifier + * chrQuery ::= (chrQueryPart COMMA)* chrQueryPart + */ + protected abstract Object reduceCHRConjunction(); + /** + * chrQueryPart ::= exp */ - protected abstract Object reduceCHRQuery(); + protected abstract Object reduceCHRAtom(); /** - * verboseChrQuery ::= LBRACE listQualifier (SEMICOLON listQualifier)* RBRACE + * chrQueryPart ::= exp EQUALS exp */ - protected abstract Object reduceVerboseCHRQuery(); + protected abstract Object reduceCHREquals(); /** - * constraintSpec ::= LBRACE exp (SEMICOLON exp)* RBRACE + * chrQueryPart ::= exp BINDS exp */ - protected abstract Object reduceConstraintSpec(); + protected abstract Object reduceCHRBinds(); /** * caseRhs ::= ARROW exp (WHERE statements)? */ diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java index 34f8d6a9f..bda298bd6 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java @@ -11,6 +11,11 @@ import org.simantics.scl.compiler.common.precedence.Precedence; import org.simantics.scl.compiler.compilation.CompilationContext; import org.simantics.scl.compiler.constants.CharacterConstant; import org.simantics.scl.compiler.constants.StringConstant; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals; +import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery; import org.simantics.scl.compiler.elaboration.equation.EqBasic; import org.simantics.scl.compiler.elaboration.equation.EqGuard; import org.simantics.scl.compiler.elaboration.equation.Equation; @@ -31,6 +36,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EListComprehension; import org.simantics.scl.compiler.elaboration.expressions.EListLiteral; import org.simantics.scl.compiler.elaboration.expressions.ELiteral; import org.simantics.scl.compiler.elaboration.expressions.EMatch; +import org.simantics.scl.compiler.elaboration.expressions.EPreCHRSelect; import org.simantics.scl.compiler.elaboration.expressions.ERange; import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral; import org.simantics.scl.compiler.elaboration.expressions.ERecord; @@ -1246,25 +1252,12 @@ public class SCLParserImpl extends SCLParser { return new EViewPattern((Expression)get(1), (Expression)get(3)); } - @Override - protected Object reduceCHRStatement() { - return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2)); - } - @Override protected Object reduceConstraintStatement() { ConstructorAst constructor = (ConstructorAst)get(1); return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations); } - @Override - protected Object reduceCHRQuery() { - ListQualifier[] query = new ListQualifier[(length()+1)/2]; - for(int i=0;i\n"); } addContentsTree(b, result); - result.toHtml(b); + result.toHtml(HtmlGenerationContext.DEFAULT, b); if(navigation != null) b.append("\n"); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlGenerationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlGenerationContext.java new file mode 100644 index 000000000..2de5a7066 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlGenerationContext.java @@ -0,0 +1,12 @@ +package org.simantics.scl.compiler.markdown.html; + +public class HtmlGenerationContext { + public final boolean generateAnchors; + + public HtmlGenerationContext(boolean generateAnchors) { + this.generateAnchors = generateAnchors; + } + + public static final HtmlGenerationContext DEFAULT = new HtmlGenerationContext(true); + public static final HtmlGenerationContext TEST_DEFAULT = new HtmlGenerationContext(false); +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java index eb4626f66..f49e4781c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java @@ -218,7 +218,7 @@ public class MarkdownParser { else if((c == '=' || c == '-') && container instanceof ParagraphNode && Scanner.isSetextHeaderLine(line, firstNonspace, c) - && container.stringContent.indexOf("\n") == -1 + /*&& container.stringContent.indexOf("\n") == -1*/ ) { HeaderNode header = new HeaderNode(c == '=' ? 1 : 2, true); header.lineNumber = container.lineNumber; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/AutolinkNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/AutolinkNode.java index 34323b402..f7b854007 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/AutolinkNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/AutolinkNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.HtmlEscape; public class AutolinkNode extends Node { @@ -11,7 +12,7 @@ public class AutolinkNode extends Node { } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append("\n"); - super.toHtml(b); + super.toHtml(context, b); b.append("\n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeBlockNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeBlockNode.java index 797a21bf0..fed7a73a8 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeBlockNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeBlockNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.HtmlEscape; public class CodeBlockNode extends Node { @@ -30,7 +31,7 @@ public class CodeBlockNode extends Node { } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { if(infoString == null || infoString.isEmpty()) b.append("
");
         else {
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeNode.java
index 673a3e82d..8a421d293 100644
--- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeNode.java
+++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeNode.java
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class CodeNode extends Node {
@@ -8,7 +9,7 @@ public class CodeNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("");
         b.append(HtmlEscape.escape(stringContent));
         b.append("");
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/EmphNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/EmphNode.java
index 82d7d2eb4..b438ab4e0 100644
--- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/EmphNode.java
+++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/EmphNode.java
@@ -1,5 +1,7 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class EmphNode extends Node {
     boolean strong;
     
@@ -8,12 +10,12 @@ public class EmphNode extends Node {
     }
 
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         if(strong)
             b.append("");
         else
             b.append("");
-        super.toHtml(b);
+        super.toHtml(context, b);
         if(strong)
             b.append("");
         else
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ExtensionBlockNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ExtensionBlockNode.java
index 62d95e1a3..525a4187c 100644
--- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ExtensionBlockNode.java
+++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ExtensionBlockNode.java
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.ExtensionNodeHandler;
 
 public class ExtensionBlockNode extends Node {
@@ -37,7 +38,7 @@ public class ExtensionBlockNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("::").append(extension).append('[').append(content).append(']');
     }
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HardLineBreakNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HardLineBreakNode.java
index 71933f0eb..816d595fb 100644
--- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HardLineBreakNode.java
+++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HardLineBreakNode.java
@@ -1,8 +1,10 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class HardLineBreakNode extends Node {
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("
\n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HeaderNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HeaderNode.java index 05de801ad..39a2b47f7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HeaderNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HeaderNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; public class HeaderNode extends Node { public int level; @@ -16,11 +17,16 @@ public class HeaderNode extends Node { } @Override - public void toHtml(StringBuilder b) { - b.append(""); - super.toHtml(b); + public void toHtml(HtmlGenerationContext context, StringBuilder b) { + b.append(""); + } + else + b.append('>'); + super.toHtml(context, b); b.append("\n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HorizontalRuleNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HorizontalRuleNode.java index 5416cb0c3..22b393cc2 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HorizontalRuleNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HorizontalRuleNode.java @@ -1,8 +1,10 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; + public class HorizontalRuleNode extends Node { @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append("
\n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlNode.java index fc0752b64..897c962d0 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlNode.java @@ -1,5 +1,7 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; + public class HtmlNode extends Node { public HtmlNode() { } @@ -12,7 +14,7 @@ public class HtmlNode extends Node { } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append(stringContent); b.append('\n'); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlTagNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlTagNode.java index 25122bc73..9ef771ab9 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlTagNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlTagNode.java @@ -1,11 +1,13 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; + public class HtmlTagNode extends Node { public HtmlTagNode(StringBuilder stringContent) { this.stringContent = stringContent; } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append(stringContent); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ImageNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ImageNode.java index ebe5d5654..e238c4351 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ImageNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ImageNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.HtmlEscape; public class ImageNode extends Node { @@ -14,7 +15,7 @@ public class ImageNode extends Node { } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append("\"");\n"); return; @@ -29,7 +30,7 @@ public class ItemNode extends Node { for(Node child = firstChild; child != null; child = child.next) { if(child instanceof ParagraphNode) { for(Node n=child.firstChild;n!=null;n=n.next) - n.toHtml(b); + n.toHtml(context, b); noNewline = true; } else { @@ -37,14 +38,14 @@ public class ItemNode extends Node { b.append('\n'); noNewline = false; } - child.toHtml(b); + child.toHtml(context, b); } } b.append("\n"); } else { b.append("
  • \n"); - super.toHtml(b); + super.toHtml(context, b); b.append("
  • \n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/LinkNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/LinkNode.java index 829dd4233..bde60f2b7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/LinkNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/LinkNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.HtmlEscape; public class LinkNode extends Node { @@ -14,7 +15,7 @@ public class LinkNode extends Node { } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append("
    "); @@ -23,7 +24,7 @@ public class LinkNode extends Node { b.append(HtmlEscape.escape(title)); b.append("\">"); } - super.toHtml(b); + super.toHtml(context, b); b.append(""); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ListNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ListNode.java index 1bf339738..82e123f26 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ListNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ListNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; public class ListNode extends Node { public char bulletChar; @@ -25,11 +26,11 @@ public class ListNode extends Node { } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { if(bulletChar == '+' || bulletChar == '-' || bulletChar == '*') { b.append("
      \n"); for(Node child = firstChild; child != null; child = child.next) - ((ItemNode)child).toHtml(b, tight); + ((ItemNode)child).toHtml(context, b, tight); b.append("
    \n"); } else { @@ -38,7 +39,7 @@ public class ListNode extends Node { else b.append("
      \n"); for(Node child = firstChild; child != null; child = child.next) - ((ItemNode)child).toHtml(b, tight); + ((ItemNode)child).toHtml(context, b, tight); b.append("
    \n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/Node.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/Node.java index 7c91ceaa0..9e576beed 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/Node.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/Node.java @@ -3,6 +3,7 @@ package org.simantics.scl.compiler.markdown.nodes; import java.util.ArrayList; import java.util.List; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.ExtensionNodeHandler; import org.simantics.scl.compiler.markdown.internal.MarkdownParser; @@ -33,9 +34,9 @@ public abstract class Node { return false; } - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { for(Node child = firstChild; child != null; child = child.next) - child.toHtml(b); + child.toHtml(context, b); } public List extractHeaders() { @@ -46,9 +47,9 @@ public abstract class Node { return result; } - public String toHtml() { + public String toHtml(HtmlGenerationContext context) { StringBuilder b = new StringBuilder(); - toHtml(b); + toHtml(context, b); int len = b.length(); if(len > 0 && b.charAt(len-1) == '\n') b.delete(len-1, len); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ParagraphNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ParagraphNode.java index 8e37c1e5c..3b3611ac7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ParagraphNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ParagraphNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; public class ParagraphNode extends Node { @Override @@ -7,9 +8,9 @@ public class ParagraphNode extends Node { return true; } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append("

    "); - super.toHtml(b); + super.toHtml(context, b); b.append("

    \n"); } } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/TextNode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/TextNode.java index 710b3ce51..8922a1e52 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/TextNode.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/TextNode.java @@ -1,5 +1,6 @@ package org.simantics.scl.compiler.markdown.nodes; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.HtmlEscape; public class TextNode extends Node { @@ -7,7 +8,7 @@ public class TextNode extends Node { this.stringContent = text; } @Override - public void toHtml(StringBuilder b) { + public void toHtml(HtmlGenerationContext context, StringBuilder b) { b.append(HtmlEscape.escape(stringContent)); } @Override diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/generator/table/ParseTableBuilder.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/generator/table/ParseTableBuilder.java index da837fb60..fdb01e58d 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/generator/table/ParseTableBuilder.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/generator/table/ParseTableBuilder.java @@ -126,7 +126,7 @@ public class ParseTableBuilder { } } stackOpMap.put(a, stackOp); - System.out.println(newState + " " + grammar.getName(a) + " " + stackOp); + //System.out.println(newState + " " + grammar.getName(a) + " " + stackOp); if(stackOverflow) { System.err.println("Stack overflow when following " + grammar.getName(a) + " at"); @@ -396,7 +396,7 @@ public class ParseTableBuilder { //builder.visualize(); - builder.printParseTable(); + //builder.printParseTable(); return builder.getParseTable(); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/grammar/input/GrammarParser.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/grammar/input/GrammarParser.java index d8526ca12..ed0968b36 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/grammar/input/GrammarParser.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/grammar/input/GrammarParser.java @@ -7,7 +7,7 @@ import java.util.Arrays; import java.util.Collections; public abstract class GrammarParser { - public static final boolean TRACE = true; + public static final boolean TRACE = false; private static final int INITIAL_CAPACITY = 16; private static final int STATE_COUNT = 19; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java index 939010d40..61a1d2c95 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java @@ -1,9 +1,11 @@ package org.simantics.scl.compiler.source.repository; +import java.util.ArrayList; import java.util.Collection; import org.simantics.scl.compiler.module.Module; import org.simantics.scl.compiler.module.repository.UpdateListener; +import org.simantics.scl.compiler.module.repository.UpdateListener.Observable; import org.simantics.scl.compiler.source.ModuleSource; import org.simantics.scl.compiler.source.PrecompiledModuleSource; @@ -21,6 +23,8 @@ public class MapModuleSourceRepository implements ModuleSourceRepository { THashMap modules = new THashMap(); THashMap documentations = new THashMap(); + THashMap> listeners = new THashMap>(); + public MapModuleSourceRepository() { } @@ -36,6 +40,12 @@ public class MapModuleSourceRepository implements ModuleSourceRepository { public void addModuleDescriptor(ModuleSource descriptor) { modules.put(descriptor.getModuleName(), descriptor); + synchronized (listeners) { + ArrayList list = listeners.get(descriptor.getModuleName()); + if(list != null) + for(UpdateListener listener : list.toArray(new UpdateListener[list.size()])) + listener.notifyAboutUpdate(); + } } public void addModule(Module module) { @@ -49,6 +59,29 @@ public class MapModuleSourceRepository implements ModuleSourceRepository { @Override public ModuleSource getModuleSource(String moduleName, UpdateListener listener) { + if(listener != null) { + synchronized(listeners) { + ArrayList list = listeners.get(moduleName); + if(list == null) { + list = new ArrayList(2); + listeners.put(moduleName, list); + } + list.add(listener); + } + listener.addObservable(new Observable() { + @Override + public void removeListener(UpdateListener listener) { + synchronized(listeners) { + ArrayList list = listeners.get(moduleName); + if(list != null) { + list.remove(listener); + if(list.isEmpty()) + listeners.remove(moduleName); + } + } + } + }); + } return modules.get(moduleName); } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java index 67f43838d..899ee0418 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java @@ -42,7 +42,6 @@ import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.codegen.writer.ExternalConstant; import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter; import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.internal.interpreted.IExpression; import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; import org.simantics.scl.compiler.internal.parsing.parser.SCLBlockParser; @@ -300,9 +299,9 @@ public class ExpressionEvaluator { if(!errorLog.hasNoErrors()) throw new SCLExpressionCompilationException(errorLog.getErrors()); if(decorateExpression && Types.canonical(expectedEffect) != Types.NO_EFFECTS) { - ExpressionDecorator decorator = + ToplevelEffectDecorator decorator = new ToplevelEffectDecorator(errorLog, environment); - expression = expression.decorate(decorator); + expression = expression.accept(decorator); } expression = context.solveConstraints(environment, expression); expressionType = expression.getType(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ToplevelEffectDecorator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ToplevelEffectDecorator.java index 5a3c39e60..491d88e41 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ToplevelEffectDecorator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ToplevelEffectDecorator.java @@ -4,7 +4,9 @@ import java.util.ArrayList; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.common.names.Names; +import org.simantics.scl.compiler.elaboration.expressions.Case; import org.simantics.scl.compiler.elaboration.expressions.EApply; +import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset; import org.simantics.scl.compiler.elaboration.expressions.EConstant; import org.simantics.scl.compiler.elaboration.expressions.EEnforce; import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess; @@ -15,16 +17,18 @@ import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda; import org.simantics.scl.compiler.elaboration.expressions.EWhen; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.expressions.Variable; +import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionTransformer; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; -public class ToplevelEffectDecorator implements ExpressionDecorator { +import gnu.trove.map.hash.THashMap; + +public class ToplevelEffectDecorator extends StandardExpressionTransformer { ErrorLog errorLog; Environment environment; @@ -34,92 +38,101 @@ public class ToplevelEffectDecorator implements ExpressionDecorator { this.environment = environment; } - private static Expression decorate(SCLValue transactionFunction, Type effect, Expression expression) { - Variable var = new Variable("_"); - var.setType(Types.UNIT); - Expression trans = new EApply(expression.getLocation(), Types.PROC, - new EConstant(transactionFunction, - expression.getType()), - new ESimpleLambda(Locations.NO_LOCATION, var, effect, expression) - ); - if(expression instanceof EApply) { - EApply apply = (EApply)expression; - trans = apply.toANormalForm(trans); - } - return trans; + @Override + public Expression transform(EEnforce expression) { + return decorateByEffect(expression, expression.getEffect()); + } + + @Override + public Expression transform(EWhen expression) { + return decorateByEffect(expression, expression.getEffect()); + } + + @Override + public Expression transform(ERuleset expression) { + return decorateByEffect(expression, expression.getEffect()); + } + + @Override + public Expression transform(ECHRRuleset expression) { + return decorateByEffect(expression, expression.getEffect()); + } + + @Override + public Expression transform(EFieldAccess expression) { + // Can we encounter EFieldAccess in this transformer? + return decorateByEffect(expression, expression.getEffect()); + } + + @Override + public Expression transform(ESelect expression) { + return decorateByEffect(expression, expression.getEffect()); } - private static final TCon R = Types.con("R/R", "R"); + @Override + public Expression transform(EApply expression) { + return decorateByEffect(super.transform(expression), expression.getLocalEffect()); + } @Override - public Expression decorate(Expression expression) { - if(expression instanceof EApply) - return decorateByEffect(expression, ((EApply)expression).getLocalEffect()); - else if(expression instanceof ESelect - || expression instanceof EEnforce - || expression instanceof EWhen - || expression instanceof EFieldAccess - || expression instanceof ERuleset) - return decorateByEffect(expression, expression.getEffect()); + public Expression transform(ESimpleLambda expression) { + // Never has side effects return expression; } + @Override + public Expression transform(ELambda expression) { + // Never has side effects + return expression; + } + + @Override + protected void transformCases(Case[] cases) { + for(Case case_ : cases) + case_.value = case_.value.accept(this); + } + + private static final THashMap DECORATION_MAP = new THashMap(); + + static { + DECORATION_MAP.put(Types.WRITE_GRAPH, Names.Simantics_DB_syncWrite); + DECORATION_MAP.put(Types.READ_GRAPH, Names.Simantics_DB_syncRead); + DECORATION_MAP.put(Types.con("R/R", "R"), Names.R_R_runR); + DECORATION_MAP.put(Types.RANDOM, Names.Random_runRandom); + } + private Expression decorateByEffect(Expression expression, Type effect) { if(effect == Types.NO_EFFECTS) return expression; - //System.out.println("decorateByEffect(" + expression + ", " + effect + ")"); - ArrayList concreteEffects = new ArrayList(); effect.collectConcreteEffects(concreteEffects); - if(concreteEffects.contains(Types.WRITE_GRAPH)) { - Name name = Names.Simantics_DB_syncWrite; - SCLValue transactionFunction = environment.getValue(name); + for(TCon ce : concreteEffects) { + Name transactionFunctionName = DECORATION_MAP.get(ce); + if(transactionFunctionName == null) + continue; + SCLValue transactionFunction = environment.getValue(transactionFunctionName); if(transactionFunction == null) { - errorLog.log(expression.location, "Cannot locate " + name); - return expression; + errorLog.log(expression.location, "Cannot locate " + transactionFunctionName); + continue; } - - expression = decorate(transactionFunction, Types.WRITE_GRAPH, expression); + expression = decorate(transactionFunction, ce, expression); } - else if(concreteEffects.contains(Types.READ_GRAPH)) { - Name name = Names.Simantics_DB_syncRead; - SCLValue transactionFunction = environment.getValue(name); - if(transactionFunction == null) { - errorLog.log(expression.location, "Cannot locate " + name); - return expression; - } - - expression = decorate(transactionFunction, Types.READ_GRAPH, expression); - } - if(concreteEffects.contains(R)) { - Name name = Names.R_R_runR; - SCLValue transactionFunction = environment.getValue(name); - if(transactionFunction == null) { - errorLog.log(expression.location, "Cannot locate " + name); - return expression; - } - - expression = decorate(transactionFunction, R, expression); - } - if(concreteEffects.contains(Types.RANDOM)) { - Name name = Names.Random_runRandom; - SCLValue transactionFunction = environment.getValue(name); - if(transactionFunction == null) { - errorLog.log(expression.location, "Cannot locate " + name); - return expression; - } - expression = decorate(transactionFunction, Types.RANDOM, expression); - } return expression; } - @Override - public boolean decorateSubstructure(Expression expression) { - if(expression instanceof ELambda || expression instanceof ESimpleLambda) - return false; - return true; + private static Expression decorate(SCLValue transactionFunction, Type effect, Expression expression) { + Variable var = new Variable("_"); + var.setType(effect == Types.RANDOM ? Types.PUNIT : Types.UNIT); + Expression trans = new EApply(expression.getLocation(), Types.PROC, + effect == Types.RANDOM ? new EConstant(transactionFunction, Types.PROC, expression.getType()) : new EConstant(transactionFunction, expression.getType()), + new ESimpleLambda(Locations.NO_LOCATION, var, effect, expression) + ); + if(expression instanceof EApply) { + EApply apply = (EApply)expression; + trans = apply.toANormalForm(trans); + } + return trans; } - } diff --git a/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF index 52095a101..61be3240e 100644 --- a/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF @@ -8,5 +8,6 @@ Require-Bundle: org.simantics.scl.runtime;bundle-version="0.4.0", org.simantics.scl.osgi;bundle-version="1.0.4", org.jdom2;bundle-version="2.0.6", org.junit;bundle-version="4.12.0";resolution:=optional, - com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2" + com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2", + com.fasterxml.jackson.core.jackson-databind Bundle-ClassPath: . diff --git a/bundles/org.simantics.scl.data/scl/Data/JsonNode.scl b/bundles/org.simantics.scl.data/scl/Data/JsonNode.scl new file mode 100644 index 000000000..f0e49f438 --- /dev/null +++ b/bundles/org.simantics.scl.data/scl/Data/JsonNode.scl @@ -0,0 +1,23 @@ +import "StandardLibrary" +import "Data/Writer" +import "JavaBuiltin" as Java +import "Data/Json" + +importJava "com.fasterxml.jackson.databind.JsonNode" where + data JsonNode + +importJava "org.simantics.scl.data.xml.JsonNodeHelper" where + @private + @JavaName toJsonString + jsonNodeToString :: JsonNode -> String + @private + @JavaName fromJsonString + stringToJsonNode :: String -> JsonNode + +jsonNodeToJson :: JsonNode -> Json +jsonNodeToJson node = fromJsonString (jsonNodeToString node) + +jsonToJsonNode :: Json -> JsonNode +jsonToJsonNode json = stringToJsonNode (toJsonString json) + + \ No newline at end of file diff --git a/bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JsonNodeHelper.java b/bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JsonNodeHelper.java new file mode 100644 index 000000000..9eda11429 --- /dev/null +++ b/bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JsonNodeHelper.java @@ -0,0 +1,28 @@ +package org.simantics.scl.data.xml; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class JsonNodeHelper { + + private static final ObjectMapper SORTED_MAPPER = new ObjectMapper(); + + static { + SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true); + } + + public static String toJsonString(JsonNode node) throws JsonProcessingException { + final Object obj = SORTED_MAPPER.treeToValue(node, Object.class); + final String json = SORTED_MAPPER.writeValueAsString(obj); + return json; + } + + public static JsonNode fromJsonString(String s) throws JsonProcessingException, IOException { + return SORTED_MAPPER.readTree(s); + } + +} diff --git a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl index df556086e..32019768b 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl @@ -265,6 +265,9 @@ importJava "org.simantics.db.common.utils.ListUtils" where @JavaName create createList :: [Resource] -> Resource + + @JavaName create + createList :: Resource -> [Resource] -> Resource @javaName insertBack insertBack :: Resource -> [Resource] -> () diff --git a/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl b/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl index a8ffd13db..9a6ffde8c 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl @@ -21,6 +21,9 @@ Example: """ variable :: String -> Variable + @JavaName getPossibleVariable + possibleVariable :: String -> Maybe Variable + @JavaName getVariable """ Function **resourceVariable** converts a resource to a corresponding variable. diff --git a/bundles/org.simantics.scl.rest/.classpath b/bundles/org.simantics.scl.rest/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/bundles/org.simantics.scl.rest/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.scl.rest/.gitignore b/bundles/org.simantics.scl.rest/.gitignore new file mode 100644 index 000000000..7fb5d66b1 --- /dev/null +++ b/bundles/org.simantics.scl.rest/.gitignore @@ -0,0 +1 @@ +.settings \ No newline at end of file diff --git a/bundles/org.simantics.scl.rest/.project b/bundles/org.simantics.scl.rest/.project new file mode 100644 index 000000000..ddf0f2c29 --- /dev/null +++ b/bundles/org.simantics.scl.rest/.project @@ -0,0 +1,28 @@ + + + org.simantics.scl.rest + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF new file mode 100644 index 000000000..e92a3cf0c --- /dev/null +++ b/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics SCL REST-Server +Bundle-SymbolicName: org.simantics.scl.rest +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.scl.rest.Activator +Require-Bundle: org.eclipse.core.runtime, + org.glassfish.jersey.core.jersey-server, + javax.ws.rs-api, + org.simantics.scl.compiler, + org.simantics.scl.osgi, + org.eclipse.jetty.servlet, + org.glassfish.jersey.containers.jersey-container-servlet-core, + javax.servlet-api, + org.eclipse.jetty.server, + org.eclipse.jetty.util, + org.eclipse.jetty.io, + com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.8", + com.fasterxml.jackson.core.jackson-annotations;bundle-version="2.8.0", + com.fasterxml.jackson.core.jackson-databind;bundle-version="2.8.8", + org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="2.25.1", + org.glassfish.jersey.media.jersey-media-multipart;bundle-version="2.25.1", + org.slf4j.api, + org.jvnet.mimepull;bundle-version="1.9.6" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy diff --git a/bundles/org.simantics.scl.rest/build.properties b/bundles/org.simantics.scl.rest/build.properties new file mode 100644 index 000000000..a4fd10d42 --- /dev/null +++ b/bundles/org.simantics.scl.rest/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + scl/ diff --git a/bundles/org.simantics.scl.rest/scl/SCL/REST/Server.scl b/bundles/org.simantics.scl.rest/scl/SCL/REST/Server.scl new file mode 100644 index 000000000..8ed1f7e96 --- /dev/null +++ b/bundles/org.simantics.scl.rest/scl/SCL/REST/Server.scl @@ -0,0 +1,3 @@ +importJava "org.simantics.scl.rest.SCLRESTServer" where + start :: String -> Integer -> () + stop :: () diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/Activator.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/Activator.java new file mode 100644 index 000000000..4f90e6900 --- /dev/null +++ b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/Activator.java @@ -0,0 +1,35 @@ +package org.simantics.scl.rest; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + SCLRESTServer.stop(); + Activator.context = null; + } + +} diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/AuthorizationFilter.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/AuthorizationFilter.java new file mode 100644 index 000000000..f307b66dc --- /dev/null +++ b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/AuthorizationFilter.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013, 2016 Association for Decentralized + * Information Management in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the THTH Simantics + * Division Member Component License which accompanies this + * distribution, and is available at + * http://www.simantics.org/legal/sdmcl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.scl.rest; + +import java.io.IOException; + +import javax.ws.rs.NotAuthorizedException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +public class AuthorizationFilter implements ContainerRequestFilter { + + private final String token; + + public AuthorizationFilter(String token) { + this.token = token; + } + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + // Get the HTTP Authorization header from the request + String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); + + // Check if the HTTP Authorization header is present and formatted correctly + if (authorizationHeader == null || !authorizationHeader.startsWith("SCLRESTServer-Bearer ")) { + throw new NotAuthorizedException("Authorization header must be provided"); + } + + // Extract the token from the HTTP Authorization header + String token = authorizationHeader.substring("SCLRESTServer-Bearer".length()).trim(); + try { + // Validate the token + validateToken(token); + } catch (Exception e) { + requestContext.abortWith(Response.status(Status.UNAUTHORIZED).build()); + } + } + + private void validateToken(String token) throws Exception { + if (!this.token.equals(token)) { + throw new Exception("Wrong token!"); + } + } + +} diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLAPI.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLAPI.java new file mode 100644 index 000000000..cb86ff861 --- /dev/null +++ b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLAPI.java @@ -0,0 +1,62 @@ +package org.simantics.scl.rest; + +import java.io.Reader; +import java.io.Writer; +import java.util.concurrent.ConcurrentHashMap; + +import org.simantics.scl.compiler.commands.CommandSessionWithModules; +import org.simantics.scl.osgi.SCLOsgi; + +public class SCLAPI { + + private static SCLAPI INSTANCE; + + private ConcurrentHashMap commandSessions; + + private SCLAPI() { + this.commandSessions = new ConcurrentHashMap<>(); + } + + public static SCLAPI getInstance() { + if (INSTANCE == null) { + synchronized (SCLAPI.class) { + if (INSTANCE == null) { + INSTANCE = new SCLAPI(); + } + } + } + return INSTANCE; + } + + public CommandSessionWithModules getOrCreateCommandSession(String sessionId) { + return commandSessions.computeIfAbsent(sessionId, key -> new CommandSessionWithModules(SCLOsgi.MODULE_REPOSITORY)); + } + + public void execute(String sessionId, Reader reader, Writer writer) { + CommandSessionWithModules session = commandSessions.get(sessionId); + if (session == null) + throw new IllegalArgumentException("CommandSession for sessionId " + sessionId + " does not exist!"); + session.runCommands(reader, writer); + } + + public void deleteCommandSession(String sessionId) { + commandSessions.computeIfPresent(sessionId, (key, session) -> { + // session could be flushed or closed here to release possible resources? + return null; + }); + } + + public Object variableValue(String sessionId, String variableName) { + CommandSessionWithModules session = commandSessions.get(sessionId); + if (session == null) + throw new IllegalArgumentException("CommandSession for sessionId " + sessionId + " does not exist!"); + return session.getCommandSession().getVariableValue(variableName); + } + + public String putModule(String sessionId, String moduleName, String moduleText) { + CommandSessionWithModules session = commandSessions.get(sessionId); + if (session == null) + throw new IllegalArgumentException("CommandSession for sessionId " + sessionId + " does not exist!"); + return session.putModule(moduleName, moduleText); + } +} diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTAPI.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTAPI.java new file mode 100644 index 000000000..4ded2476d --- /dev/null +++ b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTAPI.java @@ -0,0 +1,110 @@ +package org.simantics.scl.rest; + +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; + +@Path("SCLAPI") +@Produces(MediaType.APPLICATION_JSON) +public class SCLRESTAPI { + + private SCLAPI sclAPI; + + public SCLRESTAPI() { + sclAPI = SCLAPI.getInstance(); + } + + private static Map buildJSONResponse(Object... keyValues) { + if ((keyValues.length % 2) != 0) + throw new IllegalArgumentException("Invalid amount of arguments! " + Arrays.toString(keyValues)); + Map results = new HashMap<>(keyValues.length / 2); + for (int i = 0; i < keyValues.length; i += 2) { + Object key = keyValues[i]; + Object value = keyValues[i + 1]; + if (!(key instanceof String)) + throw new IllegalArgumentException("Key with index " + i + " is not String"); + results.put((String) key, value); + } + return results; + } + + @Path("/sessions") + @POST + public Response sessions() { + String sessionId = UUID.randomUUID().toString(); + sclAPI.getOrCreateCommandSession(sessionId); + return Response.ok(buildJSONResponse("sessionId", sessionId)).build(); + } + + @Path("/sessions/{sessionId}/modules/{moduleName:.*}") + @PUT + public Response upload(@PathParam("sessionId") String sessionId, @PathParam("moduleName") String moduleName, @FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException { + String moduleText = getModuleText(inputStream); + String response = sclAPI.putModule(sessionId, moduleName, moduleText); + if (response == null) + return Response.ok().build(); + else + return Response.status(422).entity(buildJSONResponse("response", response)).build(); + } + + private static String getModuleText(InputStream inputStream) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int length; + while ((length = inputStream.read(buffer)) != -1) + result.write(buffer, 0, length); + return result.toString(StandardCharsets.UTF_8.name()); + } + + @Path("/sessions/{sessionId}/execute") + @POST + @Produces(MediaType.TEXT_PLAIN) + public Response execute(@PathParam("sessionId") String sessionId, @FormDataParam("command") String command) { + final Reader reader = new InputStreamReader(new ByteArrayInputStream(command.getBytes(StandardCharsets.UTF_8))); + return Response.ok((StreamingOutput) output -> { + try (Writer writer = new BufferedWriter(new OutputStreamWriter(output))) { + sclAPI.execute(sessionId, reader, writer); + writer.flush(); + } + }).build(); + } + + @Path("/sessions/{sessionId}/variables/{variableName}") + @GET + public Response variableValue(@PathParam("sessionId") String sessionId, @PathParam("variableName") String variableName) { + Object value = sclAPI.variableValue(sessionId, variableName); + return Response.ok(buildJSONResponse("sessionId", sessionId, "variableName", variableName, "variableValue", value)).build(); + } + + @Path("/sessions/{sessionId}/close") + @POST + public Response sessions(@PathParam("sessionId") String sessionId) { + sclAPI.deleteCommandSession(sessionId); + return Response.ok().build(); + } + +} diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTServer.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTServer.java new file mode 100644 index 000000000..0e642026e --- /dev/null +++ b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTServer.java @@ -0,0 +1,85 @@ +package org.simantics.scl.rest; + +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.glassfish.jersey.jackson.JacksonFeature; +import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SCLRESTServer { + + private static final Logger LOGGER = LoggerFactory.getLogger(SCLRESTServer.class); + + private static SCLRESTServer INSTANCE = null; + private static Server server; + private static ServiceServerThread serverThread; + + private SCLRESTServer(String token, int preferablePort) { + ResourceConfig config = new ResourceConfig(); + // JSON serialization/deserialization + config.register(JacksonFeature.class); + // File upload + config.register(MultiPartFeature.class); + // Actual API + config.register(SCLRESTAPI.class); + // Authorization + config.register(new AuthorizationFilter(token)); + + ServletHolder holder = new ServletHolder(new ServletContainer(config)); + + server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(preferablePort); + connector.setHost("localhost"); + + server.setConnectors(new Connector[] { connector }); + + ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); + context.addServlet(holder, "/*"); + } + + private static class ServiceServerThread extends Thread { + + @Override + public void run() { + try { + server.start(); + server.join(); + } catch (Exception e) { + LOGGER.error("Could not start server ", e); + } + } + } + + private static synchronized SCLRESTServer getInstance(String token, int port) { + try { + if (INSTANCE == null) { + INSTANCE = new SCLRESTServer(token, port); + } + } catch (Exception e) { + LOGGER.error("Could not initialize SCL REST server", e); + } + return INSTANCE; + } + + public static synchronized void start(String token, int port) throws Exception { + // Ensure that an instance is created + getInstance(token, port); + if (serverThread == null && server != null) { + serverThread = new ServiceServerThread(); + serverThread.start(); + } + } + + public static synchronized void stop() throws Exception { + if (server != null) + server.stop(); + serverThread = null; + } +} diff --git a/bundles/org.simantics.scl.runtime/scl/Prelude.scl b/bundles/org.simantics.scl.runtime/scl/Prelude.scl index c81f83089..eb1e8cd6f 100644 --- a/bundles/org.simantics.scl.runtime/scl/Prelude.scl +++ b/bundles/org.simantics.scl.runtime/scl/Prelude.scl @@ -1540,6 +1540,24 @@ joinWithSeparator :: Show a => String -> [a] -> String joinWithSeparator separator values = runProc ( StringBuilder.toString $ printWithSeparator StringBuilder.new separator values) + +intercalate :: String -> [String] -> String +intercalate separator strings = do + l = length strings + if l == 0 + then "" + else if l == 1 + then strings!0 + else runProc do + sb = StringBuilder.new + sb << strings!0 + loop i | i == l = () + | otherwise = do + sb << separator << strings!i + loop (i+1) + loop 1 + StringBuilder.toString sb + instance (Show a) => Show [a] where sb <+ l = do len = length l diff --git a/bundles/org.simantics.scl.runtime/scl/SetUtils.scl b/bundles/org.simantics.scl.runtime/scl/SetUtils.scl new file mode 100644 index 000000000..00fa75215 --- /dev/null +++ b/bundles/org.simantics.scl.runtime/scl/SetUtils.scl @@ -0,0 +1,13 @@ +import "Prelude" +import "Set" as Set +import "MSet" as MSet +import "MList" as MList + +fromList :: [a] -> Set.T a +fromList l = runProc (MSet.freeze $ MSet.fromList l) + +toList :: Set.T a -> [a] +toList s = runProc do + result = MList.createC (Set.size s) + Set.iter (MList.add result) s + MList.freeze result \ No newline at end of file diff --git a/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl b/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl index 122fcd02b..7234b70be 100644 --- a/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl +++ b/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl @@ -10,6 +10,7 @@ include "Lazy" as Lazy include "File" as File include "Serialization" as Serialization include "Set" as Set +include "SetUtils" as Set //include "Map" as Map include "MMap" as MMap include "MSet" as MSet diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRRuntimeRuleset.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRRuntimeRuleset.java index 8f6ca3ee9..21f3b65ad 100644 --- a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRRuntimeRuleset.java +++ b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRRuntimeRuleset.java @@ -1,5 +1,15 @@ package org.simantics.scl.runtime.chr; public class CHRRuntimeRuleset { - + int currentId; + + public void register(CHRContext context) { + if(context.currentId < currentId) + context.currentId = currentId; + } + + public void unregister(CHRContext context) { + if(context.currentId > currentId) + currentId = context.currentId; + } } diff --git a/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF index 931ae92cd..061dad852 100644 --- a/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.ui.editors;bundle-version="3.6.0", gnu.trove3;bundle-version="3.0.0", org.simantics.scl.osgi;bundle-version="1.0.0", org.simantics.scl.compiler;bundle-version="0.6.0", - org.junit;bundle-version="4.12.0";resolution:=optional + org.junit;bundle-version="4.12.0";resolution:=optional, + com.ibm.icu Export-Package: org.simantics.scl.ui.console, org.simantics.scl.ui.editor, org.simantics.scl.ui.editor2, diff --git a/bundles/org.simantics.scl.ui/icons/import_error.png b/bundles/org.simantics.scl.ui/icons/import_error.png new file mode 100644 index 000000000..caa1838d7 Binary files /dev/null and b/bundles/org.simantics.scl.ui/icons/import_error.png differ diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/Activator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/Activator.java index a408e7f30..768682fa3 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/Activator.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/Activator.java @@ -33,6 +33,7 @@ public class Activator extends AbstractUIPlugin { reg.put("find", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/find.png") ); reg.put("disk", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/disk.png") ); reg.put("error", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/error.png") ); + reg.put("import_error", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/import_error.png") ); reg.put("warning", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/warning.png") ); } diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java index 4c429e7fd..11749a4b2 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java @@ -37,8 +37,15 @@ public class SCLCompletionProposal implements ICompletionProposal, ICompletionPr private final SCLCompletionType completionType; public SCLCompletionProposal(SCLValue value, int replacementOffset, String prefix) { - this.name = value.getName().name; - this.module = value.getName().module; + String tempName = value.getName().name; + String tempModule = value.getName().module; + int p = tempName.lastIndexOf('.'); + if(p >= 0) { + tempModule = tempModule + "." + tempName.substring(0, p); + tempName = tempName.substring(p+1); + } + this.name = tempName; + this.module = tempModule; this.documentation = value.getDocumentation(); this.content = name + " :: " + value.getType() + " (" + module + ")"; this.replacementOffset = replacementOffset; diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java index 4b6818ab7..378840397 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java @@ -9,6 +9,7 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.simantics.scl.compiler.elaboration.modules.SCLValue; +import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.module.InvalidModulePathException; import org.simantics.scl.compiler.module.ModuleUtils; import org.simantics.scl.compiler.source.ModuleSource; @@ -106,6 +107,7 @@ public class OpenDeclaration extends AbstractHandler { SCLTextEditorEnvironment editorEnvironment = moduleEditor.getSCLTextEditorEnvironment(); editorEnvironment.updateEnvironment(moduleEditor.getDocument()); SCLValue value = editorEnvironment.getValue(identifierAtCaret); + System.out.println("identifierAtCaret = " + identifierAtCaret + " [" + Locations.beginOf(value.definitionLocation) + ", " + Locations.endOf(value.definitionLocation) + "]"); if(value != null) OpenSCLDefinition.openDefinition(value); } diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java index 100f49e25..05015bb0b 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java @@ -1,17 +1,35 @@ package org.simantics.scl.ui.editor2; +import java.text.CharacterIterator; + +import org.eclipse.jface.action.IAction; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.link.LinkedModeModel; +import org.eclipse.jface.text.link.LinkedPosition; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ST; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.IUpdate; +import org.eclipse.ui.texteditor.TextNavigationAction; import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew; import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment; +import org.simantics.scl.ui.editor2.iterator.DocumentCharacterIterator; +import org.simantics.scl.ui.editor2.iterator.JavaWordIterator; + +import com.ibm.icu.text.BreakIterator; public class SCLModuleEditor2 extends TextEditor { private boolean disposed = false; @@ -43,6 +61,34 @@ public class SCLModuleEditor2 extends TextEditor { updatePartName(); } + @Override + protected void createNavigationActions() { + super.createNavigationActions(); + + // Taken from org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.createNavigationActions() + final StyledText textWidget= getSourceViewer().getTextWidget(); + + IAction action = new NavigatePreviousSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS); + setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL); + + action = new NavigateNextSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT); + setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL); + + action = new SelectPreviousSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS); + setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT, SWT.NULL); + + action = new SelectNextSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT); + setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT, SWT.NULL); + } + protected void updatePartName() { setPartName(getEditorInput().getName()); } @@ -66,4 +112,423 @@ public class SCLModuleEditor2 extends TextEditor { public IDocument getDocument() { return getSourceViewer().getDocument(); } + + /** + * Text navigation action to navigate to the next sub-word. + * + * @since 3.0 + */ + protected abstract class NextSubWordAction extends TextNavigationAction { + + protected JavaWordIterator fIterator= new JavaWordIterator(); + + /** + * Creates a new next sub-word action. + * + * @param code Action code for the default operation. Must be an action code from @see org.eclipse.swt.custom.ST. + */ + protected NextSubWordAction(int code) { + super(getSourceViewer().getTextWidget(), code); + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + @Override + public void run() { + final ISourceViewer viewer= getSourceViewer(); + final IDocument document= viewer.getDocument(); + try { + fIterator.setText((CharacterIterator)new DocumentCharacterIterator(document)); + int position= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); + if (position == -1) + return; + + int next= findNextPosition(position); + if (isBlockSelectionModeEnabled() && document.getLineOfOffset(next) != document.getLineOfOffset(position)) { + super.run(); // may navigate into virtual white space + } else if (next != BreakIterator.DONE) { + setCaretPosition(next); + getTextWidget().showSelection(); + fireSelectionChanged(); + } + } catch (BadLocationException x) { + // ignore + } + } + + /** + * Finds the next position after the given position. + * + * @param position the current position + * @return the next position + */ + protected int findNextPosition(int position) { + ISourceViewer viewer= getSourceViewer(); + int widget= -1; + int next= position; + while (next != BreakIterator.DONE && widget == -1) { // XXX: optimize + next= fIterator.following(next); + if (next != BreakIterator.DONE) + widget= modelOffset2WidgetOffset(viewer, next); + } + + IDocument document= viewer.getDocument(); + LinkedModeModel model= LinkedModeModel.getModel(document, position); + if (model != null && next != BreakIterator.DONE) { + LinkedPosition linkedPosition= model.findPosition(new LinkedPosition(document, position, 0)); + if (linkedPosition != null) { + int linkedPositionEnd= linkedPosition.getOffset() + linkedPosition.getLength(); + if (position != linkedPositionEnd && linkedPositionEnd < next) + next= linkedPositionEnd; + } else { + LinkedPosition nextLinkedPosition= model.findPosition(new LinkedPosition(document, next, 0)); + if (nextLinkedPosition != null) { + int nextLinkedPositionOffset= nextLinkedPosition.getOffset(); + if (position != nextLinkedPositionOffset && nextLinkedPositionOffset < next) + next= nextLinkedPositionOffset; + } + } + } + + return next; + } + + /** + * Sets the caret position to the sub-word boundary given with position. + * + * @param position Position where the action should move the caret + */ + protected abstract void setCaretPosition(int position); + } + + /** + * Text navigation action to navigate to the next sub-word. + * + * @since 3.0 + */ + protected class NavigateNextSubWordAction extends NextSubWordAction { + + /** + * Creates a new navigate next sub-word action. + */ + public NavigateNextSubWordAction() { + super(ST.WORD_NEXT); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int) + */ + @Override + protected void setCaretPosition(final int position) { + getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position)); + } + } + + /** + * Text operation action to delete the next sub-word. + * + * @since 3.0 + */ + protected class DeleteNextSubWordAction extends NextSubWordAction implements IUpdate { + + /** + * Creates a new delete next sub-word action. + */ + public DeleteNextSubWordAction() { + super(ST.DELETE_WORD_NEXT); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int) + */ + @Override + protected void setCaretPosition(final int position) { + if (!validateEditorInputState()) + return; + + final ISourceViewer viewer= getSourceViewer(); + StyledText text= viewer.getTextWidget(); + Point widgetSelection= text.getSelection(); + if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) { + final int caret= text.getCaretOffset(); + final int offset= modelOffset2WidgetOffset(viewer, position); + + if (caret == widgetSelection.x) + text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y); + else + text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x); + text.invokeAction(ST.DELETE_NEXT); + } else { + Point selection= viewer.getSelectedRange(); + final int caret, length; + if (selection.y != 0) { + caret= selection.x; + length= selection.y; + } else { + caret= widgetOffset2ModelOffset(viewer, text.getCaretOffset()); + length= position - caret; + } + + try { + viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$ + } catch (BadLocationException exception) { + // Should not happen + } + } + } + + /* + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + setEnabled(isEditorInputModifiable()); + } + } + + /** + * Text operation action to select the next sub-word. + * + * @since 3.0 + */ + protected class SelectNextSubWordAction extends NextSubWordAction { + + /** + * Creates a new select next sub-word action. + */ + public SelectNextSubWordAction() { + super(ST.SELECT_WORD_NEXT); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int) + */ + @Override + protected void setCaretPosition(final int position) { + final ISourceViewer viewer= getSourceViewer(); + + final StyledText text= viewer.getTextWidget(); + if (text != null && !text.isDisposed()) { + + final Point selection= text.getSelection(); + final int caret= text.getCaretOffset(); + final int offset= modelOffset2WidgetOffset(viewer, position); + + if (caret == selection.x) + text.setSelectionRange(selection.y, offset - selection.y); + else + text.setSelectionRange(selection.x, offset - selection.x); + } + } + } + + /** + * Text navigation action to navigate to the previous sub-word. + * + * @since 3.0 + */ + protected abstract class PreviousSubWordAction extends TextNavigationAction { + + protected JavaWordIterator fIterator= new JavaWordIterator(); + + /** + * Creates a new previous sub-word action. + * + * @param code Action code for the default operation. Must be an action code from @see org.eclipse.swt.custom.ST. + */ + protected PreviousSubWordAction(final int code) { + super(getSourceViewer().getTextWidget(), code); + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + @Override + public void run() { + final ISourceViewer viewer= getSourceViewer(); + final IDocument document= viewer.getDocument(); + try { + fIterator.setText((CharacterIterator)new DocumentCharacterIterator(document)); + int position= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); + if (position == -1) + return; + + int previous= findPreviousPosition(position); + if (isBlockSelectionModeEnabled() && document.getLineOfOffset(previous) != document.getLineOfOffset(position)) { + super.run(); // may navigate into virtual white space + } else if (previous != BreakIterator.DONE) { + setCaretPosition(previous); + getTextWidget().showSelection(); + fireSelectionChanged(); + } + } catch (BadLocationException x) { + // ignore - getLineOfOffset failed + } + + } + + /** + * Finds the previous position before the given position. + * + * @param position the current position + * @return the previous position + */ + protected int findPreviousPosition(int position) { + ISourceViewer viewer= getSourceViewer(); + int widget= -1; + int previous= position; + while (previous != BreakIterator.DONE && widget == -1) { // XXX: optimize + previous= fIterator.preceding(previous); + if (previous != BreakIterator.DONE) + widget= modelOffset2WidgetOffset(viewer, previous); + } + + IDocument document= viewer.getDocument(); + LinkedModeModel model= LinkedModeModel.getModel(document, position); + if (model != null && previous != BreakIterator.DONE) { + LinkedPosition linkedPosition= model.findPosition(new LinkedPosition(document, position, 0)); + if (linkedPosition != null) { + int linkedPositionOffset= linkedPosition.getOffset(); + if (position != linkedPositionOffset && previous < linkedPositionOffset) + previous= linkedPositionOffset; + } else { + LinkedPosition previousLinkedPosition= model.findPosition(new LinkedPosition(document, previous, 0)); + if (previousLinkedPosition != null) { + int previousLinkedPositionEnd= previousLinkedPosition.getOffset() + previousLinkedPosition.getLength(); + if (position != previousLinkedPositionEnd && previous < previousLinkedPositionEnd) + previous= previousLinkedPositionEnd; + } + } + } + + return previous; + } + + /** + * Sets the caret position to the sub-word boundary given with position. + * + * @param position Position where the action should move the caret + */ + protected abstract void setCaretPosition(int position); + } + + /** + * Text navigation action to navigate to the previous sub-word. + * + * @since 3.0 + */ + protected class NavigatePreviousSubWordAction extends PreviousSubWordAction { + + /** + * Creates a new navigate previous sub-word action. + */ + public NavigatePreviousSubWordAction() { + super(ST.WORD_PREVIOUS); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int) + */ + @Override + protected void setCaretPosition(final int position) { + getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position)); + } + } + + /** + * Text operation action to delete the previous sub-word. + * + * @since 3.0 + */ + protected class DeletePreviousSubWordAction extends PreviousSubWordAction implements IUpdate { + + /** + * Creates a new delete previous sub-word action. + */ + public DeletePreviousSubWordAction() { + super(ST.DELETE_WORD_PREVIOUS); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int) + */ + @Override + protected void setCaretPosition(int position) { + if (!validateEditorInputState()) + return; + + final int length; + final ISourceViewer viewer= getSourceViewer(); + StyledText text= viewer.getTextWidget(); + Point widgetSelection= text.getSelection(); + if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) { + final int caret= text.getCaretOffset(); + final int offset= modelOffset2WidgetOffset(viewer, position); + + if (caret == widgetSelection.x) + text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y); + else + text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x); + text.invokeAction(ST.DELETE_PREVIOUS); + } else { + Point selection= viewer.getSelectedRange(); + if (selection.y != 0) { + position= selection.x; + length= selection.y; + } else { + length= widgetOffset2ModelOffset(viewer, text.getCaretOffset()) - position; + } + + try { + viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$ + } catch (BadLocationException exception) { + // Should not happen + } + } + } + + /* + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + setEnabled(isEditorInputModifiable()); + } + } + + /** + * Text operation action to select the previous sub-word. + * + * @since 3.0 + */ + protected class SelectPreviousSubWordAction extends PreviousSubWordAction { + + /** + * Creates a new select previous sub-word action. + */ + public SelectPreviousSubWordAction() { + super(ST.SELECT_WORD_PREVIOUS); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int) + */ + @Override + protected void setCaretPosition(final int position) { + final ISourceViewer viewer= getSourceViewer(); + + final StyledText text= viewer.getTextWidget(); + if (text != null && !text.isDisposed()) { + + final Point selection= text.getSelection(); + final int caret= text.getCaretOffset(); + final int offset= modelOffset2WidgetOffset(viewer, position); + + if (caret == selection.x) + text.setSelectionRange(selection.y, offset - selection.y); + else + text.setSelectionRange(selection.x, offset - selection.x); + } + } + } + } diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2DocumentProvider.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2DocumentProvider.java index 4dfa0507b..cf6bf9a87 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2DocumentProvider.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2DocumentProvider.java @@ -23,32 +23,38 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider { private SCLSourceViewerConfigurationNew sourceViewer; protected AnnotationModel annotationModel = new AnnotationModel(); - public SCLModuleEditor2DocumentProvider( - SCLSourceViewerConfigurationNew sourceViewer) { + private Object currentElement; + private TextualModuleSource currentSource; + + public SCLModuleEditor2DocumentProvider(SCLSourceViewerConfigurationNew sourceViewer) { this.sourceViewer = sourceViewer; } - private static TextualModuleSource toTextualModuleSource(Object input) { - if(!(input instanceof SCLModuleEditorInput)) - return null; - ModuleSource source = ((SCLModuleEditorInput)input).getAdapter(ModuleSource.class); + private void updateTextualModuleSource(Object input) { + if (currentElement != null && currentElement.equals(input)) + return; + currentElement = input; + if(!(currentElement instanceof SCLModuleEditorInput)) + return; + + ModuleSource source = ((SCLModuleEditorInput)currentElement).getAdapter(ModuleSource.class); if(source == null) - return null; + return; if(!(source instanceof TextualModuleSource)) - return null; - return (TextualModuleSource)source; + return; + currentSource = (TextualModuleSource)source; } @Override protected IDocument createDocument(Object element) throws CoreException { - TextualModuleSource source = toTextualModuleSource(element); - if(source == null) + updateTextualModuleSource(element); + if(currentSource == null) throw new CoreException( new Status(Status.ERROR, "org.simantics.scl.ui", "Source for the SCL module could not be found.") ); Document document; try { - document = new Document(source.getSourceText(null)); + document = new Document(currentSource.getSourceText(null)); } catch (IOException e) { throw new CoreException( new Status(Status.ERROR, "org.simantics.scl.ui", "Reading SCL module failed.", e) @@ -57,16 +63,25 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider { IDocumentPartitioner partitioner = new FastPartitioner(new SCLPartitionScanner(), SCLPartitionScanner.PARTITION_TYPES); partitioner.connect(document); document.setDocumentPartitioner(partitioner); - sourceViewer.updateCompletionAssistModuleName(source.getModuleName()); + sourceViewer.updateCompletionAssistModuleName(currentSource.getModuleName()); return document; } + @Override + public void changed(Object element) { + updateTextualModuleSource(element); + } + + @Override + public void aboutToChange(Object element) { + super.aboutToChange(element); + } + @Override public boolean isModifiable(Object element) { - TextualModuleSource source = toTextualModuleSource(element); - if(source == null) + if(currentSource == null) return false; - return source.isUpdateable(); + return currentSource.isUpdateable(); } @Override @@ -84,10 +99,9 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider { @Override protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { - TextualModuleSource source = toTextualModuleSource(element); - if(source == null) + if(currentSource == null) return; - source.update(document.get()); + currentSource.update(document.get()); } @Override diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/DocumentCharacterIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/DocumentCharacterIterator.java new file mode 100644 index 000000000..de12b15f4 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/DocumentCharacterIterator.java @@ -0,0 +1,220 @@ +package org.simantics.scl.ui.editor2.iterator; + +import java.text.CharacterIterator; + +import org.eclipse.core.runtime.Assert; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + + +/** + * An IDocument based implementation of + * CharacterIterator and CharSequence. Note that + * the supplied document is not copied; if the document is modified during the + * lifetime of a DocumentCharacterIterator, the methods + * returning document content may not always return the same values. Also, if + * accessing the document fails with a {@link BadLocationException}, any of + * CharacterIterator methods as well as charAtmay + * return {@link CharacterIterator#DONE}. + * + * @since 3.0 + */ +public class DocumentCharacterIterator implements CharacterIterator, CharSequence { + + private int fIndex= -1; + private final IDocument fDocument; + private final int fFirst; + private final int fLast; + + private void invariant() { + Assert.isTrue(fIndex >= fFirst); + Assert.isTrue(fIndex <= fLast); + } + + /** + * Creates an iterator for the entire document. + * + * @param document the document backing this iterator + * @throws BadLocationException if the indices are out of bounds + */ + public DocumentCharacterIterator(IDocument document) throws BadLocationException { + this(document, 0); + } + + /** + * Creates an iterator, starting at offset first. + * + * @param document the document backing this iterator + * @param first the first character to consider + * @throws BadLocationException if the indices are out of bounds + */ + public DocumentCharacterIterator(IDocument document, int first) throws BadLocationException { + this(document, first, document.getLength()); + } + + /** + * Creates an iterator for the document contents from first (inclusive) to + * last (exclusive). + * + * @param document the document backing this iterator + * @param first the first character to consider + * @param last the last character index to consider + * @throws BadLocationException if the indices are out of bounds + */ + public DocumentCharacterIterator(IDocument document, int first, int last) throws BadLocationException { + if (document == null) + throw new NullPointerException(); + if (first < 0 || first > last) + throw new BadLocationException(); + if (last > document.getLength()) { + throw new BadLocationException(); + } + fDocument= document; + fFirst= first; + fLast= last; + fIndex= first; + invariant(); + } + + /* + * @see java.text.CharacterIterator#first() + */ + public char first() { + return setIndex(getBeginIndex()); + } + + /* + * @see java.text.CharacterIterator#last() + */ + public char last() { + if (fFirst == fLast) + return setIndex(getEndIndex()); + else + return setIndex(getEndIndex() - 1); + } + + /* + * @see java.text.CharacterIterator#current() + */ + public char current() { + if (fIndex >= fFirst && fIndex < fLast) + try { + return fDocument.getChar(fIndex); + } catch (BadLocationException e) { + // ignore + } + return DONE; + } + + /* + * @see java.text.CharacterIterator#next() + */ + public char next() { + return setIndex(Math.min(fIndex + 1, getEndIndex())); + } + + /* + * @see java.text.CharacterIterator#previous() + */ + public char previous() { + if (fIndex > getBeginIndex()) { + return setIndex(fIndex - 1); + } else { + return DONE; + } + } + + /* + * @see java.text.CharacterIterator#setIndex(int) + */ + public char setIndex(int position) { + if (position >= getBeginIndex() && position <= getEndIndex()) + fIndex= position; + else + throw new IllegalArgumentException(); + + invariant(); + return current(); + } + + /* + * @see java.text.CharacterIterator#getBeginIndex() + */ + public int getBeginIndex() { + return fFirst; + } + + /* + * @see java.text.CharacterIterator#getEndIndex() + */ + public int getEndIndex() { + return fLast; + } + + /* + * @see java.text.CharacterIterator#getIndex() + */ + public int getIndex() { + return fIndex; + } + + /* + * @see java.text.CharacterIterator#clone() + */ + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + } + + /* + * @see java.lang.CharSequence#length() + */ + public int length() { + return getEndIndex() - getBeginIndex(); + } + + /** + * {@inheritDoc} + *

    + * Note that, if the document is modified concurrently, this method may + * return {@link CharacterIterator#DONE} if a {@link BadLocationException} + * was thrown when accessing the backing document. + *

    + * + * @param index {@inheritDoc} + * @return {@inheritDoc} + */ + public char charAt(int index) { + if (index >= 0 && index < length()) + try { + return fDocument.getChar(getBeginIndex() + index); + } catch (BadLocationException e) { + // ignore and return DONE + return DONE; + } + else + throw new IndexOutOfBoundsException(); + } + + /* + * @see java.lang.CharSequence#subSequence(int, int) + */ + public CharSequence subSequence(int start, int end) { + if (start < 0) + throw new IndexOutOfBoundsException(); + if (end < start) + throw new IndexOutOfBoundsException(); + if (end > length()) + throw new IndexOutOfBoundsException(); + try { + return new DocumentCharacterIterator(fDocument, getBeginIndex() + start, getBeginIndex() + end); + } catch (BadLocationException ex) { + throw new IndexOutOfBoundsException(); + } + } +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaBreakIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaBreakIterator.java new file mode 100644 index 000000000..f02087896 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaBreakIterator.java @@ -0,0 +1,431 @@ +package org.simantics.scl.ui.editor2.iterator; + +import java.text.CharacterIterator; + +import com.ibm.icu.text.BreakIterator; + +import org.eclipse.core.runtime.Assert; + + + +/** + * A java break iterator. It returns all breaks, including before and after + * whitespace, and it returns all camel case breaks. + *

    + * A line break may be any of "\n", "\r", "\r\n", "\n\r". + *

    + * + * @since 3.0 + */ +public class JavaBreakIterator extends BreakIterator { + + /** + * A run of common characters. + */ + protected static abstract class Run { + /** The length of this run. */ + protected int length; + + public Run() { + init(); + } + + /** + * Returns true if this run consumes ch, + * false otherwise. If true is returned, + * the length of the receiver is adjusted accordingly. + * + * @param ch the character to test + * @return true if ch was consumed + */ + protected boolean consume(char ch) { + if (isValid(ch)) { + length++; + return true; + } + return false; + } + + /** + * Whether this run accepts that character; does not update state. Called + * from the default implementation of consume. + * + * @param ch the character to test + * @return true if ch is accepted + */ + protected abstract boolean isValid(char ch); + + /** + * Resets this run to the initial state. + */ + protected void init() { + length= 0; + } + } + + static final class Whitespace extends Run { + @Override + protected boolean isValid(char ch) { + return Character.isWhitespace(ch) && ch != '\n' && ch != '\r'; + } + } + + static final class LineDelimiter extends Run { + /** State: INIT -> delimiter -> EXIT. */ + private char fState; + private static final char INIT= '\0'; + private static final char EXIT= '\1'; + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#init() + */ + @Override + protected void init() { + super.init(); + fState= INIT; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#consume(char) + */ + @Override + protected boolean consume(char ch) { + if (!isValid(ch) || fState == EXIT) + return false; + + if (fState == INIT) { + fState= ch; + length++; + return true; + } else if (fState != ch) { + fState= EXIT; + length++; + return true; + } else { + return false; + } + } + + @Override + protected boolean isValid(char ch) { + return ch == '\n' || ch == '\r'; + } + } + + static final class Identifier extends Run { + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#isValid(char) + */ + @Override + protected boolean isValid(char ch) { + return Character.isJavaIdentifierPart(ch); + } + } + + static final class CamelCaseIdentifier extends Run { + /* states */ + private static final int S_INIT= 0; + private static final int S_LOWER= 1; + private static final int S_ONE_CAP= 2; + private static final int S_ALL_CAPS= 3; + private static final int S_EXIT= 4; + private static final int S_EXIT_MINUS_ONE= 5; + + /* character types */ + private static final int K_INVALID= 0; + private static final int K_LOWER= 1; + private static final int K_UPPER= 2; + private static final int K_OTHER= 3; + + private int fState; + + private final static int[][] MATRIX= new int[][] { + // K_INVALID, K_LOWER, K_UPPER, K_OTHER + { S_EXIT, S_LOWER, S_ONE_CAP, S_LOWER }, // S_INIT + { S_EXIT, S_LOWER, S_EXIT, S_LOWER }, // S_LOWER + { S_EXIT, S_LOWER, S_ALL_CAPS, S_LOWER }, // S_ONE_CAP + { S_EXIT, S_EXIT_MINUS_ONE, S_ALL_CAPS, S_LOWER }, // S_ALL_CAPS + }; + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#init() + */ + @Override + protected void init() { + super.init(); + fState= S_INIT; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#consumes(char) + */ + @Override + protected boolean consume(char ch) { + int kind= getKind(ch); + fState= MATRIX[fState][kind]; + switch (fState) { + case S_LOWER: + case S_ONE_CAP: + case S_ALL_CAPS: + length++; + return true; + case S_EXIT: + return false; + case S_EXIT_MINUS_ONE: + length--; + return false; + default: + Assert.isTrue(false); + return false; + } + } + + /** + * Determines the kind of a character. + * + * @param ch the character to test + */ + private int getKind(char ch) { + if (Character.isUpperCase(ch)) + return K_UPPER; + if (Character.isLowerCase(ch)) + return K_LOWER; + if (Character.isJavaIdentifierPart(ch)) // _, digits... + return K_OTHER; + return K_INVALID; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#isValid(char) + */ + @Override + protected boolean isValid(char ch) { + return Character.isJavaIdentifierPart(ch); + } + } + + static final class Other extends Run { + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#isValid(char) + */ + @Override + protected boolean isValid(char ch) { + return !Character.isWhitespace(ch) && !Character.isJavaIdentifierPart(ch); + } + } + + private static final Run WHITESPACE= new Whitespace(); + private static final Run DELIMITER= new LineDelimiter(); + private static final Run CAMELCASE= new CamelCaseIdentifier(); // new Identifier(); + private static final Run OTHER= new Other(); + + /** The platform break iterator (word instance) used as a base. */ + protected final BreakIterator fIterator; + /** The text we operate on. */ + protected CharSequence fText; + /** our current position for the stateful methods. */ + private int fIndex; + + + /** + * Creates a new break iterator. + */ + public JavaBreakIterator() { + fIterator= BreakIterator.getWordInstance(); + fIndex= fIterator.current(); + } + + /* + * @see java.text.BreakIterator#current() + */ + @Override + public int current() { + return fIndex; + } + + /* + * @see java.text.BreakIterator#first() + */ + @Override + public int first() { + fIndex= fIterator.first(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#following(int) + */ + @Override + public int following(int offset) { + // work around too eager IAEs in standard implementation + if (offset == getText().getEndIndex()) + return DONE; + + int next= fIterator.following(offset); + if (next == DONE) + return DONE; + + // TODO deal with complex script word boundaries + // Math.min(offset + run.length, next) does not work + // since BreakIterator.getWordInstance considers _ as boundaries + // seems to work fine, however + Run run= consumeRun(offset); + return offset + run.length; + + } + + /** + * Consumes a run of characters at the limits of which we introduce a break. + * @param offset the offset to start at + * @return the run that was consumed + */ + private Run consumeRun(int offset) { + // assert offset < length + + char ch= fText.charAt(offset); + int length= fText.length(); + Run run= getRun(ch); + while (run.consume(ch) && offset < length - 1) { + offset++; + ch= fText.charAt(offset); + } + + return run; + } + + /** + * Returns a run based on a character. + * + * @param ch the character to test + * @return the correct character given ch + */ + private Run getRun(char ch) { + Run run; + if (WHITESPACE.isValid(ch)) + run= WHITESPACE; + else if (DELIMITER.isValid(ch)) + run= DELIMITER; + else if (CAMELCASE.isValid(ch)) + run= CAMELCASE; + else if (OTHER.isValid(ch)) + run= OTHER; + else { + Assert.isTrue(false); + return null; + } + + run.init(); + return run; + } + + /* + * @see java.text.BreakIterator#getText() + */ + @Override + public CharacterIterator getText() { + return fIterator.getText(); + } + + /* + * @see java.text.BreakIterator#isBoundary(int) + */ + @Override + public boolean isBoundary(int offset) { + if (offset == getText().getBeginIndex()) + return true; + else + return following(offset - 1) == offset; + } + + /* + * @see java.text.BreakIterator#last() + */ + @Override + public int last() { + fIndex= fIterator.last(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#next() + */ + @Override + public int next() { + fIndex= following(fIndex); + return fIndex; + } + + /* + * @see java.text.BreakIterator#next(int) + */ + @Override + public int next(int n) { + return fIterator.next(n); + } + + /* + * @see java.text.BreakIterator#preceding(int) + */ + @Override + public int preceding(int offset) { + if (offset == getText().getBeginIndex()) + return DONE; + + if (isBoundary(offset - 1)) + return offset - 1; + + int previous= offset - 1; + do { + previous= fIterator.preceding(previous); + } while (!isBoundary(previous)); + + int last= DONE; + while (previous < offset) { + last= previous; + previous= following(previous); + } + + return last; + } + + /* + * @see java.text.BreakIterator#previous() + */ + @Override + public int previous() { + fIndex= preceding(fIndex); + return fIndex; + } + + /* + * @see java.text.BreakIterator#setText(java.lang.String) + */ + @Override + public void setText(String newText) { + setText((CharSequence) newText); + } + + /** + * Creates a break iterator given a char sequence. + * @param newText the new text + */ + public void setText(CharSequence newText) { + fText= newText; + fIterator.setText(new SequenceCharacterIterator(newText)); + first(); + } + + /* + * @see java.text.BreakIterator#setText(java.text.CharacterIterator) + */ + @Override + public void setText(CharacterIterator newText) { + if (newText instanceof CharSequence) { + fText= (CharSequence) newText; + fIterator.setText(newText); + first(); + } else { + throw new UnsupportedOperationException("CharacterIterator not supported"); //$NON-NLS-1$ + } + } +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaWordIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaWordIterator.java new file mode 100644 index 000000000..403cc9df3 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaWordIterator.java @@ -0,0 +1,224 @@ +package org.simantics.scl.ui.editor2.iterator; + +import java.text.CharacterIterator; + +import com.ibm.icu.text.BreakIterator; + +import org.eclipse.core.runtime.Assert; + + + +/** + * Breaks java text into word starts, also stops at line start and end. No + * direction dependency. + * + * @since 3.0 + */ +public class JavaWordIterator extends BreakIterator { + + /** + * The underlying java break iterator. It returns all breaks, including + * before and after every whitespace. + */ + private JavaBreakIterator fIterator; + /** The current index for the stateful operations. */ + private int fIndex; + + /** + * Creates a new word iterator. + */ + public JavaWordIterator() { + fIterator= new JavaBreakIterator(); + first(); + } + + /* + * @see java.text.BreakIterator#first() + */ + @Override + public int first() { + fIndex= fIterator.first(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#last() + */ + @Override + public int last() { + fIndex= fIterator.last(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#next(int) + */ + @Override + public int next(int n) { + int next= 0; + while (--n > 0 && next != DONE) { + next= next(); + } + return next; + } + + /* + * @see java.text.BreakIterator#next() + */ + @Override + public int next() { + fIndex= following(fIndex); + return fIndex; + } + + /* + * @see java.text.BreakIterator#previous() + */ + @Override + public int previous() { + fIndex= preceding(fIndex); + return fIndex; + } + + + /* + * @see java.text.BreakIterator#preceding(int) + */ + @Override + public int preceding(int offset) { + int first= fIterator.preceding(offset); + if (isWhitespace(first, offset)) { + int second= fIterator.preceding(first); + if (second != DONE && !isDelimiter(second, first)) + return second; + } + return first; + } + + /* + * @see java.text.BreakIterator#following(int) + */ + @Override + public int following(int offset) { + int first= fIterator.following(offset); + if (eatFollowingWhitespace(offset, first)) { + int second= fIterator.following(first); + if (isWhitespace(first, second)) + return second; + } + return first; + } + + private boolean eatFollowingWhitespace(int offset, int exclusiveEnd) { + if (exclusiveEnd == DONE || offset == DONE) + return false; + + if (isWhitespace(offset, exclusiveEnd)) + return false; + if (isDelimiter(offset, exclusiveEnd)) + return false; + + return true; + } + + /** + * Returns true if the given sequence into the underlying text + * represents a delimiter, false otherwise. + * + * @param offset the offset + * @param exclusiveEnd the end offset + * @return true if the given range is a delimiter + */ + private boolean isDelimiter(int offset, int exclusiveEnd) { + if (exclusiveEnd == DONE || offset == DONE) + return false; + + Assert.isTrue(offset >= 0); + Assert.isTrue(exclusiveEnd <= getText().getEndIndex()); + Assert.isTrue(exclusiveEnd > offset); + + CharSequence seq= fIterator.fText; + + while (offset < exclusiveEnd) { + char ch= seq.charAt(offset); + if (ch != '\n' && ch != '\r') + return false; + offset++; + } + + return true; + } + + /** + * Returns true if the given sequence into the underlying text + * represents whitespace, but not a delimiter, false otherwise. + * + * @param offset the offset + * @param exclusiveEnd the end offset + * @return true if the given range is whitespace + */ + private boolean isWhitespace(int offset, int exclusiveEnd) { + if (exclusiveEnd == DONE || offset == DONE) + return false; + + Assert.isTrue(offset >= 0); + Assert.isTrue(exclusiveEnd <= getText().getEndIndex()); + Assert.isTrue(exclusiveEnd > offset); + + CharSequence seq= fIterator.fText; + + while (offset < exclusiveEnd) { + char ch= seq.charAt(offset); + if (!Character.isWhitespace(ch)) + return false; + if (ch == '\n' || ch == '\r') + return false; + offset++; + } + + return true; + } + + /* + * @see java.text.BreakIterator#current() + */ + @Override + public int current() { + return fIndex; + } + + /* + * @see java.text.BreakIterator#getText() + */ + @Override + public CharacterIterator getText() { + return fIterator.getText(); + } + + /** + * Sets the text as CharSequence. + * @param newText the new text + */ + public void setText(CharSequence newText) { + fIterator.setText(newText); + first(); + } + + /* + * @see java.text.BreakIterator#setText(java.text.CharacterIterator) + */ + @Override + public void setText(CharacterIterator newText) { + fIterator.setText(newText); + first(); + } + + /* + * @see java.text.BreakIterator#setText(java.lang.String) + */ + @Override + public void setText(String newText) { + setText((CharSequence) newText); + } + +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/SequenceCharacterIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/SequenceCharacterIterator.java new file mode 100644 index 000000000..96520a315 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/SequenceCharacterIterator.java @@ -0,0 +1,158 @@ +package org.simantics.scl.ui.editor2.iterator; + +import java.text.CharacterIterator; + +import org.eclipse.core.runtime.Assert; + + + +/** + * A CharSequence based implementation of CharacterIterator. + * + * @since 3.0 + */ +public class SequenceCharacterIterator implements CharacterIterator { + + private int fIndex= -1; + private final CharSequence fSequence; + private final int fFirst; + private final int fLast; + + private void invariant() { + Assert.isTrue(fIndex >= fFirst); + Assert.isTrue(fIndex <= fLast); + } + + /** + * Creates an iterator for the entire sequence. + * + * @param sequence the sequence backing this iterator + */ + public SequenceCharacterIterator(CharSequence sequence) { + this(sequence, 0); + } + + /** + * Creates an iterator. + * + * @param sequence the sequence backing this iterator + * @param first the first character to consider + * @throws IllegalArgumentException if the indices are out of bounds + */ + public SequenceCharacterIterator(CharSequence sequence, int first) throws IllegalArgumentException { + this(sequence, first, sequence.length()); + } + + /** + * Creates an iterator. + * + * @param sequence the sequence backing this iterator + * @param first the first character to consider + * @param last the last character index to consider + * @throws IllegalArgumentException if the indices are out of bounds + */ + public SequenceCharacterIterator(CharSequence sequence, int first, int last) throws IllegalArgumentException { + if (sequence == null) + throw new NullPointerException(); + if (first < 0 || first > last) + throw new IllegalArgumentException(); + if (last > sequence.length()) + throw new IllegalArgumentException(); + fSequence= sequence; + fFirst= first; + fLast= last; + fIndex= first; + invariant(); + } + + /* + * @see java.text.CharacterIterator#first() + */ + public char first() { + return setIndex(getBeginIndex()); + } + + /* + * @see java.text.CharacterIterator#last() + */ + public char last() { + if (fFirst == fLast) + return setIndex(getEndIndex()); + else + return setIndex(getEndIndex() - 1); + } + + /* + * @see java.text.CharacterIterator#current() + */ + public char current() { + if (fIndex >= fFirst && fIndex < fLast) + return fSequence.charAt(fIndex); + else + return DONE; + } + + /* + * @see java.text.CharacterIterator#next() + */ + public char next() { + return setIndex(Math.min(fIndex + 1, getEndIndex())); + } + + /* + * @see java.text.CharacterIterator#previous() + */ + public char previous() { + if (fIndex > getBeginIndex()) { + return setIndex(fIndex - 1); + } else { + return DONE; + } + } + + /* + * @see java.text.CharacterIterator#setIndex(int) + */ + public char setIndex(int position) { + if (position >= getBeginIndex() && position <= getEndIndex()) + fIndex= position; + else + throw new IllegalArgumentException(); + + invariant(); + return current(); + } + + /* + * @see java.text.CharacterIterator#getBeginIndex() + */ + public int getBeginIndex() { + return fFirst; + } + + /* + * @see java.text.CharacterIterator#getEndIndex() + */ + public int getEndIndex() { + return fLast; + } + + /* + * @see java.text.CharacterIterator#getIndex() + */ + public int getIndex() { + return fIndex; + } + + /* + * @see java.text.CharacterIterator#clone() + */ + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + } +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLIssuesView.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLIssuesView.java index b4fd1edd8..3e0cc3120 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLIssuesView.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLIssuesView.java @@ -90,6 +90,8 @@ public class SCLIssuesView extends ViewPart { SCLIssuesTableEntry entry = (SCLIssuesTableEntry)element; return entry.error.severity == ErrorSeverity.ERROR ? imageRegistry.get("error") + : entry.error.severity == ErrorSeverity.IMPORT_ERROR + ? imageRegistry.get("import_error") : imageRegistry.get("warning"); } }); diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleAction.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleAction.java new file mode 100644 index 000000000..1d70442c8 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleAction.java @@ -0,0 +1,72 @@ +package org.simantics.scl.ui.modulebrowser; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.simantics.scl.ui.Activator; + +import gnu.trove.map.hash.THashMap; + +public class CreateModuleAction { + public static final String PREFIX = "reference:file:/"; + + public static final void createModule(Bundle bundle, String packageName, String moduleName) throws IOException { + String bundleLocation = bundle.getLocation(); + bundleLocation = bundleLocation.substring(PREFIX.length()); + + Path packagePath = Paths.get(bundleLocation).resolve("scl").resolve(packageName); + Files.createDirectories(packagePath); + Path modulePath = packagePath.resolve(moduleName + ".scl"); + if(Files.exists(modulePath)) + return; + Files.createFile(modulePath); + } + + public static THashMap findGoodBundles() { + BundleContext context = Activator.getInstance().getBundle().getBundleContext(); + THashMap result = new THashMap(); + for(Bundle bundle : context.getBundles()) { + String location = bundle.getLocation(); + if(location.endsWith(".jar") || !location.startsWith(PREFIX)) + continue; + location = location.substring(PREFIX.length()); + Path bundlePath = Paths.get(location); + if(!Files.isDirectory(bundlePath)) + continue; + result.put(bundle.getSymbolicName(), bundle); + } + return result; + } + + public static String findBestPlugin(THashMap bundles, String packageName) { + for(Bundle bundle : bundles.values()) { + String location = bundle.getLocation(); + location = location.substring(PREFIX.length()); + Path packagePath = Paths.get(location).resolve("scl").resolve(packageName); + if(Files.exists(packagePath)) + return bundle.getSymbolicName(); + } + int p = packageName.lastIndexOf('/'); + if(p == -1) + return ""; + else + return findBestPlugin(bundles, packageName.substring(0, p)); + } + + public static int packageMatchLength(Bundle bundle, String packageName) { + if(bundle.getEntry("scl") == null) + return 0; + packageName = "scl/" + packageName; + while(packageName.length() > 3) { + if(bundle.getEntry(packageName) != null) + return packageName.length(); + int p = packageName.lastIndexOf('/'); + packageName = packageName.substring(0, p); + } + return 3; + } +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleDialog.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleDialog.java new file mode 100644 index 000000000..875c9ace4 --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleDialog.java @@ -0,0 +1,186 @@ +package org.simantics.scl.ui.modulebrowser; + +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.osgi.framework.Bundle; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.ui.editor2.OpenSCLModule; +import org.simantics.scl.ui.modulebrowser.PluginSelectionDialog.Entry; + +import gnu.trove.map.hash.THashMap; + +public class CreateModuleDialog extends Dialog { + + SCLModuleBrowser parentBrowser; + + String initialPackageName = ""; + String initialPluginName = ""; + + Text packageName; + Text moduleName; + Text pluginName; + private THashMap bundles; + + private Color normalBackground; + private Color errorBackground; + + protected CreateModuleDialog(Shell parentShell, SCLModuleBrowser parentBrowser) { + super(parentShell); + this.parentBrowser = parentBrowser; + setShellStyle(SWT.RESIZE | SWT.TITLE | SWT.BORDER); + bundles = CreateModuleAction.findGoodBundles(); + + normalBackground = parentShell.getDisplay().getSystemColor(SWT.COLOR_WHITE); + errorBackground = new Color(parentShell.getDisplay(), 255, 128, 128); + } + + @Override + protected Control createDialogArea(Composite parent) { + getShell().setText("Create New Module"); + getShell().addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + errorBackground.dispose(); + } + }); + + final Composite composite = (Composite) super.createDialogArea(parent); + GridLayoutFactory.fillDefaults().margins(10,10).numColumns(2).applyTo(composite); + GridDataFactory.fillDefaults().grab(true,true).applyTo(composite); + + // Package name + Label packageNameLabel = new Label(composite, SWT.NONE); + packageNameLabel.setText("Package"); + GridDataFactory.fillDefaults().applyTo(packageNameLabel); + + packageName = new Text(composite, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).minSize(500, SWT.DEFAULT).applyTo(packageName); + packageName.setText(initialPackageName); + packageName.addModifyListener(modifyListener); + + // Module name + Label moduleNameLabel = new Label(composite, SWT.NONE); + moduleNameLabel.setText("Module name"); + GridDataFactory.fillDefaults().applyTo(moduleNameLabel); + + moduleName = new Text(composite, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(moduleName); + moduleName.addModifyListener(modifyListener); + + // Plugin + Label pluginNameLabel = new Label(composite, SWT.NONE); + pluginNameLabel.setText("Plugin"); + GridDataFactory.fillDefaults().applyTo(pluginNameLabel); + + Composite pluginNameComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(pluginNameComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(pluginNameComposite); + + pluginName = new Text(pluginNameComposite, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(pluginName); + pluginName.setText(initialPluginName); + pluginName.addModifyListener(modifyListener); + + Button browsePlugins = new Button(pluginNameComposite, SWT.PUSH); + browsePlugins.setText("Browse..."); + GridDataFactory.fillDefaults().applyTo(browsePlugins); + browsePlugins.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + browsePlugins(); + } + }); + + // Focus + moduleName.setFocus(); + parent.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + validate(); + } + }); + + return composite; + } + + private void browsePlugins() { + ArrayList entries = new ArrayList(bundles.size()); + String currentPackageName = packageName.getText(); + for(Bundle bundle : bundles.values()) + entries.add(new Entry(bundle, CreateModuleAction.packageMatchLength(bundle, currentPackageName))); + PluginSelectionDialog dialog = new PluginSelectionDialog(getShell(), entries); + if(dialog.open() == Dialog.OK) { + Entry result = (Entry)dialog.getFirstResult(); + if(result != null) { + pluginName.setText(result.bundle.getSymbolicName()); + validate(); + } + } + } + + private void validate() { + boolean validPackageName = CreateModuleValidator.isValidPackageName(packageName.getText()); + packageName.setBackground(validPackageName ? normalBackground : errorBackground); + + boolean validModuleName = CreateModuleValidator.isValidModuleName(moduleName.getText()); + if(validModuleName && validPackageName) { + String fullModuleName = packageName.getText() + "/" + moduleName.getText(); + validModuleName = SCLOsgi.SOURCE_REPOSITORY.getModuleSource(fullModuleName, null) == null; + } + moduleName.setBackground(validModuleName ? normalBackground : errorBackground); + + boolean validPluginName = bundles.containsKey(pluginName.getText()); + pluginName.setBackground(validPluginName ? normalBackground : errorBackground); + + getButton(IDialogConstants.OK_ID).setEnabled(validPackageName && validModuleName && validPackageName); + } + + private ModifyListener modifyListener = new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + validate(); + } + }; + + public void setPackage(String initialPackageName) { + this.initialPackageName = initialPackageName; + this.initialPluginName = CreateModuleAction.findBestPlugin(bundles, initialPackageName); + } + + @Override + protected void okPressed() { + try { + Bundle bundle = bundles.get(pluginName.getText()); + if(bundle != null) { + CreateModuleAction.createModule(bundle, packageName.getText(), moduleName.getText()); + parentBrowser.refresh(); + OpenSCLModule.openModule(packageName.getText() + "/" + moduleName.getText()); + } + } catch (IOException e) { + ErrorDialog.openError(getParentShell(), "Module creation failed", e.getMessage(), + new Status(Status.ERROR, "org.simantics.scl.ui", e.getMessage())); + } + super.okPressed(); + } +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleValidator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleValidator.java new file mode 100644 index 000000000..d3236c0dd --- /dev/null +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleValidator.java @@ -0,0 +1,28 @@ +package org.simantics.scl.ui.modulebrowser; + +public class CreateModuleValidator { + public static boolean isValidPackageName(String packageName) { + if(packageName.isEmpty()) + return true; + for(String part : packageName.split("/", -1)) + if(!isValidModuleName(part)) + return false; + return true; + } + + public static boolean isValidModuleName(String moduleName) { + if(moduleName.isEmpty()) + return false; + { + char c = moduleName.charAt(0); + if(!Character.isLetter(c)) + return false; + } + for(int i=1;i entries; + + public PluginSelectionDialog(Shell shell, Collection entries) { + super(shell, true); + this.entries = entries; + setListLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + Entry entry = (Entry)element; + if(entry == null) + return "NULL"; + return entry.bundle.getSymbolicName(); + } + }); + } + + @Override + protected Control createExtendedContentArea(Composite parent) { + return null; + } + + @Override + protected IDialogSettings getDialogSettings() { + IDialogSettings settings = org.simantics.scl.ui.Activator.getInstance() + .getDialogSettings().getSection(PLUGIN_SELECTION_DIALOG); + if (settings == null) + settings = Activator.getInstance() + .getDialogSettings().addNewSection(PLUGIN_SELECTION_DIALOG); + return settings; + } + + @Override + protected IStatus validateItem(Object item) { + return Status.OK_STATUS; + } + + @Override + protected ItemsFilter createFilter() { + return new ItemsFilter() { + { + String patternText = getPattern(); + patternMatcher = new SearchPattern(); + if(patternText != null && patternText.length() > 0) + patternMatcher.setPattern(patternText); + else + patternMatcher.setPattern("*"); + } + + @Override + public boolean matchItem(Object item) { + Entry entry = (Entry)item; + String name = entry.bundle.getSymbolicName(); + if(getPattern().indexOf('/') > 0) + return matches(name); + else { + for(String part : name.split("/")) + if(matches(part)) + return true; + return false; + } + } + + @Override + public boolean isConsistentItem(Object item) { + return true; + } + + }; + } + + Comparator comparator = new Comparator() { + @Override + public int compare(Entry o1, Entry o2) { + if(o1.packageMatchLength != o2.packageMatchLength) + return Integer.compare(o2.packageMatchLength, o1.packageMatchLength); + return o1.bundle.getSymbolicName().compareTo(o2.bundle.getSymbolicName()); + } + }; + + @SuppressWarnings("rawtypes") + @Override + protected Comparator getItemsComparator() { + return comparator; + } + + @Override + protected void fillContentProvider(final AbstractContentProvider contentProvider, + final ItemsFilter itemsFilter, IProgressMonitor progressMonitor) + throws CoreException { + for(Entry entry : entries) + contentProvider.add(entry, itemsFilter); + if(progressMonitor != null) + progressMonitor.done(); + } + + @Override + public String getElementName(Object item) { + Entry entry = (Entry)item; + return entry.bundle.getSymbolicName(); + } + +} diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/SCLModuleBrowser.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/SCLModuleBrowser.java index 5e08a55a4..b175a3e60 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/SCLModuleBrowser.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/SCLModuleBrowser.java @@ -1,13 +1,17 @@ package org.simantics.scl.ui.modulebrowser; import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.part.ViewPart; import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.ui.Activator; @@ -21,6 +25,8 @@ public class SCLModuleBrowser extends ViewPart { public void createPartControl(Composite parent) { this.content = new SCLModuleTree(parent, SWT.NONE, SCLOsgi.MODULE_REPOSITORY); setPartName("SCL Modules"); + + // Opening modules content.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { @@ -33,15 +39,41 @@ public class SCLModuleBrowser extends ViewPart { } }); + // Toolbar IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); toolBarManager.add(new Action("Refresh modules", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/arrow_refresh.png")) { @Override public void run() { - SCLOsgi.MODULE_REPOSITORY.getSourceRepository().checkUpdates(); - content.recalculateInput(); + refresh(); + } + }); + + // Context menu + MenuManager menuMgr = new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + ModuleNameTreeEntry entry = (ModuleNameTreeEntry)content.getStructuredSelection().getFirstElement(); + if(!entry.isModule) + manager.add(new Action("New Module...") { + @Override + public void run() { + CreateModuleDialog dialog = new CreateModuleDialog(content.getControl().getShell(), SCLModuleBrowser.this); + dialog.setPackage(entry.fullName); + dialog.open(); + } + }); } }); + Menu menu = menuMgr.createContextMenu(content.getControl()); + content.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, content); + } + + public void refresh() { + SCLOsgi.MODULE_REPOSITORY.getSourceRepository().checkUpdates(); + content.recalculateInput(); } @Override diff --git a/bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/Experiment.java b/bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/Experiment.java index 41125d0a0..827677451 100644 --- a/bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/Experiment.java +++ b/bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/Experiment.java @@ -81,6 +81,7 @@ public abstract class Experiment implements IExperiment { localStateChange(); for(IExperimentListener listener : listeners.getListeners()) listener.stateChanged(newState); + EXPERIMENT_STATE_READ.run(); } } diff --git a/bundles/org.simantics.spreadsheet.common/src/org/simantics/spreadsheet/common/TreeTableCell.java b/bundles/org.simantics.spreadsheet.common/src/org/simantics/spreadsheet/common/TreeTableCell.java index baf3b83de..299c7c796 100644 --- a/bundles/org.simantics.spreadsheet.common/src/org/simantics/spreadsheet/common/TreeTableCell.java +++ b/bundles/org.simantics.spreadsheet.common/src/org/simantics/spreadsheet/common/TreeTableCell.java @@ -36,6 +36,16 @@ public class TreeTableCell extends TableCell implements ITreeTableCell { this.data = data; } + @Override + public int getRowSpan() { + throw new IllegalStateException("Row span is not supported in TreeTableCell"); + } + + @Override + public int getColumnSpan() { + throw new IllegalStateException("Column span is not supported in TreeTableCell"); + } + public static TreeTableCell createTreeTableCell(String text, Object data, Object font, int parent, int row, int column, boolean editable) { return new TreeTableCell(text, data, extractIFont(font), parent, row, column, editable); } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java index e4f08db10..283e1b5dd 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java @@ -7,6 +7,7 @@ import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.ResourceRead2; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; @@ -62,8 +63,10 @@ abstract public class AbstractCompileStructuralValueRequest extends AbstractExpr Layer0 L0 = Layer0.getInstance(graph); String valueType = graph.getPossibleRelatedValue(relation, L0.RequiresValueType, Bindings.STRING); if(valueType != null) { + Resource relationIndexRoot = graph.syncRequest(new PossibleIndexRoot(relation)); + RuntimeEnvironment relationRuntimeEnvironment = relationIndexRoot != null ? graph.syncRequest(new RuntimeEnvironmentRequest(relationIndexRoot)) : context.runtimeEnvironment; try { - return Environments.getType(context.runtimeEnvironment.getEnvironment(), valueType); + return Environments.getType(relationRuntimeEnvironment.getEnvironment(), valueType); } catch (SCLExpressionCompilationException e) { e.printStackTrace(); } diff --git a/bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph b/bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph index a0e60d0b3..bcae4c480 100644 --- a/bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph +++ b/bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph @@ -57,6 +57,8 @@ ACTIONS.NewSTSTest @MOD.sclAction "createSTSTestAction" ACTIONS.RunSTSTest @MOD.sclAction "runSTSTestAction" +ACTIONS.IgnoreSTSTest + @MOD.sclAction "ignoreSTSTestAction" ACTIONS.NewSTSVariable @MOD.sclAction "createSTSVariableAction" @@ -82,6 +84,13 @@ MAC VP.ActionContribution.HasNodeType TESTS.STSSuite VP.ActionContribution.HasNodeType TESTS.STSTest VP.ActionContribution.HasAction ACTIONS.RunSTSTest + VP.BrowseContext.HasActionContribution _ : VP.ActionContribution + L0.HasLabel "Ignore" + VP.ActionContribution.HasImage SILK.control_play + VP.ActionContribution.HasCategory VP.EditActionCategory + VP.ActionContribution.HasNodeType TESTS.STSSuite + VP.ActionContribution.HasNodeType TESTS.STSTest + VP.ActionContribution.HasAction ACTIONS.IgnoreSTSTest VP.BrowseContext.HasActionContribution _ : VP.ActionContribution L0.HasLabel "STS Variable" VP.ActionContribution.HasImage SILK.page_white_edit diff --git a/bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl b/bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl index 53218224a..0b99fe784 100644 --- a/bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl +++ b/bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl @@ -7,6 +7,7 @@ createSTSTestAction res = do importJava "org.simantics.tests.modelled.ui.TestsUIUtils" where runSTSTestAction :: Resource -> () + ignoreSTSTestAction :: [Resource] -> () createSTSSuiteAction :: Resource -> () createSTSSuiteAction res = do diff --git a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java index 651ee47df..b24f445e2 100644 --- a/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java +++ b/bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java @@ -1,10 +1,16 @@ package org.simantics.tests.modelled.ui; import java.io.IOException; +import java.util.List; import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Write; +import org.simantics.tests.modelled.ontology.TestsResource; import org.simantics.ui.workbench.e4.E4WorkbenchUtils; public class TestsUIUtils { @@ -20,4 +26,17 @@ public class TestsUIUtils { view.currentTest(test); view.execute(); } + + public static void ignoreSTSTestAction(List tests) throws DatabaseException { + Simantics.getSession().syncRequest(new Write() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + TestsResource TESTS = TestsResource.getInstance(graph); + for (Resource test : tests) { + graph.claimLiteral(test, TESTS.ignore, true, Bindings.BOOLEAN); + } + } + }); + } } diff --git a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java index e1eb08baf..78964403f 100644 --- a/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java +++ b/bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java @@ -11,9 +11,9 @@ import java.util.Set; import org.simantics.scl.compiler.commands.CommandSession; import org.simantics.scl.compiler.commands.TestScriptExecutor; +import org.simantics.scl.compiler.elaboration.java.Builtins; +import org.simantics.scl.compiler.elaboration.java.JavaModule; import org.simantics.scl.compiler.module.coverage.CombinedCoverage; -import org.simantics.scl.compiler.module.options.ModuleCompilationOptions; -import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor; import org.simantics.scl.compiler.module.repository.ModuleRepository; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; @@ -99,7 +99,8 @@ public class ModelledSTSTest { } public List run(List vars) throws IOException { - ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY); +// ModuleRepository repo = new ModuleRepository(SCLOsgi.SOURCE_REPOSITORY); + ModuleRepository repo = SCLOsgi.MODULE_REPOSITORY; CommandSession session = null; try { // repo.setAdvisor(new ModuleCompilationOptionsAdvisor() { @@ -116,7 +117,7 @@ public class ModelledSTSTest { // // } // // } // return new ModuleCompilationOptions(coverage); -// } + // } // }); SCLReportingHandler handler = (SCLReportingHandler) SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER); @@ -139,7 +140,9 @@ public class ModelledSTSTest { return result; } finally { // remember to flush this repository - repo.flush(); +// repo.flush(); + Builtins.flush(); + JavaModule.flush(); } } diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4WorkbenchUtils.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4WorkbenchUtils.java index 3c1888a01..6d7daeb3c 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4WorkbenchUtils.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4WorkbenchUtils.java @@ -5,6 +5,7 @@ import java.util.Map; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.commands.MCommand; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.advanced.MArea; import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; @@ -14,9 +15,12 @@ import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; +import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor; import org.simantics.db.Resource; import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.workbench.WorkbenchUtils; /** * @author Tuukka Lehtonen @@ -166,5 +170,32 @@ public class E4WorkbenchUtils { part = partService.createPart(partId); return part; } + + public static MCommand getMCommandById(String id) { + IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class); + MApplication application = context.get(MApplication.class); + for (MCommand command : application.getCommands()) { + if (id.equals(command.getElementId())) { + return command; + } + } + return null; + } + @SuppressWarnings("restriction") + public static IEditorPart getActiveIEditorPart(MPart mActiveEditorPart) { + // TODO: Fix this when we get rid of CompatibilityEditors + IEditorPart activeEditor = null; + if (mActiveEditorPart != null) { + Object editor = mActiveEditorPart.getObject(); + if (editor instanceof CompatibilityEditor) { + CompatibilityEditor compEditor = (CompatibilityEditor) editor; + activeEditor = compEditor.getEditor(); + } else { + // TODO: This is not good practice with E4 but an OK fallback for now + activeEditor = WorkbenchUtils.getActiveEditor(); + } + } + return activeEditor; + } } diff --git a/bundles/org.simantics.viewpoint.ontology/graph/ViewpointTests.pgraph b/bundles/org.simantics.viewpoint.ontology/graph/ViewpointTests.pgraph index 1eb13238f..4f297e417 100644 --- a/bundles/org.simantics.viewpoint.ontology/graph/ViewpointTests.pgraph +++ b/bundles/org.simantics.viewpoint.ontology/graph/ViewpointTests.pgraph @@ -35,3 +35,9 @@ VP.InstanceOfTest + + + + diff --git a/features/org.simantics.sdk.feature/feature.xml b/features/org.simantics.sdk.feature/feature.xml index 5ba353170..4cf211443 100644 --- a/features/org.simantics.sdk.feature/feature.xml +++ b/features/org.simantics.sdk.feature/feature.xml @@ -13,7 +13,7 @@ diff --git a/releng/doc/release.html b/releng/doc/release.html index 17c7d28f4..aaccfc915 100644 --- a/releng/doc/release.html +++ b/releng/doc/release.html @@ -332,7 +332,7 @@ img {
  • Simantics R - simantics/r.git
  • FMIL - simantics/fmil.git
  • FMI Studio - members/fmi.git
  • -
  • Simupedia - Members SVN
  • +
  • Simupedia - members/simupedia.git
  • For simplicity, each of these components are versioned accoring to platform versioning, i.e. for Platform SDK 1.26.0 there will be Simantics Desktop 1.26.0, Sysdyn 1.26.0, and so on.


    @@ -478,7 +478,7 @@ refs #yyyy

    Tag release/* branches

    When the release branches are ready for the release, tag them with the tag vx.y.z[.w]:

    git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git
    -cd platform    
    +cd platform
     git checkout release/x.y.z[.w]
     git tag vx.y.z[.w] -m "Simantics x.y.z[.w] simultaneous release"
     git push origin --tags
    @@ -556,15 +556,15 @@ separate Mediawiki installation.

    Disseminate information about the release

    Newsletter template:

    Hello everyone,
    -   
    +
     Simantics release x.y.z[.w] has been released. Head over to
     https://www.simantics.org/redmine/news/<news number>
     for the release news.
    @@ -583,6 +583,9 @@ Insert some general thoughts on the release...
     

    TODO

    +
    • Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release
      • Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio
      • @@ -590,12 +593,7 @@ Insert some general thoughts on the release...
        -
      • -

        Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK

        -
      • -
      • -

        Start using https://github.com/mbarbero/fr.obeo.releng.targetplatform to generate .target files. .tpd files allow specifying version ranges instead of specific versions.

        -
      • +
      • Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK
      diff --git a/releng/doc/release.md b/releng/doc/release.md index 79359efd2..871b1d0aa 100644 --- a/releng/doc/release.md +++ b/releng/doc/release.md @@ -36,7 +36,7 @@ Plug-in components that are part of the release train: * Simantics R - [simantics/r.git](https://www.simantics.org:8088/r/gitweb?p=simantics/r.git;a=summary) * FMIL - [simantics/fmil.git](https://www.simantics.org:8088/r/gitweb?p=simantics/fmil.git;a=summary) * FMI Studio - [members/fmi.git](https://www.simantics.org:8088/r/gitweb?p=members/fmi.git;a=summary) -* Simupedia - [Members SVN](https://www.simantics.org/svn/members/simupedia) +* Simupedia - [members/simupedia.git](https://www.simantics.org:8088/r/gitweb?p=members/simupedia.git;a=summary) For simplicity, each of these components are versioned accoring to platform versioning, i.e. for Platform SDK 1.26.0 there will be Simantics Desktop 1.26.0, Sysdyn 1.26.0, and so on. @@ -246,8 +246,8 @@ separate Mediawiki installation. ## Disseminate information about the release -* [Developer Wiki](http://dev.simantics.org): Update roadmap at http://dev.simantics.org/index.php/Roadmap -* [Redmine](https://www.simantics.org/redmine/): Post news on the developer/user-visible changes here. +* [Developer Wiki](http://dev.simantics.org): Update roadmap at [http://dev.simantics.org/index.php/Roadmap](http://dev.simantics.org/index.php/Roadmap) +* [Redmine](https://www.simantics.org/redmine/): Post news on the developer/user-visible changes here * [simantics.org](https://www.simantics.org): Post news on the release and a link to the redmine post * [Members Wiki](https://www.simantics.org/members/): Update frame plan to reflect the realized dates and link to Redmine news * [mailto:simantics-developers@simantics.org](mailto:simantics-developers@simantics.org) Send "newsletter" to `simantics-developers@simantics.org: @@ -278,11 +278,11 @@ Insert some general thoughts on the release... # TODO -* Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release - * Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio +* Start using [https://github.com/mbarbero/fr.obeo.releng.targetplatform](https://github.com/mbarbero/fr.obeo.releng.targetplatform) to generate `.target` files. `.tpd` files allow specifying version ranges instead of specific versions. -* Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK +* Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release + * Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio -* Start using https://github.com/mbarbero/fr.obeo.releng.targetplatform to generate `.target` files. `.tpd` files allow specifying version ranges instead of specific versions. +* Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK \ No newline at end of file diff --git a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target index 888bb1e27..d99e6fd4f 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target +++ b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target @@ -147,6 +147,8 @@ + + diff --git a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd index a3cefa4bb..1fc2f710c 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd +++ b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd @@ -148,6 +148,8 @@ location "http://www.simantics.org/download/private/eclipse-4.7/external-compone com.fasterxml.jackson.core.jackson-annotations.source com.fasterxml.jackson.core.jackson-core com.fasterxml.jackson.core.jackson-core.source + com.fasterxml.jackson.core.jackson-databind + com.fasterxml.jackson.core.jackson-databind.source com.fasterxml.jackson.dataformat.jackson-dataformat-csv com.fasterxml.jackson.dataformat.jackson-dataformat-csv.source com.fasterxml.jackson.dataformat.jackson-dataformat-xml diff --git a/releng/org.simantics.sdk.build.targetdefinition/simantics.target b/releng/org.simantics.sdk.build.targetdefinition/simantics.target index 356d4c2c3..9290a8b82 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/simantics.target +++ b/releng/org.simantics.sdk.build.targetdefinition/simantics.target @@ -1,4 +1,4 @@ - + @@ -149,6 +149,8 @@ + + @@ -303,8 +305,8 @@ - - + + diff --git a/releng/org.simantics.sdk.repository/pom.xml b/releng/org.simantics.sdk.repository/pom.xml index a72cb5e12..683a1e580 100644 --- a/releng/org.simantics.sdk.repository/pom.xml +++ b/releng/org.simantics.sdk.repository/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.simantics.sdk.repository - 1.30.0-SNAPSHOT + 1.31.0-SNAPSHOT eclipse-repository diff --git a/sonar-simantics-platform-sdk.properties b/sonar-simantics-platform-sdk.properties index d92944975..29d0e5533 100644 --- a/sonar-simantics-platform-sdk.properties +++ b/sonar-simantics-platform-sdk.properties @@ -1,7 +1,7 @@ # required metadata sonar.projectKey=simantics-platform-sdk sonar.projectName=Simantics Platform SDK -sonar.projectVersion=1.25 +sonar.projectVersion=1.30 # path to source directories (required) sonar.sources=bundles @@ -20,4 +20,4 @@ sonar.sources=bundles #sonar.language=cobol # Additional parameters -#sonar.my.property=value \ No newline at end of file +#sonar.my.property=value diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakTest.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakExperiment.java similarity index 98% rename from tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakTest.java rename to tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakExperiment.java index 7ff61a83e..76cd51e90 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakTest.java +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakExperiment.java @@ -14,7 +14,7 @@ import org.simantics.scl.compiler.top.SCLExpressionCompilationException; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; -public class MemoryLeakTest { +public class MemoryLeakExperiment { ModuleRepository moduleRepository; EnvironmentSpecification environmentSpecification; diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java index a5975932b..cf3aa021b 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java @@ -32,6 +32,12 @@ public class ModuleRegressionTests extends TestBase { @Test public void CHR8() { test(); } @Test public void CHR9() { test(); } @Test public void CHR10() { test(); } + @Test public void CHR11() { test(); } + @Test public void CHR12() { test(); } + @Test public void CHR13() { test(); } + @Test public void CHRSelect1() { test(); } + @Test public void CHRSelect2() { test(); } + @Test public void CHRSelect3() { test(); } @Test public void ClosureRecursion() { test(); } @Test public void Collaz() { test(); } @Test public void Compose() { test(); } @@ -45,7 +51,8 @@ public class ModuleRegressionTests extends TestBase { @Test public void DifferentBranchTypes() { test(); } @Test public void Div() { test(); } @Test public void DoubleConversion() { test(); } - @Test public void DoubleEffect() { test(); } + @Test public void DoubleEffect() { test(); } + @Test public void Dynamic1() { test(); } @Test public void Effects1() { test(); } @Test public void Effects2() { test(); } @Test public void Effects3() { test(); } @@ -201,13 +208,14 @@ public class ModuleRegressionTests extends TestBase { @Test public void Record1() { test(); } @Test public void Record2() { test(); } @Test public void RecordShorthand() { test(); } + @Test public void RecursionBug() { test(); } @Test public void RecursiveContext() { test(); } @Test public void RecursiveValues2() { test(); } @Test public void RecursiveValues3() { test(); } @Test public void RecursiveValues4() { test(); } @Test public void RedBlackTrees() { test(); } @Test public void Relations1() { test(); } - @Test public void Relations2() { test(); } + @Test public void Relations2() { test(); } @Test public void RepeatedVariableInPattern() { test(); } @Test public void Scanl() { test(); } @Test public void Search() { test(); } diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java new file mode 100644 index 000000000..9e8c14ecb --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java @@ -0,0 +1,31 @@ +package org.simantics.scl.compiler.tests; + +import java.io.StringReader; +import java.io.StringWriter; + +import org.junit.Assert; +import org.junit.Test; +import org.simantics.scl.compiler.commands.CommandSessionWithModules; +import org.simantics.scl.osgi.SCLOsgi; + +public class TestCommandSessionWithModules { + @Test + public void testCommandSessionWithModules() { + CommandSessionWithModules session = new CommandSessionWithModules(SCLOsgi.MODULE_REPOSITORY); + session.putModule("My/Test/Module", "someValue = 13"); + + { + StringWriter writer = new StringWriter(); + session.runCommands(new StringReader("import \"My/Test/Module\"\nsomeValue"), writer); + Assert.assertEquals("13\n", writer.toString()); + } + + session.putModule("My/Test/Module", "someValue = 14"); + + { + StringWriter writer = new StringWriter(); + session.runCommands(new StringReader("someValue\nsomeValue+1"), writer); + Assert.assertEquals("14\n15\n", writer.toString()); + } + } +} diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java index ff0c799ed..7644afe05 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java @@ -7,6 +7,7 @@ import java.io.StringReader; import java.nio.charset.Charset; import org.junit.Test; +import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext; import org.simantics.scl.compiler.markdown.internal.MarkdownParser; import org.simantics.scl.compiler.markdown.nodes.Node; @@ -77,10 +78,12 @@ public class MarkdownTests { } public static int test(int id, String in, String out) throws IOException { + if(in.contains("\u2192")) + return SKIPPED; MarkdownParser parser = new MarkdownParser(); Node node = parser.parseDocument(new StringReader(in.replace('\u2192', '\t'))); - String result = node.toHtml().replace('\t', '\u2192'); + String result = node.toHtml(HtmlGenerationContext.TEST_DEFAULT).replace('\t', '\u2192'); boolean passed = result.equals(out); diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR11.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR11.scl new file mode 100644 index 000000000..3ba991ef5 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR11.scl @@ -0,0 +1,26 @@ +module { export = [main], features = [chr] } +import "Prelude" + +ruleset Foo where + constraint Foo Integer + +main = () + where + foo = createFoo + include Foo foo + + when Foo ?x + then print ?x + + when True + then Foo 2 + + when Foo ?x + ?x < 5 + then Foo (?x + 1) +-- +2 +3 +4 +5 +() \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR12.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR12.scl new file mode 100644 index 000000000..7c9376d78 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR12.scl @@ -0,0 +1,15 @@ +module { export = [main], features = [chr] } +import "Prelude" + +main = () + where + when Foo ?x ?x + then print (?x :: Integer) + + when True + then Foo 1 2 + Foo 2 1 + Foo 2 2 +-- +2 +() \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR13.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR13.scl new file mode 100644 index 000000000..597c0016e --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR13.scl @@ -0,0 +1,16 @@ +module { export = [main], features = [chr] } +import "Prelude" + +main = () + where + when Foo ?x + then y = ?x + 1 :: Integer + print y + + when True + then Foo 1 + Foo 2 +-- +3 +2 +() \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl index 1d8451439..98c3a4338 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl @@ -6,5 +6,4 @@ main = () A ?x, not A (?x+1) => A (?x-1) True => A 0 -- -0 -() \ No newline at end of file +6:11-6:23: CHR negation is not yet supported. \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect1.scl new file mode 100644 index 000000000..63ea561b2 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect1.scl @@ -0,0 +1,10 @@ +module { + features = [chr] +} +import "StandardLibrary" + +main = select (?a,?b) where + ?a <- [1,2,3] + ?b <- [2,3,4] +-- +[(1,2), (1,3), (1,4), (2,2), (2,3), (2,4), (3,2), (3,3), (3,4)] \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect2.scl new file mode 100644 index 000000000..e49dd44b4 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect2.scl @@ -0,0 +1,17 @@ +module { + features = [chr] +} +import "StandardLibrary" + +main = + select (?a,?b) where + Foo ?a + Bar ?b + where + True => Foo 1 + True => Foo 2 + + True => Bar 3 + True => Bar 4 +-- +[(2,4), (2,3), (1,4), (1,3)] \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect3.scl new file mode 100644 index 000000000..2be9b98c5 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect3.scl @@ -0,0 +1,21 @@ +module { + features = [chr] +} +import "StandardLibrary" + +main = () + where + constraint Edge Integer Integer + + True => Edge 2 3 + True => Edge 1 2 + True => Edge 3 4 + + when -Edge ?x ?y + [] = select ?z where + Edge ?z ?x + then print "removed \(?x) \(?y)" +-- +removed 1 2 +removed 2 3 +() \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Dynamic1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Dynamic1.scl new file mode 100644 index 000000000..ca32ea4a2 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Dynamic1.scl @@ -0,0 +1,13 @@ +import "Prelude" + +myShow :: Dynamic -> String +myShow (Dynamic v) = show (v :: Integer) +myShow (Dynamic v) = show (v :: Double) +myShow (Dynamic v) = show (v :: String) +myShow (Dynamic v) = show (v :: Boolean) +myShow (Dynamic v) = "[\(intercalate ", " $ map myShow v)]" +myShow _ = "Unknown" + +main = myShow $ Dynamic [Dynamic False, Dynamic (3 :: Integer), Dynamic (3.1 :: Double), Dynamic "Foo"] +-- +[False, 3, 3.1, "Foo"] \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl index 95d8b03da..3cf6ed74b 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl @@ -1,4 +1,4 @@ main = \ /* no parameters */ -> 3 -- -2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION. \ No newline at end of file +2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, CHR_SELECT, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION. \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursionBug.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursionBug.scl new file mode 100644 index 000000000..3a6ab2482 --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursionBug.scl @@ -0,0 +1,16 @@ +module { + export = [main] +} + +import "Prelude" + +data Path = EmptyPath | ConsPath String Path + +showR :: Path -> String +showR EmptyPath = "@" +showR (ConsPath h EmptyPath) = h +showR (ConsPath h t) = "\(h)-\(showR t)" + +main = "Hello world!" +-- +Hello world! \ No newline at end of file diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl index 85637b16b..45f6b0853 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl @@ -1,4 +1,4 @@ a = = b = 4 -- -1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION. \ No newline at end of file +1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, CHR_SELECT, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION. \ No newline at end of file