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;
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();
}
}
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();
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();
class="org.simantics.browsing.ui.model.tests.FailTest"
constructor="get">
</type>
+ <type uri="http://www.simantics.org/Viewpoint-0.0/HasURITest"
+ class="org.simantics.browsing.ui.model.tests.HasURITest"
+ constructor="get">
+ </type>
+ <type uri="http://www.simantics.org/Viewpoint-0.0/InDevelopmentModeTest"
+ class="org.simantics.browsing.ui.model.tests.InDevelopmentModeTest"
+ constructor="get">
+ </type>
</target>
<target interface="org.simantics.browsing.ui.model.actions.IActionCategory">
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+
+}
import org.simantics.layer0.Layer0;
public class DescriptionTooltipRule implements TooltipRule {
-
+
public static final DescriptionTooltipRule INSTANCE = new DescriptionTooltipRule();
-
+
public DescriptionTooltipRule() {
}
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<Object, Object> auxiliary) throws DatabaseException {
+ public boolean shouldCreateToolTip(ReadGraph graph, NodeContext context, Map<Object, Object> auxiliary) throws DatabaseException {
String content = getToolTipContent(graph, context);
if (content == null || content.isEmpty())
return false;
WriteGraph g, Layer0 L0, Resource list,
Resource before, Resource after,
Iterable<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);
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);
}
public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
+ createExisting(g, list, false, elements);
+ }
+
+ public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable<Resource> 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);
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;
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;
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;
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;
}
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);
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);
+ }
+
}
}
@Override
- public void finished(AsyncReadGraph graph) {
- user.finished(graph);
+ public void finished(AsyncReadGraph graph, C context) {
+ user.finished(graph, context);
}
@Override
public List<Resource> 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.<Function>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.<Function>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<Resource> results = (List<Resource>)dependencyResources.apply(graph, parameter, filter);
+ List<Resource> results = (List<Resource>)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<Resource> resultSet = new TreeSet<Resource>();
-// for (Map<String, Object> 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<Resource> 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<Resource> result = coll.createList();
-
- for (Resource res : Layer0Utils.sortByCluster(graph, results)) {
+ List<Resource> 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;
}
@Override
- public void finished(AsyncReadGraph graph) {
+ public void finished(AsyncReadGraph graph, Resource parent) {
}
@Override
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
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<InternalEntry> result;
+ final Set<Resource> childrenWithNoName;
final AsyncContextMultiProcedure<InternalEntry, Resource> structure;
final AsyncContextMultiProcedure<InternalEntry, Resource> names;
- public static List<InternalEntry> walk(ReadGraph graph, ResourceMap<ExtentStatus> status, Collection<Resource> resources, Set<Resource> exclusions, boolean ignoreVirtual) throws DatabaseException {
+ public static Pair<List<InternalEntry>,Set<Resource>> walk(ReadGraph graph, ResourceMap<ExtentStatus> status, Collection<Resource> resources, Set<Resource> 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;
final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
result = new ArrayList<InternalEntry>();
-
+ childrenWithNoName = new HashSet<>();
names = dqs.compileForEachObject(graph, L0.HasName, new AsyncContextMultiProcedure<InternalEntry, Resource>() {
@Override
graph.forPossibleValue(nameResource, new Procedure<String>() {
@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
}
@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<InternalEntry, Resource>() {
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
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;
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<List<InternalEntry>,Set<Resource>> pair = ConsistsOfProcess.walk(graph, status, fringe, exclusions, ignoreVirtual);
+ state.internalEntries = pair.first;
for(InternalEntry entry : state.internalEntries) {
Resource r = entry.resource;
}
}
+ for(Resource unnamedChild : pair.second) {
+ if (status.put(unnamedChild, ExtentStatus.INTERNAL) == null) {
+ fringe.add(unnamedChild);
+ }
+ }
+
if (state.monitor.isCanceled())
throw new CancelTransactionException();
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);
}
* � All o are internal
* � All stm are included
*/
- List<InternalEntry> entries = ConsistsOfProcess.walk(graph, null, fringe, exclusions, true);
+ Pair<List<InternalEntry>,Set<Resource>> pair = ConsistsOfProcess.walk(graph, null, fringe, exclusions, true);
+ List<InternalEntry> entries = pair.first;
for(InternalEntry entry : entries) {
Resource r = entry.resource;
if (status.put(r, ExtentStatus.INTERNAL) == null) {
}
}
+ 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.
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;
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
return new GUIDExclusionFunction(graph);
// The root is OK - check everything beneath
- List<InternalEntry> entries = ConsistsOfProcess.walk(graph, null, Collections.singleton(r), Collections.emptySet(), true);
+ Pair<List<InternalEntry>,Set<Resource>> pair = ConsistsOfProcess.walk(graph, null, Collections.singleton(r), Collections.emptySet(), true);
+ List<InternalEntry> entries = pair.first;
for(InternalEntry entry : entries) {
if(findByIdentifier(graph, targetRoot, entry.resource))
return new GUIDExclusionFunction(graph);
if(Variables.TYPE.equals(key)) return getTypeVariable();
else if(Variables.URI.equals(key)) return getURIVariable();
- return variable;
+ return null;
}
}
}
}
}
- 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) {
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) {
this.backend = new TIntArrayList();
}
+ ResourceList(SessionImplSocket session, int capacity) {
+ this.session = session;
+ this.backend = new TIntArrayList(capacity);
+ }
+
ResourceList(SessionImplSocket session, Collection<Resource> rs) {
this.session = session;
this.backend = new TIntArrayList(rs.size());
return new ResourceList(session);
}
+ @Override
+ public List<Resource> createList(int capacity) {
+ return new ResourceList(session, capacity);
+ }
+
static final class StatementList implements Collection<Statement> {
final private SessionImplSocket session;
}
}
- procedure.finished(graph);
+ procedure.finished(graph, context);
// graph.dec();
return;
}
- procedure.finished(graph);
+ procedure.finished(graph, context);
// graph.dec();
assert(size == count);
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;
}
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
}
} 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
}
}
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
}
// 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);
}
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
}
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;
}
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
}
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
}
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);
}
}
- procedure.finished(graph);
+ procedure.finished(graph, context);
// graph.state.dec(0);
}
*
* @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
Set<Resource> createSet();
Set<Resource> createSet(int capacity);
List<Resource> createList();
+ List<Resource> createList(int capacity);
List<Resource> asSortedList(Collection<Resource> set);
void sort(List<Resource> list);
Collection<Statement> createStatementList();
*******************************************************************************/
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;
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;
}
@Override
- public void execute(AsyncReadGraph graph, final ElementClass clazz) {
-
+ public void execute(AsyncReadGraph graph, ElementClass mutableClazz) {
+ List<SubstituteElementClass> 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<IElement>() {
@Override
graph.forHasStatement(element, gl.getVisible(), element, new AsyncProcedureAdapter<Boolean>() {
@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() + "'");
graph.forHasStatement(element, gl.getFocusable(), element, new AsyncProcedureAdapter<Boolean>() {
@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() + "'");
RELATIONS.commandExecutorRelation <T STR.ConnectionRelation
@L0.assert STR.AllowsConnectionType DOC.CommandConnectionType
@L0.assert MOD.ConnectionRelationToTerminal DOC.Terminals.CommandExecutorTerminal
- @L0.assert STR.HasAttachmentRelation DIA.HasPlainConnector
+ @L0.assert STR.HasAttachmentRelation DIA.HasArrowConnector
>-- RELATIONS.commandExecutorRelation.propagate --> "Boolean" <R L0.HasProperty : L0.FunctionalRelation
@L0.assert RELATIONS.commandExecutorRelation.propagate false
RELATIONS.commandRelation <T L0.FunctionalRelation <T STR.ConnectionRelation
@L0.assert STR.AllowsConnectionType DOC.CommandConnectionType
@L0.assert MOD.ConnectionRelationToTerminal DOC.Terminals.CommandTerminal
- @L0.assert STR.HasAttachmentRelation DIA.HasArrowConnector
+ @L0.assert STR.HasAttachmentRelation DIA.HasPlainConnector
RELATIONS.click : RELATIONS.commandRelation
@defCommandConnectionPoint "1"
Bundle-ManifestVersion: 2
Bundle-Name: Document Server I/O interface
Bundle-SymbolicName: org.simantics.document.server.io
-Bundle-Version: 0.0.1.qualifier
+Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.simantics.document.server.io.Activator
Bundle-Vendor: Semantum Oy
Require-Bundle: org.eclipse.core.runtime
if (context != null) {
Map<String,List<List<Object>>> from = context.getData();
for (Map.Entry<String, List<List<Object>>> 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<List<Object>> rows = ensureRowsAvailable(entry.getKey());
rows.addAll(entry.getValue());
}
package org.simantics.document.server.io;
public interface ITreeTableCell extends ITableCell {
-
- int getParent();
-
- Object getData();
- boolean isEditable();
+ int getParent();
+ Object getData();
+ boolean isEditable();
}
return Collections.emptyList();
}
+ @SuppressWarnings("unchecked")
+ public static Collection<ITreeTableCell> 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<ITreeTableCell>) tableCells;
+ } else {
+ return Collections.emptyList();
+ }
+ } catch (ClassCastException e) {
+ e.printStackTrace();
+ }
+ return Collections.emptyList();
+ }
+
public static Collection<FileInfo> getFiles(IJSONObject object) {
try {
@SuppressWarnings("unchecked")
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;
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<String, Exception> exceptions = (Map<String, Exception>)DocumentServerUtils.getValue(graph, attrib);
+
+ List<String> errorList = object.getJSONField(NodeRequest.ERRORS);
+ if(errorList == null)
+ errorList = new ArrayList<String>();
+
+ for (Map.Entry<String, Exception> 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<String> errorList = object.getJSONField(NodeRequest.ERRORS);
if(errorList == null)
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;
@SCLValue(type = "VariableMap")
public static VariableMap primitiveProperties = new VariableMapImpl() {
+ private void storePropertyValueAndExceptions(ReadGraph graph, Variable parent, String name, Variable property, Map<String, Variable> 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<String, Exception> exceptionMap;
+ if (propertyExceptions == null) {
+ exceptionMap = new TreeMap<String, Exception>();
+ 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);
@Override
public Map<String, Variable> getVariables(final ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+ if(map == null) map = new HashMap<String,Variable>();
+
Variable parent = context.getParent(graph);
DocumentationResource DOC = DocumentationResource.getInstance(graph);
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;
}
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<String,Variable>();
- 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<String,Variable>();
- 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<String,Variable>();
- 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;
}
public class NodeRequest extends VariableRead<JSONObject> {
public static final String ERRORS = "Errors";
-
+ public static final String PROPERTY_VALUE_EXCEPTIONS = "_PropertyValueExceptions";
+
public NodeRequest(Variable node) {
super(node);
}
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) {
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<SelectionSpecification> ss = e.getElementClass().getItemsByClass(SelectionSpecification.class);
if (!ss.isEmpty()) {
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;
public Node init(G2DParentNode parent) {
ImageNode node = parent.getOrCreateNode("image", ImageNode.class);
node.setImage(bi);
+ node.setAlpha(alpha);
+ node.setZIndex(-100);
return node;
}
@SGInit
public void initSG(G2DParentNode parent) {
- node = parent.addNode("ruler", RulerNode.class);
+ node = parent.addNode("ruler", getNodeClass());
node.setZIndex(PAINT_PRIORITY);
updateNode();
}
+ protected Class<? extends RulerNode> getNodeClass() {
+ return RulerNode.class;
+ }
+
@SGCleanup
public void cleanupSG() {
node.remove();
}
- void updateNode() {
+ protected void updateNode() {
node.setEnabled(isPaintingEnabled());
node.setGridSize(getGridSize());
}
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;
private boolean ignoreIdentifiers;
+ private TransferableGraphQueries query;
+
static class ResourceInfo {
final boolean hasURI;
String name;
}
}
- 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<String, ResourceInfo> orderedInfos = new TreeMap<>();
TIntObjectHashMap<ResourceInfo> 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<String, ResourceInfo> 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<String, TreeSet<Integer>> sortByPredicateUniqueStatements(TransferableGraph1 graph, int resource) {
+ /**
+ * Sorts statements by predicateURI in natural order
+ *
+ * @param graph
+ * @param resource
+ * @return
+ */
+ private TreeMap<String, TreeSet<Integer>> sortByPredicateUniqueStatements(int resource) {
TreeMap<String, TreeSet<Integer>> 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<Integer> objects = results.get(predicateURI);
if (objects == null) {
objects = new TreeSet<>();
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<statements.size();i+=2) {
- for (TreeSet<Integer> objects : sortByPredicateUniqueStatements(graph, resource).values()) {
+ for (TreeSet<Integer> 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);
+ }
}
}
}
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);
// 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")) {
}
}
- 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 = "\"" +
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;
// }
}
- 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)
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;
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);
}
return ((predicate & 0xffffffffL) << 32) | (object & 0xffffffffL);
}
- private void addInlineStatement(TransferableGraph1 graph, Map<String, Set<String>> statements, String predicate,
+ private void addInlineStatement(Map<String, Set<String>> statements, String predicate,
ResourceInfo objectInfo, int indent) {
Set<String> 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;
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;
return null;
Map<String, Set<String>> 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();
processed.add(stmId);
}
- TreeMap<String, Integer> predicateURIs = new TreeMap<>();
+ TreeMap<String, List<Integer>> 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);
// indent++;
// }
}
- String predicateURI = rewritePredicateURI(graph, predicate);
- predicateURIs.put(predicateURI, object);
+ String predicateURI = rewritePredicateURI(predicate);
+ List<Integer> objects = predicateURIs.get(predicateURI);
+ if (objects == null) {
+ objects = new ArrayList<>();
+ predicateURIs.put(predicateURI, objects);
+ }
+ objects.add(object);
}
- for (Entry<String, Integer> entry : predicateURIs.entrySet()) {
+ for (Entry<String, List<Integer>> 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<Integer> 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);
}
}
}
}
- TreeMap<String, Integer> ownedOrdered = new TreeMap<>();
+ TreeMap<String, Set<Integer>> 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<Integer> 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<String, Integer> entry : ownedOrdered.entrySet()) {
+ for (Entry<String, Set<Integer>> 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<Integer> 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<String, String> knownOntologies = new HashMap<>();
static {
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) {
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);
} 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)) {
}
}
}
- }
+ return true;
+ });
// Discover other resources
log("Discovering other resources..");
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);
@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);
}
}
}
}
- 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;
}
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<String> 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 {
} 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 {
}
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;
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);
}
}
for (ResourceInfo info : infos.valueCollection()) {
if (info.name.startsWith("blank")) {
- info.name = "blank" + findHash(graph, info);
+ info.name = "blank" + findHash(info);
}
}
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);
}
// 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);
}
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);
}
}
- private String calculateHash(TransferableGraph1 graph, ResourceInfo info) {
+ private String calculateHash(ResourceInfo info) {
StringBuilder statementHash = new StringBuilder();
TreeSet<String> parts = new TreeSet<>();
for (int i = 0; i < info.owned.size(); i += 2) {
// 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 + ";;;");
}
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);
}
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: <input .sharedOntology file> [<output .tg file>]");
- } 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();
}
}
--- /dev/null
+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<Identity> internalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+ private final TIntObjectHashMap<Identity> externalIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+ private final TIntObjectHashMap<Identity> rootIdentities = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, NOT_FOUND);
+
+ private final TObjectIntHashMap<String> internalIdentitiesByURI = new TObjectIntHashMap<>();
+ private final TObjectIntHashMap<String> externalIdentitiesByURI = new TObjectIntHashMap<>();
+ private final TObjectIntHashMap<String> rootIdentitiesByURI = new TObjectIntHashMap<>();
+
+ private final TIntObjectHashMap<TIntArrayList> 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 "<internal reference " + id + ">:";
+ return getURI(identity);
+ }
+
+ private static final Comparator<Identity> IDENTITY_NAME_COMPARATOR = new Comparator<Identity>() {
+
+ @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<Identity> getChildren(Identity parent) {
+ TreeSet<Identity> 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<Identity> 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<String, TreeSet<Integer>> sortByPredicateUniqueStatements(int resource) {
+ TreeMap<String, TreeSet<Integer>> 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<Integer> 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;
+ }
+
+}
public class TransferableGraphUtils {
- public static Collection<Identity> getRoots(TransferableGraph1 tg) {
-
- ArrayList<Identity> result = new ArrayList<Identity>();
- 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<Identity> getRoots(TransferableGraph1 tg) {
+
+ ArrayList<Identity> result = new ArrayList<Identity>();
+ 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<tg.statements.length;i+=4) {
+ if(tg.statements[i] == resource) {
+ result.add(tg.statements[i+1]);
+ result.add(tg.statements[i+3]);
+ }
+ }
+ return result;
+ }
+
+ public static Collection<Identity> getChildren2(TransferableGraph1 tg, Identity parent) {
+ return getChildren2(tg, parent.resource);
+ }
+
+ public static Collection<Identity> getChildren2(TransferableGraph1 tg, int parentResource) {
+ TreeMap<String, Identity> 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<tg.statements.length;i+=4) {
- if(tg.statements[i] == resource) {
- result.add(tg.statements[i+1]);
- result.add(tg.statements[i+3]);
- }
- }
- return result;
- }
-
- public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {
- TreeMap<String,Identity> 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<tg.statements.length;i+=4) {
- if(tg.statements[i] == parent.resource) {
- 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 = getPossibleObject(tg, tg.statements[i+3], hasName);
- if(possibleNameResource != 0) {
- 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 TIntArrayList getObjects(TransferableGraph1 tg, int subject, Identity predicate) {
- TIntArrayList result = new TIntArrayList();
- for(int i=0;i<tg.statements.length;i+=4) {
- if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
- result.add(tg.statements[i+3]);
- }
- }
- return result;
- }
-
/**
* This implementation is no longer advised to use because it returns 0 as
* NOT_FOUND which is in fact a valid ID for resource in graph
*/
- @Deprecated
- public static int getPossibleObject(TransferableGraph1 tg, int subject, Identity predicate) {
- int result = 0;
- for(int i=0;i<tg.statements.length;i+=4) {
- if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
- if(result != 0 && tg.statements[i+3] != result) return 0;
- result = tg.statements[i+3];
- }
- }
- return result;
- }
+ @Deprecated
+ public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {
+ TreeMap<String,Identity> 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<tg.statements.length;i+=4) {
+ if(tg.statements[i] == parent.resource) {
+ 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 = getPossibleObject(tg, tg.statements[i+3], hasName);
+ if(possibleNameResource != 0) {
+ 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 TIntArrayList getObjects(TransferableGraph1 tg, int subject, Identity predicate) {
+ TIntArrayList result = new TIntArrayList();
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
+ result.add(tg.statements[i+3]);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * This implementation is no longer advised to use because it returns 0 as
+ * NOT_FOUND which is in fact a valid ID for resource in graph
+ */
+ @Deprecated
+ public static int getPossibleObject(TransferableGraph1 tg, int subject, Identity predicate) {
+ int result = 0;
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
+ if(result != 0 && tg.statements[i+3] != result) return 0;
+ result = tg.statements[i+3];
+ }
+ }
+ return result;
+ }
- public static final int NOT_FOUND = -2;
+ public static final int NOT_FOUND = -2;
- public static int getPossibleObject2(TransferableGraph1 tg, int subject, Identity predicate) {
- int result = NOT_FOUND;
+ public static int getPossibleObject2(TransferableGraph1 tg, int subject, Identity predicate) {
+ int result = NOT_FOUND;
for(int i=0;i<tg.statements.length;i+=4) {
if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
if(result != NOT_FOUND && tg.statements[i+3] != result)
}
}
return result;
- }
-
- /**
- * @return 0 for presenting not found which is BAD
- * @see getPossibleObject2
- */
- @Deprecated
- public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
- Identity p = findExternal(tg, predicate);
- if(p == null) return 0;
- return getPossibleObject(tg, subject.resource, p);
- }
-
+ }
+
+ /**
+ * @return 0 for presenting not found which is BAD
+ * @see getPossibleObject2
+ */
+ @Deprecated
+ public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
+ Identity p = findExternal(tg, predicate);
+ if(p == null) return 0;
+ return getPossibleObject(tg, subject.resource, p);
+ }
+
public static int getPossibleObject2(TransferableGraph1 tg, Identity subject, String predicate) {
Identity p = findExternal(tg, predicate);
if (p == null)
return getPossibleObject2(tg, subject.resource, p);
}
- public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {
- Map<Identity, String> result = new HashMap<Identity, String>();
- for(Identity id : ids) {
- if(id.definition instanceof Internal) {
- Internal internal = (Internal)id.definition;
- result.put(id, internal.name);
- }
- }
- return result;
- }
+ public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {
+ Map<Identity, String> result = new HashMap<Identity, String>();
+ 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 "<internal reference " + 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.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 "<internal reference " + id + ">:";
+ }
- public static TIntObjectMap<Identity> mapIdentities(TransferableGraph1 tg) {
- return mapIdentities(tg.identities);
- }
+ public static TIntObjectMap<Identity> mapIdentities(TransferableGraph1 tg) {
+ return mapIdentities(tg.identities);
+ }
- public static TIntObjectMap<Identity> mapIdentities(Identity[] identities) {
- // Integer.MIN_VALUE cannot be the value of Identity.resource
- TIntObjectMap<Identity> map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE);
- for (Identity id : identities)
- map.put(id.resource, id);
- return map;
- }
+ public static TIntObjectMap<Identity> mapIdentities(Identity[] identities) {
+ // Integer.MIN_VALUE cannot be the value of Identity.resource
+ TIntObjectMap<Identity> 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<Identity> 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 "<internal reference " + id + ">:";
- }
+ public static String getURI(int resourceCount, TIntObjectMap<Identity> 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 "<internal reference " + id + ">:";
+ }
}
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;
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
*/
--- /dev/null
+/*******************************************************************************
+ * 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"));
+// }
+
+}
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;
public MaxIssueSeverityRecursive(Resource resource, Resource childRelation, Set<Resource> 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<Resource> 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<Severity> 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<Resource>() {
- 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<Severity>() {
- @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<Resource>() {
+ @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<Severity>() {
+ @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);
+ }
+ });
+ }
}
}
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;
@Override
public void perform(AsyncReadGraph graph, final AsyncProcedure<Severity> procedure) {
+
final IssueResource ISSUE = graph.getService(IssueResource.class);
- //System.out.println(getClass().getSimpleName() + ": " + resource);
+
+ AtomicReference<Severity> maxSeverity = new AtomicReference<Severity>();
graph.forEachObject(resource, ISSUE.Issue_HasContext_Inverse, new AsyncMultiProcedure<Resource>() {
- AtomicReference<Severity> maxSeverity = new AtomicReference<Severity>();
@Override
public void execute(AsyncReadGraph graph, final Resource issue) {
}
@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<Resource>() {
+ @Override
+ public void execute(AsyncReadGraph graph, final Resource element) {
+
+ graph.asyncRequest(new ResourceRead<Resource>(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<Resource>() {
+
+ @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());
+
}
/**
ISSUE.DynamicIssueSource <T ISSUE.IssueSource
L0.HasDescription "A dynamic issue source is a source that is browsed purely through the Variable interface to produce a single subtree to represent issues. The issues do not have to have a database resource representation backing them."
+ISSUE.Issue.ContextList <T L0.List
+ @L0.assert L0.List.ElementPredicate
+ ISSUE.Issue.ContextList.Element <R L0.List.ElementWithInverse
+
ISSUE.Issue <T L0.Entity
L0.HasDescription "A notification of specified severity about an issue in the model."
>-- ISSUE.Issue.HasContext <R L0.IsRelatedTo
L0.InverseOf ISSUE.Issue.HasContext.Inverse <R L0.IsRelatedTo
>-- ISSUE.Issue.HasSeverity --> ISSUE.Severity <R L0.DependsOn : L0.FunctionalRelation
- >-- ISSUE.Issue.HasContexts --> L0.List <R L0.DependsOn
+ >-- ISSUE.Issue.HasContexts --> ISSUE.Issue.ContextList <R L0.DependsOn
>-- ISSUE.Issue.contexts ==> "[Resource]" <R L0.HasProperty : L0.FunctionalRelation
>-- ISSUE.Issue.severity ==> "String" <R L0.HasProperty : L0.FunctionalRelation
>-- ISSUE.Issue.resource ==> "String" <R L0.HasProperty : L0.FunctionalRelation
L0.HasDescription """Represents a list of resources that may contain repetitions."""
@L0.assert L0.HasValueType "[Resource]"
@L0.assert L0.ConvertsToValueWith L0.Functions.listResources
+ >-- L0.List.ElementPredicate --> L0.Relation <R L0.DependsOn : L0.FunctionalRelation
+ @L0.assert L0.List.ElementPredicate L0.List.Element
+L0.ListWithInverses <T L0.List
+ @L0.assert L0.List.ElementPredicate L0.List.ElementWithInverse
L0.List.Entry <T L0.List
L0.List.Next <R L0.IsRelatedTo : L0.TotalFunction
L0.HasDomain L0.List
L0.List.Previous <R L0.IsRelatedTo : L0.TotalFunction
L0.InverseOf L0.List.Next
L0.List.Element <R L0.IsRelatedTo : L0.TotalFunction
- L0.HasDomain L0.List.Entry
\ No newline at end of file
+ L0.HasDomain L0.List.Entry
+L0.List.ElementWithInverse <R L0.List.Element
+ L0.InverseOf L0.List.ElementWithInverse.Inverse <R L0.IsRelatedTo
\ No newline at end of file
"svgTabContribution"
"() -> <Proc> 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
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
//ACTIONS.MigrateMasterTypical : ACT.Action
ACTIONS.RenameDiagramComponents : ACT.Action
ACTIONS.Help : ACT.Action
+ACTIONS.CopyURI : ACT.Action
ACTIONS.NavigateToSubstructure
@MOD.sclAction "navigateToSubstructureAction"
</type>
</target>
+ <target interface="org.simantics.scenegraph.profile.Style">
+ <resource uri="http://www.simantics.org/Modeling-0.0/IssueDecorationStyle"
+ class="org.simantics.modeling.ui.diagram.style.IssueDecorationStyle">
+ </resource>
+ </target>
+
</adapters>
\ No newline at end of file
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 -> <Proc> String
+ decorateLabel :: LabelDecorator -> String -> String -> Integer -> <Proc> Maybe String
decorateForeground :: LabelDecorator -> a -> String -> Integer -> <Proc> a
decorateBackground :: LabelDecorator -> a -> String -> Integer -> <Proc> a
decorateFont :: LabelDecorator -> Maybe a -> String -> Integer -> <Proc> Maybe a
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;
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();
@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);
+ }
+ }
}
});
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));
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;
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;
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
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() {
}
@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.<Object>singleton(element));
-
+ Pair<Resource, Collection<Object>> 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<Resource, Collection<Object>> extractContext(ReadGraph graph, Object input) throws DatabaseException {
+ Pair<Variable, Resource> p = extractInput(graph, input);
+ Pair<Resource, Collection<Object>> 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> T extractContent(ReadGraph graph, Object input, WorkbenchSelectionContentType<T> contentType, Class<T> 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<Variable, Resource> 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<Resource, Collection<Object>> findConfigurationAndObjects(ReadGraph graph, Resource issue) throws DatabaseException {
+ IssueResource ISSUE = IssueResource.getInstance(graph);
+ if (!graph.isInstanceOf(issue, ISSUE.Issue))
+ return null;
+ List<Resource> 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<Resource, Collection<Object>> findConfigurationAndObjects(ReadGraph graph, Variable v) throws DatabaseException {
+ List<Resource> contexts = v.getPossiblePropertyValue(graph, IssueResource.getInstance(graph).Issue_contexts);
+ return contexts != null ? findConfigurationAndObjects(graph, contexts) : null;
+ }
+
+ protected static Pair<Resource, Collection<Object>> findConfigurationAndObjects(ReadGraph graph, List<Resource> 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<Resource> types = graph.getTypes(context);
+ if (types.contains(DIA.Element)) {
+ Resource config = findConfigurationForElement(graph, context);
+ if (config != null) {
+ Collection<Object> elements = Collections.<Object>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.<Object>singleton(element));
+ }
+ }
+ }
+ }
+
+ return null;
}
- public static Collection<Object> 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<Object> findElementObjects(ReadGraph g, Resource component) throws DatabaseException {
+ Collection<Object> 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<Object> 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<Object> selectedObjects = new ArrayList<Object>();
- 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<Object> 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;
- }
+ }
}
</type>
<resource uri="http://www.simantics.org/Modeling-0.0/ModelingActionContext/Actions/Help"
class="org.simantics.modeling.actions.Help" />
+ <resource uri="http://www.simantics.org/Modeling-0.0/ModelingActionContext/Actions/CopyURI"
+ class="org.simantics.modeling.actions.CopyURI" />
</target>
<target interface="org.simantics.db.layer0.adapter.DropActionFactory">
"""Returns all diagrams of the given model."""
diagramsOf :: Model -> <ReadGraph> [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 -> <ReadGraph> [Resource]
+diagramsUnder folder = recurse DIA.Diagram folder
where
recurse t r = do
cs = children r
importJava "org.simantics.modeling.svg.CreateSVGElement" where
createSVGElement :: Resource -> String -> ByteArray -> Double -> Double -> <WriteGraph> ()
+ createSVGElementR :: Resource -> String -> ByteArray -> Double -> Double -> <WriteGraph> Resource
importSVGElement :: Resource -> File -> Double -> Double -> <WriteGraph> ()
+ importSVGElementR :: Resource -> File -> Double -> Double -> <WriteGraph> Resource
importJava "org.simantics.diagram.synchronization.graph.RemoveElement" where
removeElement :: Resource -> Resource -> <WriteGraph> ()
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;
// at the very start of the editor
List<CompilationError> errors = new ArrayList<CompilationError>();
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);
}
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;
}
public static List<Resource> 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.<List<Resource>>instance());
}
public static List<Resource> searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
}
public static List<Resource> 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.<List<Resource>>instance());
}
public static List<Resource> searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException {
}
public static List<Resource> 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.<List<Resource>>instance());
}
/**
--- /dev/null
+/*******************************************************************************
+ * 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;
+ }
+
+}
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;
+ }
}
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;
+ }
}
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);
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();
}
-
+
}
//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"
*******************************************************************************/
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;
protected Boolean visible = Boolean.TRUE;
protected BufferedImage img = null;
+ protected float alpha = 1.0f;
@SyncField("visible")
public void setVisible(Boolean visible) {
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;
// 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);
}
public void render(Graphics2D g) {
if (!enabled)
return;
-
+
AffineTransform tr = g.getTransform();
double scaleX = Math.abs(tr.getScaleX());
double scaleY = Math.abs(tr.getScaleY());
// 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) {
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) {
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);
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,
--- /dev/null
+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> 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);
+ }
+}
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");
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;
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)
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,
for(TransformationRule rule : module.getRules())
for(Query[] queries : rule.sections.values())
for(Query query : queries)
- query.collectRefs(allRefs, refs);
+ query.collectRefs(allRefs, refs);
}
@Override
public class LocalVariableConstant extends Constant {
- LocalVariable var;
+ public LocalVariable var;
public LocalVariableConstant(Type type, LocalVariable var) {
super(type);
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;
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;
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 {
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<parameters.length;++i)
parameters[i] = parameters[i].resolve(context);
}
}
- public void collectRefs(TObjectIntHashMap<Object> 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)
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];
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<Variable> 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;
return b.toString();
}
- public void collectQueryEffects(THashSet<Type> effects) {
- }
-
- public void collectEnforceEffects(THashSet<Type> effects) {
+ public CHRLiteral replace(ReplaceContext context) {
+ CHRLiteral copy = new CHRLiteral(location, relation, context.replace(parameters), killAfterMatch, negated);
+ for(int i=0;i<parameters.length;++i)
+ copy.parameters[i] = copy.parameters[i].replace(context);
+ copy.passive = passive;
+ copy.typeConstraintEvidenceParameters = context.replace(typeConstraintEvidenceParameters);
+ copy.typeParameters = context.replace(typeParameters);
+ copy.fields = context.replace(fields);
+ return copy;
}
}
import org.simantics.scl.compiler.elaboration.chr.plan.PostCommitOp;
import org.simantics.scl.compiler.elaboration.chr.plan.PreCommitOp;
import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
+import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
+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.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.errors.Locations;
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 class CHRQuery extends Symbol {
literal.resolve(context);
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(CHRLiteral literal : literals)
- literal.collectRefs(allRefs, refs);
- }
-
public void checkType(TypingContext context) {
for(CHRLiteral literal : literals)
literal.checkType(context);
for(CHRLiteral literal : literals)
literal.collectVars(allVars, vars);
}
-
- public void forVariables(VariableProcedure procedure) {
- for(CHRLiteral literal : literals)
- literal.forVariables(procedure);
- }
-
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(CHRLiteral literal : literals)
- literal.collectFreeVariables(vars);
- }
-
+
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
this.location = loc;
}
}
- 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<literals.length;++i) {
CHRLiteral literal = literals[i];
if(i == activeLiteralId)
else
context.add(literal, i);
}
+ if(activeLiteralId == -1 && inputFact != null) {
+ context.addInitFact(initConstraint, inputFact);
+ }
return context.createQueryPlan();
}
visitor.visit(this);
return b.toString();
}
+
+ public CHRQuery replace(ReplaceContext context) {
+ CHRLiteral[] newLiterals = new CHRLiteral[literals.length];
+ for(int i=0;i<literals.length;++i)
+ newLiterals[i] = literals[i].replace(context);
+ return new CHRQuery(newLiterals);
+ }
}
import org.simantics.scl.compiler.types.Types;
import org.simantics.scl.compiler.types.kinds.Kinds;
+import gnu.trove.set.hash.THashSet;
+
public interface CHRRelation {
public static final TVar A = Types.var(Kinds.STAR);
default String[] getFieldNames() {
return null;
}
+ void collectEnforceEffects(THashSet<Type> effects);
+ void collectQueryEffects(THashSet<Type> effects);
}
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;
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 {
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();
existentialVariables = context.popExistentialFrame();
}
- public void collectRefs(TObjectIntHashMap<Object> 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));
body.collectVars(allVars, vars);
}
- public void forVariables(VariableProcedure procedure) {
- head.forVariables(procedure);
- body.forVariables(procedure);
- }
-
- public void collectFreeVariables(THashSet<Variable> vars) {
- head.collectFreeVariables(vars);
- body.collectFreeVariables(vars);
- }
-
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
this.location = loc;
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()));
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);
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;
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 {
}*/
}
- public void collectRefs(TObjectIntHashMap<Object> 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);
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<Variable> 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;
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();
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);
}
{
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);
}
}
return runtimeRulesetVariable;
}
- public void collectEffects(THashSet<Type> 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;
--- /dev/null
+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<conjuncts.length;++i)
+ conjuncts[i] = atom(apply.parameters[i]);
+ CHRAstQuery query = CHRAstConjunction.conjunction(conjuncts);
+ query.location = expression.location;
+ return query;
+ }
+ }
+ }
+ CHRAstAtom query = new CHRAstAtom(expression, remove);
+ query.location = expression.location;
+ return query;
+ }
+
+ @Override
+ protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList<CHRLiteral> 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;
+ }
+}
--- /dev/null
+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<CHRLiteral> literals) {
+ literals.add(new CHRLiteral(location, SpecialCHRRelation.MEMBER,
+ new Expression[] { left, right }, false, false));
+ }
+}
--- /dev/null
+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<CHRAstQuery> conjuncts;
+
+ public CHRAstConjunction(List<CHRAstQuery> conjuncts) {
+ this.conjuncts = conjuncts;
+ }
+
+ @Override
+ public void accept(CHRAstQueryVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ public static CHRAstQuery conjunction(CHRAstQuery[] conjuncts) {
+ ArrayList<CHRAstQuery> result = new ArrayList<CHRAstQuery>(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<CHRLiteral> literals) {
+ for(CHRAstQuery conjunct : conjuncts)
+ conjunct.translate(context, mode, literals);
+ }
+}
--- /dev/null
+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<CHRLiteral> literals) {
+ literals.add(new CHRLiteral(location, mode.isHead ? SpecialCHRRelation.EQUALS : SpecialCHRRelation.ASSIGN,
+ new Expression[] { left, right }, false, false));
+ }
+}
--- /dev/null
+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<CHRLiteral> literals) {
+ context.getCompilationContext().errorLog.log(location, "CHR negation is not yet supported.");
+ }
+}
--- /dev/null
+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<CHRLiteral> literals = new ArrayList<CHRLiteral>();
+ translate(context, mode, literals);
+ return new CHRQuery(literals.toArray(new CHRLiteral[literals.size()]));
+ }
+
+ protected abstract void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList<CHRLiteral> literals);
+
+ public abstract void accept(CHRAstQueryVisitor visitor);
+}
--- /dev/null
+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);
+}
--- /dev/null
+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;
+ }
+}
if(end != null)
end.return_(BooleanConstant.FALSE);
}
-
}
variable.setVal(expression.toVal(context, w));
planContext.nextOp(w);
}
-
-
}
return b.toString();
}
- public abstract void toString(StringBuilder b);
+ public void toString(StringBuilder b) {}
public abstract void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w);
}
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;
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;
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.");
}
for(int i=0;i<literal.parameters.length;++i)
addOneSidedEquals(literal.parameters[i].location, new EVariable(variables[i]), literal.parameters[i], secondaryPriority);
}
+
+ public void addInitFact(CHRConstraint initConstraint, Expression inputFact) {
+ planOps.add(new AccessFactOp(Locations.NO_LOCATION, inputFact, initConstraint, Variable.EMPTY_ARRAY, false));
+ }
public void claim(QueryPlanningContext context, CHRLiteral literal) {
if(literal.relation instanceof CHRConstraint) {
case EXECUTE:
addPlanOp(new ExecuteOp(literal.location, literal.parameters[0]));
break;
+ case ASSIGN:
+ addPlanOp(new MatchOp(literal.location, literal.parameters[1], literal.parameters[0]));
+ break;
default:
context.getCompilationContext().errorLog.log(
literal.location,
import org.simantics.scl.compiler.types.Types;
import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.set.hash.THashSet;
public class CHRConstraint extends Symbol implements CHRRelation {
public final String name;
public String[] getFieldNames() {
return fieldNames;
}
+
+ @Override
+ public void collectEnforceEffects(THashSet<Type> effects) {
+ effects.add(Types.PROC);
+ }
+
+ @Override
+ public void collectQueryEffects(THashSet<Type> effects) {
+ effects.add(Types.PROC);
+ }
}
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;
public String[] getFieldNames() {
return relation.getFieldNames();
}
+
+ @Override
+ public void collectEnforceEffects(THashSet<Type> effects) {
+ effects.add(relation.getEnforceEffect());
+ }
+
+ @Override
+ public void collectQueryEffects(THashSet<Type> effects) {
+ effects.add(relation.getQueryEffect());
+ }
}
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;
public TPred[] getTypeConstraints() {
return TPred.EMPTY_ARRAY;
}
+
+ @Override
+ public void collectEnforceEffects(THashSet<Type> effects) {
+ }
+
+ @Override
+ public void collectQueryEffects(THashSet<Type> effects) {
+ }
}
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;
public TPred[] getTypeConstraints() {
throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking.");
}
+
+ @Override
+ public void collectEnforceEffects(THashSet<Type> effects) {
+ effects.add(Types.PROC);
+ }
+
+ @Override
+ public void collectQueryEffects(THashSet<Type> effects) {
+ effects.add(Types.PROC);
+ }
}
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;
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;
}
}
- public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) {
- ArrayList<CHRLiteral> head = new ArrayList<CHRLiteral>(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<CHRLiteral> query = new ArrayList<CHRLiteral>(lqs.length);
+ for(ListQualifier qualifier : lqs) {
+ CHRLiteral literal = convertListQualifier(context, isHead, qualifier);
if(literal != null)
- head.add(literal);
- }
- ArrayList<CHRLiteral> body = new ArrayList<CHRLiteral>(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));
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;
public ReplaceContext(TypingContext typingContext) {
this(new THashMap<TVar, Type>(), new THashMap<Variable, Expression>(), typingContext);
}
+
+ public Expression[] replace(Expression[] expressions) {
+ if(expressions == null)
+ return null;
+ Expression[] result = new Expression[expressions.length];
+ for(int i=0;i<expressions.length;++i)
+ result[i] = expressions[i].replace(this);
+ return result;
+ }
+
+ public Type[] replace(Type[] types) {
+ if(types == null)
+ return null;
+ return Types.replace(types, tvarMap);
+ }
+
+ public FieldAssignment[] replace(FieldAssignment[] fields) {
+ if(fields == null)
+ return null;
+ FieldAssignment[] result = new FieldAssignment[fields.length];
+ for(int i=0;i<fields.length;++i)
+ result[i] = fields[i].replace(this);
+ return result;
+ }
}
TIntArrayList chrConstraintFrames = new TIntArrayList();
ArrayList<CHRConstraintEntry> chrConstraintEntries = new ArrayList<CHRConstraintEntry>();
+ public CHRRuleset currentRuleset;
+
static class Entry {
String name;
Variable variable;
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;
}
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- left.forVariables(procedure);
- right.forVariables(procedure);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> 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<Type> 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<Object> allRefs, TIntHashSet refs) {
- left.collectRefs(allRefs, refs);
- right.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
- left.collectVars(allVars, vars);
- right.collectVars(allVars, vars);
- }
-
@Override
public void resolve(TranslationContext context) {
left = left.resolve(context);
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;
}
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- guard.forVariables(procedure);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- guard.collectFreeVariables(vars);
- }
-
- @Override
- public void decorate(ExpressionDecorator decorator) {
- guard = guard.decorate(decorator);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- guard.collectEffects(effects);
- }
-
@Override
public void checkType(TypingContext context) {
guard = guard.checkIgnoredType(context);
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- guard.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
- guard.collectVars(allVars, vars);
- }
-
@Override
public void resolve(TranslationContext context) {
guard = guard.resolve(context);
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<Variable> vars);
- public abstract void decorate(ExpressionDecorator decorator);
- public abstract void collectEffects(THashSet<Type> effects);
public abstract void checkType(TypingContext context);
- public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);
- public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
public abstract void resolve(TranslationContext context);
public abstract void accept(EquationVisitor visitor);
public abstract Equation replace(ReplaceContext context);
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() {
}
throw new InternalCompilerError(getClass().getSimpleName() + " does not support simplify.");
}
- @Override
- final public void collectFreeVariables(THashSet<Variable> vars) {
- throw new InternalCompilerError(getClass().getSimpleName() + " does not support collectFreeVariables.");
-
- }
-
- @Override
- final public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- throw new InternalCompilerError(getClass().getSimpleName() + " does not support collectRefs.");
- }
-
- @Override
- final public void collectVars(TObjectIntHashMap<Variable> 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<Type> 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.");
}
}
@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;
}
}
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 {
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);
- }
}
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;
return lhs;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- }
-
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- value.collectVars(allVars, vars);
- }
-
- public void collectFreeVariables(THashSet<Variable> 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<patterns.length;++i)
patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);
value = value.checkIgnoredType(context);
}
-
- public void decorate(ExpressionDecorator decorator) {
- for(int i=0;i<patterns.length;++i)
- patterns[i] = patterns[i].decorate(decorator);
- value = value.decorate(decorator);
- }
-
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- }
}
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 abstract class DecoratingExpression extends SimplifiableExpression {
public Expression expression;
this.expression = expression;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- expression.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- expression.collectVars(allVars, vars);
- }
-
@Override
protected void updateType() throws MatchException {
setType(expression.getType());
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- expression.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
expression = expression.simplify(context);
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<Type> effects) {
- expression.collectEffects(effects);
- }
@Override
public void setLocationDeep(long loc) {
}
}
- @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() + ".");
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;
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;
boolean[] active;
int activeCount;
transient TypingContext context;
- Expression resolvedExpression;
+ public Expression resolvedExpression;
public abstract static class Alternative {
public abstract Type getType();
this.activeCount = alternatives.length;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- }
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
-
@Override
protected void updateType() throws MatchException {
throw new InternalCompilerError();
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<alternatives.length;++i) {
b.append("\n ");
b.append(alternatives[i]);
listenType();
return this;
}
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- }
@Override
public Expression resolve(TranslationContext context) {
location = loc;
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return this;
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- // TODO Auto-generated method stub
- }
-
@Override
public void accept(ExpressionVisitor visitor) {
- // TODO Auto-generated method stub
+ visitor.visit(this);
}
@Override
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;
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;
public Expression[] getParameters() {
return parameters;
}
-
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- function.collectRefs(allRefs, refs);
- for(Expression parameter : parameters)
- parameter.collectRefs(allRefs, refs);
- }
-
- public void collectVars(TObjectIntHashMap<Variable> 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<parameters.length;++i)
if(!Types.equals(parameters[i].getType(), mfun.parameterTypes[i]))
effect = Types.simplifyFinalEffect(effect);
return w.applyWithEffect(location, effect, type, functionVal, parameterVals);
}
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- function.collectFreeVariables(vars);
- for(Expression parameter : parameters)
- parameter.collectFreeVariables(vars);
- }
private void combineApplications() {
if(function instanceof EApply) {
for(Expression parameter : this.parameters)
parameters.add(parameter);
}
-
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- function.removeFreeVariables(vars);
- for(Expression parameter : parameters)
- parameter.removeFreeVariables(vars);
- }
@Override
public Expression replace(ReplaceContext context) {
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<parameters.length;++i)
- parameters[i] = parameters[i].decorate(decorator);
- }
- return decorator.decorate(this);
- }
public Type getLocalEffect() {
return effect;
return function.isConstructorApplication();
}
- @Override
- public void collectEffects(THashSet<Type> effects) {
- effects.add(effect);
- function.collectEffects(effects);
- for(Expression parameter : parameters)
- parameter.collectEffects(effects);
- }
-
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
return false;
}
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- function.forVariables(procedure);
- for(Expression parameter : parameters)
- parameter.forVariables(procedure);
- }
@Override
public boolean isPattern(int arity) {
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) {
return parameter;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- expression.collectRefs(allRefs, refs);
+ @Override
+ protected void updateType() throws MatchException {
+ setType(Types.instantiate(expression.getType(), parameter));
}
-
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
- expression.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
expression = expression.simplify(context);
expression = expression.resolve(context);
return this;
}
-
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- expression.removeFreeVariables(vars);
- }
@Override
public Expression replace(ReplaceContext context) {
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<Type> effects) {
- expression.collectEffects(effects);
- }
@Override
public void setLocationDeep(long loc) {
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- expression.forVariables(procedure);
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
public Expression getPattern() {
return pattern;
}
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- pattern.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- int id = allVars.get(var);
- if(id >= 0)
- vars.add(id);
- pattern.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- throw new InternalCompilerError(location, "Cannot collect free variables for a pattern.");
- }
-
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- vars.remove(var);
- pattern.removeFreeVariables(vars);
- }
@Override
public Expression simplify(SimplificationContext context) {
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) {
return result;
}
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- pattern.collectEffects(effects);
- }
@Override
public void setLocationDeep(long loc) {
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) {
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;
this.value = value;
this.in = in;
}
-
- @Override
- public void collectRefs(final TObjectIntHashMap<Object> allRefs, final TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- in.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- value.collectVars(allVars, vars);
- in.collectVars(allVars, vars);
- }
@Override
protected void updateType() throws MatchException {
return simplified.simplify(context);
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- in.collectFreeVariables(vars);
- value.collectFreeVariables(vars);
- pattern.removeFreeVariables(vars);
- }
-
@Override
public Expression resolve(TranslationContext context) {
value = value.resolve(context);
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<Type> effects) {
- pattern.collectEffects(effects);
- value.collectEffects(effects);
- in.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
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) {
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;
public class EBlock extends ASTExpression {
- ArrayList<Statement> statements = new ArrayList<Statement>();
+ public ArrayList<Statement> statements = new ArrayList<Statement>();
boolean monadic;
public EBlock() {
ruleset.location = Locations.combine(statements.get(begin).location, statements.get(end-1).location);
for(int i=begin;i<end;++i) {
Statement statement = statements.get(i);
- if(statement instanceof CHRStatement)
- ruleset.addRule(CHRTranslation.convertCHRStatement(context, (CHRStatement)statement));
+ if(statement instanceof CHRStatement) {
+ CHRStatement chrStatement = (CHRStatement)statement;
+ ruleset.addRule(new CHRRule(chrStatement.location,
+ chrStatement.head.translate(context, CHRQueryTranslationMode.RULE_HEAD),
+ chrStatement.body.translate(context, CHRQueryTranslationMode.RULE_BODY)));
+ }
else if(statement instanceof ConstraintStatement)
ruleset.constraints.add(CHRTranslation.convertConstraintStatement(context, (ConstraintStatement)statement));
else if(statement instanceof IncludeStatement)
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 ECHRRuleset extends Expression {
- CHRRuleset ruleset;
- Expression in;
+ public CHRRuleset ruleset;
+ public Expression in;
public ECHRRuleset(CHRRuleset ruleset, Expression in) {
this.ruleset = ruleset;
this.in = in;
}
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- ruleset.collectRefs(allRefs, refs);
- in.collectRefs(allRefs, refs);
- }
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> 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
in.setLocationDeep(loc);
}
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- in = in.decorate(decorator);
- return this;
- }
- @Override
- public void collectEffects(THashSet<Type> effects) {
- ruleset.collectEffects(effects);
- in.collectEffects(effects);
- }
+
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
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<Object> allRefs, TIntHashSet refs) {
- ruleset.collectRefs(allRefs, refs);
- }
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
- ruleset.collectFreeVariables(vars);
- }
+
@Override
public Expression resolve(TranslationContext context) {
context.pushFrame();
}
}
@Override
- public Expression decorate(ExpressionDecorator decorator) {
- return this;
- }
- @Override
- public void collectEffects(THashSet<Type> effects) {
- ruleset.collectEffects(effects);
- }
- @Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
--- /dev/null
+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<PlanOp> 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<existentialVariables.length;++i) {
+ Variable newVariable = existentialVariables[i].copy();
+ context.varMap.put(existentialVariables[i], new EVariable(newVariable));
+ newExistentialVariables[i] = newVariable;
+ }
+ ECHRSelect copy = new ECHRSelect(expression.replace(context), query.replace(context));
+ copy.existentialVariables = newExistentialVariables;
+ copy.currentRuleset = currentRuleset;
+ copy.planOps = planOps;
+ if(planOps != null) {
+ copy.planOps = new ArrayList<PlanOp>(planOps.size());
+ throw new InternalCompilerError(location, "Copying of ECHRSelect is not supported.");
+ //for(PlanOp op : planOps)
+ // copy.planOps.add(op.replace(context));
+ }
+ return copy;
+ }
+}
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;
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;
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) {
setType(Types.instantiate(getType(), type));
return this;
}
-
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- int id = allRefs.get(value);
- if(id >= 0)
- refs.add(id);
+
+ @Override
+ public Set<Variable> getFreeVariables() {
+ return Collections.emptySet();
}
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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));
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<Variable> vars) {
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ IVal val = value.getValue();
+ if(typeParameters.length > 0) {
+ val = val.createSpecialization(typeParameters);
+ }
+ return val;
}
@Override
public Expression resolveAsPattern(TranslationContext context) {
return this;
}
-
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- }
@Override
public Expression replace(ReplaceContext context) {
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
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<Type> effects) {
+ return false;
}
@Override
public Precedence getPrecedence() {
return value.getPrecedence();
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
@Override
public boolean isPattern(int arity) {
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;
return query;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- query.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- query.collectVars(allVars, vars);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects.");
- }
-
@Override
protected void updateType() throws MatchException {
setType(Types.tupleConstructor(0));
return query.generateEnforce(new EnforcingContext(context));
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- query.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
/*query = query.simplify(context);
query = new QExists(variables, query);
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
@Override
public void setLocationDeep(long loc) {
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- query.forVariables(procedure);
- }
@Override
public Expression replace(ReplaceContext context) {
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;
return transformer.transform(this);
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(Equation equation : equations)
- equation.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> 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<Type> effects) {
- for(Equation equation : equations)
- equation.collectEffects(effects);
- }
-
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
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) {
setType(type);
}
- public EError() {
+ public EError() {
}
public EError(long loc) {
this(loc, Types.metaVar(Kinds.STAR));
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ throw new UnsupportedOperationException();
}
@Override
public Expression inferType(TypingContext context) {
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return this;
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- }
@Override
public void setLocationDeep(long loc) {
public Expression replace(ReplaceContext context) {
return this;
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
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;
return value;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> 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;
return new EExternalConstant(value, getType().replace(context.tvarMap));
}
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- }
-
@Override
public Expression inferType(TypingContext context) {
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- }
@Override
public void setLocationDeep(long loc) {
public IExpression toIExpression(ExpressionInterpretationContext context) {
return new IConstant(value);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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) {
((EFieldAccess)parent).lastAccessor = false;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- parent.collectRefs(allRefs, refs);
- accessor.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- parent.collectVars(allVars, vars);
- accessor.collectVars(allVars, vars);
- }
-
private boolean returnsValue() {
return accessor.accessSeparator == '#' && !accessor.isVariableId();
}
return this;
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- parent.collectFreeVariables(vars);
- accessor.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
// Simplify subexpressions
accessor.resolve(context);
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- // FIXME
- effects.add(Types.READ_GRAPH);
- }
@Override
public void setLocationDeep(long loc) {
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) {
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<Object> allRefs,
- TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- if(evidence != null)
- evidence.collectVars(allVars, vars);
- }
@Override
public Expression inferType(TypingContext context) {
setType(constraint);
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- if(evidence != null)
- evidence.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
return evidence.simplify(context);
return this;
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- evidence.forVariables(procedure);
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
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_;
this.else_ = else_;
}
- public void collectRefs(TObjectIntHashMap<Object> 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<Variable> 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();
return w.getParameters()[0];
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- condition.collectFreeVariables(vars);
- then_.collectFreeVariables(vars);
- if(else_ != null)
- else_.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
condition = condition.simplify(context);
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<Type> effects) {
- condition.collectEffects(effects);
- then_.collectEffects(effects);
- if(else_ != null)
- else_.collectEffects(effects);
- }
@Override
public void setLocationDeep(long loc) {
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);
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<Object> allRefs,
- TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- }
public String getValue() {
return value;
throw new InternalCompilerError();
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- }
-
@Override
public Expression simplify(SimplificationContext context) {
try {
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<Type> effects) {
- }
@Override
public void setLocationDeep(long loc) {
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) {
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 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;
this(loc, new Case(new Expression[] {pat}, exp));
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(Case case_ : cases)
- case_.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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
return decomposeMatching().simplify(context);
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(Case case_ : cases)
- case_.collectFreeVariables(vars);
- }
-
@Override
public Expression resolve(TranslationContext context) {
for(Case case_ : cases)
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<Type> 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) {
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;
this.value = value;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
+ @Override
+ protected void updateType() throws MatchException {
+ setType(Types.forAll(parameters, value.getType()));
}
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
- value.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
value = value.simplify(context);
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<Type> effects) {
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
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;
this.assignments = assignments;
this.in = in;
}
-
- @Override
- public void collectRefs(final TObjectIntHashMap<Object> allRefs, final TIntHashSet refs) {
- for(Assignment assign : assignments)
- assign.value.collectRefs(allRefs, refs);
- in.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- for(Assignment assign : assignments)
- assign.value.collectVars(allVars, vars);
- in.collectVars(allVars, vars);
- }
@Override
protected void updateType() throws MatchException {
return result;
}
- @Override
- public void collectFreeVariables(THashSet<Variable> 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.");
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<Type> effects) {
- for(Assignment assignment : assignments) {
- assignment.pattern.collectEffects(effects);
- assignment.value.collectEffects(effects);
- }
- in.collectEffects(effects);
- }
@Override
public void setLocationDeep(long loc) {
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) {
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;
this.head = head;
this.qualifier = qualifier;
}
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- head.collectRefs(allRefs, refs);
- qualifier.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- head.collectVars(allVars, vars);
- qualifier.collectVars(allVars, vars);
- }
@Override
public Expression checkBasicType(TypingContext context, Type requiredType) {
setType(Types.list(head.getType()));
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- head.collectFreeVariables(vars);
- qualifier.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
context.pushLocation(location);
return this;
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- head = head.decorate(decorator);
- qualifier.decorate(decorator);
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- head.collectEffects(effects);
- qualifier.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
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) {
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;
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) {
return components;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- for(Expression component : components)
- component.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- for(Expression component : components)
- component.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(Expression component : components)
- component.collectFreeVariables(vars);
- }
-
@Override
public Expression simplify(SimplificationContext context) {
context.pushLocation(location);
return this;
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- for(int i=0;i<components.length;++i)
- components[i] = components[i].decorate(decorator);
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- for(Expression component : components)
- component.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
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) {
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;
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;
public Constant getValue() {
return value;
}
-
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+
+ @Override
+ public Set<Variable> getFreeVariables() {
+ return Collections.emptySet();
}
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ return value;
}
-
@Override
public Expression simplify(SimplificationContext context) {
return this;
return new ELiteral(value);
}
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- }
-
@Override
public IExpression toIExpression(ExpressionInterpretationContext target) {
return new IConstant(value.realizeValue(target.localClassBuilder));
public Expression inferType(TypingContext context) {
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- }
@Override
public void setLocationDeep(long loc) {
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
@Override
public boolean isPattern(int arity) {
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;
this.cases = cases;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(Expression s : scrutinee)
- s.collectRefs(allRefs, refs);
- for(Case case_ : cases)
- case_.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Row> rows = new ArrayList<Row>(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<scrutinee.length;++i)
- scrutineeVals[i] = scrutinee[i].toVal(context, w);
-
- CodeWriter joinPoint = w.createBlock(getType());
- CodeWriter failurePoint = w.createBlock(); // TODO generate only one failurePoint per function
- PatternMatchingCompiler.split(w, context, scrutineeVals, joinPoint.getContinuation(), failurePoint.getContinuation(), rows);
- failurePoint.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());
- w.continueAs(joinPoint);
- return w.getParameters()[0];
+ @Override
+ protected void updateType() {
+ setType(cases[0].value.getType());
}
@Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(Expression s : scrutinee)
- s.collectFreeVariables(vars);
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ ArrayList<Row> rows = new ArrayList<Row>(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<scrutinee.length;++i)
+ scrutineeVals[i] = scrutinee[i].toVal(context, w);
+
+ CodeWriter joinPoint = w.createBlock(getType());
+ CodeWriter failurePoint = w.createBlock(); // TODO generate only one failurePoint per function
+ PatternMatchingCompiler.split(w, context, scrutineeVals, joinPoint.getContinuation(), failurePoint.getContinuation(), rows);
+ failurePoint.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());
+ w.continueAs(joinPoint);
+ return w.getParameters()[0];
}
@Override
setType(Types.UNIT);
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- for(int i=0;i<scrutinee.length;++i)
- scrutinee[i] = scrutinee[i].decorate(decorator);
- for(Case case_ : cases)
- case_.decorate(decorator);
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> 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) {
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) {
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) {
public Expression resolveAsPattern(TranslationContext context) {
return expression.resolveAsPattern(context);
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return expression.decorate(decorator);
- }
}
--- /dev/null
+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);
+ }
+}
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TObjectObjectProcedure;
+/**
+ * Generated mainly from EBlock
+ */
public class EPreLet extends ASTExpression {
- List<LetStatement> assignments;
- Expression in;
+ public List<LetStatement> assignments;
+ public Expression in;
public EPreLet(List<LetStatement> assignments, Expression in) {
this.assignments = assignments;
public class EPreRuleset extends ASTExpression {
- RuleStatement[] statements;
- Expression in;
+ public RuleStatement[] statements;
+ public Expression in;
public EPreRuleset(RuleStatement[] statements, Expression in) {
this.statements = statements;
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<Object> allRefs,
- TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- }
-
private Expression tryToConvertToPrimitive(ErrorLog errorLog, Type requiredType) {
if(requiredType.equals(Types.DOUBLE))
return new ELiteral(new DoubleConstant(Double.parseDouble(value)));
protected void updateType() throws MatchException {
throw new InternalCompilerError("TODO");
}
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- }
@Override
public Expression simplify(SimplificationContext context) {
return copy;
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
public String getValue() {
return value;
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- if(constraint != null)
- constraint.forVariables(procedure);
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
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;
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) {
return compile(context);
}
- @Override
- public void collectFreeVariables(THashSet<Variable> 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<Object> 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<Variable> 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<Type> 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();
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) {
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;
this.query = query;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- expression.collectRefs(allRefs, refs);
- query.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- expression.collectVars(allVars, vars);
- query.collectVars(allVars, vars);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects.");
- }
-
@Override
protected void updateType() throws MatchException {
setType(selectVariant==SCLTerminals.SELECT_FIRST
return loc(location, result);
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- expression.collectFreeVariables(vars);
- query.collectFreeVariables(vars);
- for(Variable variable : variables)
- vars.remove(variable);
- }
-
@Override
public Expression resolve(TranslationContext context) {
context.pushExistentialFrame();
variables = context.popExistentialFrame();
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
@Override
public void setLocationDeep(long loc) {
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) {
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;
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;
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;
this.effect = effect;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> vars) {
- value.collectFreeVariables(vars);
- vars.remove(parameter);
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ return lambdaToVal(context, w);
}
@Override
// Free variables;
ExpressionInterpretationContext innerContext = context.createNewContext();
- THashSet<Variable> freeVariables = cur.getFreeVariables();
+ Set<Variable> freeVariables = cur.getFreeVariables();
for(Variable parameter : parameters)
freeVariables.remove(parameter);
int i=0;
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<Type> effects) {
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
public Variable getParameter() {
return parameter;
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
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)
this.in = in;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- in.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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<Variable> 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
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<Type> effects) {
- value.collectEffects(effects);
- in.collectEffects(effects);
- }
@Override
public void accept(ExpressionVisitor visitor) {
return in;
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- in.forVariables(procedure);
- }
-
@Override
public Expression accept(ExpressionTransformer transformer) {
return transformer.transform(this);
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();
this.seed = seed;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> 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<Variable> allVars,
- TIntHashSet vars) {
- seed.collectVars(allVars, vars);
- }
-
@Override
protected void updateType() throws MatchException {
setType(Types.UNIT);
}
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- seed.collectFreeVariables(vars);
- }
@Override
public Expression inferType(TypingContext context) {
}
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
-
- @Override
- public void collectEffects(THashSet<Type> 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) {
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;
this.type = type;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- value.collectVars(allVars, vars);
- }
-
- @Override
- protected void updateType() throws MatchException {
- setType(type);
- }
-
@Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- value.collectFreeVariables(vars);
+ protected void updateType() throws MatchException {
+ setType(type);
}
@Override
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<Type> effects) {
- value.collectEffects(effects);
- }
@Override
public void setLocationDeep(long loc) {
public Expression getValue() {
return value;
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- }
@Override
public Expression accept(ExpressionTransformer transformer) {
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;
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;
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;
this.variable = variable;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- int id = allVars.get(variable);
- if(id >= 0)
- vars.add(id);
- }
+ @Override
+ public Set<Variable> 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<Variable> vars) {
- vars.add(variable);
+ public IVal toVal(CompilationContext context, CodeWriter w) {
+ return variable.getVal();
}
@Override
ArrayList<Expression> parameters) {
}
- @Override
- public void removeFreeVariables(THashSet<Variable> vars) {
- vars.remove(variable);
- }
-
@Override
public Expression resolveAsPattern(TranslationContext context) {
return this;
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<Type> effects) {
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION)
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) {
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;
this.expression = expression;
this.pattern = pattern;
}
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- expression.collectRefs(allRefs, refs);
- pattern.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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) {
throw new InternalCompilerError(location, "EViewPattern.toVal should not be invoked.");
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- throw new InternalCompilerError(location, "Cannot collect free variables for a pattern.");
- }
-
- @Override
- public void removeFreeVariables(THashSet<Variable> 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?");
}
}
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- expression = expression.decorate(decorator);
- return this;
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- expression.collectEffects(effects);
- }
-
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
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;
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;
this.variables = variables;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- query.collectRefs(allRefs, refs);
- action.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- query.collectVars(allVars, vars);
- action.collectVars(allVars, vars);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectEffects.");
- }
-
@Override
protected void updateType() throws MatchException {
setType(Types.UNIT);
}
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- action.collectFreeVariables(vars);
- query.collectFreeVariables(vars);
- for(Variable var : variables)
- vars.remove(var);
- }
-
@Override
public Expression resolve(TranslationContext context) {
context.pushExistentialFrame();
variables = context.popExistentialFrame();
return this;
}
-
- @Override
- public Expression decorate(ExpressionDecorator decorator) {
- return decorator.decorate(this);
- }
@Override
public Expression replace(ReplaceContext context) {
public Expression getAction() {
return action;
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- query.forVariables(procedure);
- action.forVariables(procedure);
- }
@Override
public Expression simplify(SimplificationContext context) {
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;
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;
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 {
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;
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<Variable> constraints = new ArrayList<Variable>(2);
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);
else
break;
}
- }
- return checkBasicType(context, requiredType);
- }
+ }
+ return checkBasicType(context, requiredType);
+ }
- public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);
- public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
- public abstract void forVariables(VariableProcedure procedure);
-
- public Expression decomposeMatching() {
+ public final void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ accept(new CollectRefsVisitor(allRefs, refs));
+ }
+
+ public final void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
+ accept(new CollectVarsVisitor(allVars, vars));
+ }
+
+ public final void forVariableUses(VariableProcedure procedure) {
+ accept(new ForVariablesUsesVisitor(procedure));
+ }
+
+ public Expression decomposeMatching() {
return this;
}
return new ELambdaType(vars, this);
}
- public abstract void collectFreeVariables(THashSet<Variable> vars);
-
public Expression simplify(SimplificationContext context) {
System.out.println("#############################");
System.out.println(this);
public void getParameters(TranslationContext translationContext,
ArrayList<Expression> 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<Variable> 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<Variable> getFreeVariables() {
- THashSet<Variable> result = new THashSet<Variable>();
- collectFreeVariables(result);
- return result;
- }
+ /**
+ * Used during simplification and in toIExpression
+ */
+ public Set<Variable> getFreeVariables() {
+ CollectFreeVariablesVisitor visitor = new CollectFreeVariablesVisitor();
+ accept(visitor);
+ return visitor.getFreeVariables();
+ }
public static Expression[] concat(Expression[] a, Expression[] b) {
if(a.length == 0)
}
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) {
public Expression applyType(Type type) {
return new EApplyType(location, this, type);
}
-
- public abstract Expression decorate(ExpressionDecorator decorator);
public boolean isEffectful() {
return true;
return false;
}
- public abstract void collectEffects(THashSet<Type> effects);
-
public Type getEffect() {
- THashSet<Type> effects = new THashSet<Type>();
- 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);
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);
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);
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 {
value.replace(context));
}
- public void decorate(ExpressionDecorator decorator) {
- for(int i=0;i<guards.length;++i)
- guards[i] = guards[i].decorate(decorator);
- value = value.decorate(decorator);
- }
-
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
location = loc;
value.setLocationDeep(loc);
}
}
-
- public void forVariables(VariableProcedure procedure) {
- for(Expression guard : guards)
- guard.forVariables(procedure);
- value.forVariables(procedure);
- }
}
import org.simantics.scl.compiler.internal.codegen.references.IVal;
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.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 GuardedExpressionGroup extends Expression {
public GuardedExpression[] expressions;
this.expressions = expressions;
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> 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<Variable> 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());
//throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");
}
- @Override
- public void collectFreeVariables(THashSet<Variable> 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) {
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<Type> effects) {
- for(GuardedExpression ge : expressions) {
- for(Expression guard : ge.guards)
- guard.collectEffects(effects);
- ge.value.collectEffects(effects);
- }
- }
@Override
public void setLocationDeep(long loc) {
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);
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;
this.fieldName = fieldName;
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- fieldName.collectFreeVariables(vars);
- }
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- fieldName.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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);
public void accept(FieldAccessorVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- fieldName.forVariables(procedure);
- }
}
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;
this.accessSeparator = accessSeparator;
}
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- }
-
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- }
-
- public void collectFreeVariables(THashSet<Variable> 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();
public abstract void setLocationDeep(long loc);
public abstract void accept(FieldAccessorVisitor visitor);
-
- public abstract void forVariables(VariableProcedure procedure);
}
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 {
public void accept(FieldAccessorVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
}
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 {
public void accept(FieldAccessorVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- }
}
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;
}
@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
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;
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;
pattern.checkTypeAsPattern(context, value.getType());
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- value.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> 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<Variable> variables = pattern.getFreeVariables();
+ Set<Variable> variables = pattern.getFreeVariables();
Variable[] variableArray = variables.toArray(new Variable[variables.size()]);
Expression[] variableExps = new Expression[variableArray.length];
for(int i=0;i<variableArray.length;++i)
pattern = pattern.resolveAsPattern(context);
}
- @Override
- public void decorate(ExpressionDecorator decorator) {
- value = value.decorate(decorator);
- pattern = pattern.decorate(decorator);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- pattern.collectEffects(effects);
- value.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
visitor.visit(this);
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- }
-
@Override
public ListQualifier accept(ListQualifierTransformer transformer) {
return transformer.transform(this);
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;
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;
pattern.checkTypeAsPattern(context, componentType);
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- value.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- value.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- value.collectFreeVariables(vars);
- pattern.collectFreeVariables(vars);
- }
-
@Override
public CompiledQualifier compile(SimplificationContext context) {
if(pattern instanceof EVariable)
return new CompiledQualifier(value, pattern);
else {
- THashSet<Variable> variables = pattern.getFreeVariables();
+ Set<Variable> variables = pattern.getFreeVariables();
Variable[] variableArray = variables.toArray(new Variable[variables.size()]);
Expression[] variableExps = new Expression[variableArray.length];
for(int i=0;i<variableArray.length;++i)
value = value.resolve(context);
pattern = pattern.resolveAsPattern(context);
}
-
- @Override
- public void decorate(ExpressionDecorator decorator) {
- value = value.decorate(decorator);
- pattern = pattern.decorate(decorator);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- pattern.collectEffects(effects);
- value.collectEffects(effects);
- }
-
+
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
visitor.visit(this);
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- value.forVariables(procedure);
- }
-
@Override
public ListQualifier accept(ListQualifierTransformer transformer) {
return transformer.transform(this);
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;
condition.checkType(context, Types.BOOLEAN);
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- condition.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- condition.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- condition.collectFreeVariables(vars);
- }
-
@Override
public CompiledQualifier compile(SimplificationContext context) {
return new CompiledQualifier(
@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<Type> effects) {
- condition.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
visitor.visit(this);
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- condition.forVariables(procedure);
- }
-
@Override
public ListQualifier accept(ListQualifierTransformer transformer) {
return transformer.transform(this);
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<Object> allRefs, TIntHashSet refs);
- public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
- public abstract void collectFreeVariables(THashSet<Variable> 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<Type> 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);
}
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;
a.checkType(context);
b.checkType(context);
}
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- a.collectRefs(allRefs, refs);
- b.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- a.collectVars(allVars, vars);
- b.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- b.collectFreeVariables(vars);
- a.collectFreeVariables(vars);
- }
@Override
public CompiledQualifier compile(SimplificationContext context) {
b.resolve(context);
}
- @Override
- public void decorate(ExpressionDecorator decorator) {
- a.decorate(decorator);
- b.decorate(decorator);
- }
-
- @Override
- public void collectEffects(THashSet<Type> effects) {
- a.collectEffects(effects);
- b.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
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);
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;
}
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- left.collectRefs(allRefs, refs);
- transformer.collectRefs(allRefs, refs);
- if(by != null)
- by.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- left.collectVars(allVars, vars);
- transformer.collectVars(allVars, vars);
- if(by != null)
- by.collectVars(allVars, vars);
- }
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- left.collectFreeVariables(vars);
- transformer.collectFreeVariables(vars);
- if(by != null)
- by.collectFreeVariables(vars);
- }
-
@Override
public CompiledQualifier compile(SimplificationContext context) {
CompiledQualifier q = left.compile(context);
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<Type> effects) {
- left.collectEffects(effects);
- transformer.collectEffects(effects);
- if(by != null)
- by.collectEffects(effects);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
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) {
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;
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;
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('\\');
}
b.append('"');
}
+
+ @Override
+ public void visit(EAmbiguous eAmbiguous) {
+ b.append("EAmbigious");
+ }
}
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;
this.name = name;
this.value = value;
}
+
+ public FieldAssignment replace(ReplaceContext context) {
+ return new FieldAssignment(name, value == null ? null : value.replace(context));
+ }
}
--- /dev/null
+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<Type> effects = new THashSet<Type>();
+
+ @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()]));
+ }
+}
--- /dev/null
+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<Variable> freeVariables = new THashSet<Variable>();
+
+ 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<Variable> getFreeVariables() {
+ return freeVariables;
+ }
+}
--- /dev/null
+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<Object> allRefs;
+ private final TIntHashSet refs;
+
+ public CollectRefsVisitor(TObjectIntHashMap<Object> 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);
+ }
+ }
+}
--- /dev/null
+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<Variable> allVars;
+ private final TIntHashSet vars;
+
+ public CollectVarsVisitor(TObjectIntHashMap<Variable> 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);
+ }
+}
--- /dev/null
+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);
+ }
+}
-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;
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;
}
statement.value = statement.value.accept(this);
}
+ public void transform(CHRQuery query) {
+ for(CHRLiteral lit : query.literals)
+ for(int i=0;i<lit.parameters.length;++i)
+ lit.parameters[i] = lit.parameters[i].accept(this);
+ }
+
public void transform(CHRRuleset ruleset) {
for(CHRRule rule : ruleset.rules) {
- for(CHRLiteral lit : rule.head.literals)
- for(int i=0;i<lit.parameters.length;++i)
- lit.parameters[i] = lit.parameters[i].accept(this);
- for(CHRLiteral lit : rule.body.literals)
- for(int i=0;i<lit.parameters.length;++i)
- lit.parameters[i] = lit.parameters[i].accept(this);
+ transform(rule.head);
+ transform(rule.body);
}
}
return expression;
}
+ @Override
+ public Expression transform(ECHRSelect expression) {
+ expression.expression = expression.expression.accept(this);
+ transform(expression.query);
+ return expression;
+ }
+
@Override
public Expression transform(ECHRRulesetConstructor expression) {
transform(expression.ruleset);
@Override
public void visit(CHRStatement statement) {
- for(int i=0;i<statement.body.length;++i)
- statement.body[i] = statement.body[i].accept(this);
- for(int i=0;i<statement.head.length;++i)
- statement.head[i] = statement.head[i].accept(this);
+ statement.head.accept(this);
+ statement.body.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstAtom query) {
+ query.expression = query.expression.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstBinds query) {
+ query.left = query.left.accept(this);
+ query.right = query.right.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstConjunction query) {
+ for(CHRAstQuery conjunct : query.conjuncts)
+ conjunct.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstEquals query) {
+ query.left = query.left.accept(this);
+ query.right = query.right.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstNegation query) {
+ query.subquery.accept(this);
}
}
-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.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.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.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.ExpressionVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
+import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessorVisitor;
import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
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.ListQualifierVisitor;
import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
public class StandardExpressionVisitor implements
ExpressionVisitor, QueryVisitor, FieldAccessorVisitor, ListQualifierVisitor,
-EquationVisitor, StatementVisitor {
+EquationVisitor, StatementVisitor, CHRAstQueryVisitor {
@Override
public void visit(EApply expression) {
expression.pattern.accept(this);
expression.value.accept(this);
expression.in.accept(this);
+ if(expression.monadEvidence != null)
+ visit(expression.monadEvidence);
}
@Override
public void visit(ELet expression) {
for(Assignment assignment : expression.assignments)
visit(assignment);
+ expression.in.accept(this);
}
public void visit(Assignment assignment) {
expression.query.accept(this);
expression.expression.accept(this);
}
+
+ @Override
+ public void visit(ECHRSelect expression) {
+ visit(expression.query);
+ expression.expression.accept(this);
+ }
@Override
public void visit(ESimpleLambda expression) {
equation.accept(this);
}
+ public void visit(CHRLiteral literal) {
+ for(Expression parameter : literal.parameters)
+ parameter.accept(this);
+ }
+
+ public void visit(CHRQuery query) {
+ for(CHRLiteral literal : query.literals)
+ visit(literal);
+ }
+
+ public void visit(CHRRule rule) {
+ visit(rule.head);
+ visit(rule.body);
+ }
+
public void visit(CHRRuleset ruleset) {
- for(CHRRule rule : ruleset.rules) {
- for(CHRLiteral literal : rule.head.literals)
- for(Expression parameter : literal.parameters)
- parameter.accept(this);
- for(CHRLiteral literal : rule.body.literals)
- for(Expression parameter : literal.parameters)
- parameter.accept(this);
- }
+ for(CHRRule rule : ruleset.rules)
+ visit(rule);
+ for(IncludeStatement include : ruleset.includes)
+ include.value.accept(this);
}
@Override
@Override
public void visit(CHRStatement statement) {
- for(ListQualifier q : statement.body)
- q.accept(this);
- for(ListQualifier q : statement.head)
- q.accept(this);
+ statement.body.accept(this);
+ statement.head.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstAtom query) {
+ query.expression.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstBinds query) {
+ query.left.accept(this);
+ query.right.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstConjunction query) {
+ for(CHRAstQuery conjunct : query.conjuncts)
+ conjunct.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstEquals query) {
+ query.left.accept(this);
+ query.right.accept(this);
+ }
+
+ @Override
+ public void visit(CHRAstNegation query) {
+ query.subquery.accept(this);
+ }
+
+ @Override
+ public void visit(EAmbiguous expression) {
+ if(expression.resolvedExpression != null)
+ expression.resolvedExpression.accept(this);
}
}
import org.simantics.scl.compiler.common.precedence.Precedence;
import org.simantics.scl.compiler.constants.BooleanConstant;
import org.simantics.scl.compiler.constants.Constant;
-import org.simantics.scl.compiler.constants.JavaConstructor;
import org.simantics.scl.compiler.constants.JavaStaticField;
import org.simantics.scl.compiler.constants.JavaStaticMethod;
import org.simantics.scl.compiler.constants.NoRepConstant;
public class Builtins extends ConcreteModule {
- public static SCLValue[] TUPLE_CONSTRUCTORS = new SCLValue[Constants.MAX_TUPLE_LENGTH+1];
- public static SCLValue[] LIST_CONSTRUCTORS = new SCLValue[Constants.MAX_LIST_LITERAL_LENGTH+1];
+ public static final SCLValue[] TUPLE_CONSTRUCTORS = new SCLValue[Constants.MAX_TUPLE_LENGTH+1];
+ public static final SCLValue[] LIST_CONSTRUCTORS = new SCLValue[Constants.MAX_LIST_LITERAL_LENGTH+1];
- public static final Builtins INSTANCE = new Builtins();
+ public static Builtins INSTANCE = new Builtins();
public static SCLValue Nothing;
public static SCLValue Just;
new Constructor(Locations.NO_LOCATION, MaybeType.INSTANCE, Just.getName(), new Type[] {MaybeType.INSTANCE.parameters[0]}, null)
);
+ // *** Dynamic ***
+
+ addValue("Dynamic", DynamicConstructor.INSTANCE);
+
// *** Vector ***
TypeClass VecCompC = new TypeClass(Locations.NO_LOCATION,
return documentation;
}
+ public static void flush() {
+ INSTANCE = new Builtins();
+ }
+
}
public String toString() {
return "Check";
}
+
+ @Override
+ public Type getEnforceEffect() {
+ return Types.NO_EFFECTS;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return Types.NO_EFFECTS;
+ }
}
--- /dev/null
+package org.simantics.scl.compiler.elaboration.java;
+
+import org.cojen.classfile.TypeDesc;
+import org.objectweb.asm.Label;
+import org.simantics.scl.compiler.constants.FunctionValue;
+import org.simantics.scl.compiler.constants.LocalVariableConstant;
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+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.kinds.Kinds;
+
+/**
+ * Dynamic :: a -> 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));
+ }
+}
public String toString() {
return "=";
}
-
+
+ @Override
+ public Type getEnforceEffect() {
+ return Types.NO_EFFECTS;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return Types.NO_EFFECTS;
+ }
}
public String toString() {
return "Execute";
}
-
+
+ @Override
+ public Type getEnforceEffect() {
+ return Types.NO_EFFECTS;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return Types.NO_EFFECTS;
+ }
}
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";
result = new EApplyType(result, var);
return result;
}
-
+
+ public static void flush() {
+ INSTANCE = new JavaModule();
+ }
}
public String toString() {
return "<-";
}
+
+ @Override
+ public Type getEnforceEffect() {
+ return Types.NO_EFFECTS;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return Types.NO_EFFECTS;
+ }
}
public String toString() {
return "Statement";
}
+
+ @Override
+ public Type getEnforceEffect() {
+ return GRAPH;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return GRAPH;
+ }
});
addEntityType("Resource", new SCLEntityType() {
@Override
public String toString() {
return "Optional";
}
+
+ @Override
+ public Type getEnforceEffect() {
+ return Types.NO_EFFECTS;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return Types.NO_EFFECTS;
+ }
}
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<Variable> vars) {
- for(Query query : queries)
- query.collectFreeVariables(vars);
- }
@Override
public Query resolve(TranslationContext context) {
query.checkType(context);
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- for(Query query : queries)
- query.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
- for(Query query : queries)
- query.collectVars(allVars, vars);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
query.setLocationDeep(loc);
}
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- for(Query query : queries)
- query.forVariables(procedure);
- }
}
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<Variable> vars) {
- query.collectFreeVariables(vars);
- }
@Override
public Query resolve(TranslationContext context) {
query.checkType(context);
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- query.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- query.collectVars(allVars, vars);
- }
-
@Override
public void setLocationDeep(long loc) {
if(location == Locations.NO_LOCATION) {
query.setLocationDeep(loc);
}
}
-
- @Override
- public void forVariables(VariableProcedure procedure) {
- query.forVariables(procedure);
- }
}
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 {
this.parameters = parameters;
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(Expression parameter : parameters)
- parameter.collectFreeVariables(vars);
- }
-
@Override
public void checkType(TypingContext context) {
// Type parameters
}
else {
optionalVariableByParameter[i] = -1;
- parameter.forVariables(procedure);
+ parameter.forVariableUses(procedure);
}
}
}
}
}
- private static void collectRefs(SCLRelation relation, TObjectIntHashMap<Object> 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<Object> allRefs,
- TIntHashSet refs) {
- collectRefs(relation, allRefs, refs);
- for(Expression parameter : parameters)
- parameter.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- for(Expression parameter : parameters)
- parameter.collectVars(allVars, vars);
- }
-
@Override
public Query replace(ReplaceContext context) {
Type[] newTypeParameters;
visitor.visit(this);
}
- @Override
- public void forVariables(VariableProcedure procedure) {
- for(Expression parameter : parameters)
- parameter.forVariables(procedure);
- }
-
@Override
public void splitToPhases(TIntObjectHashMap<ArrayList<Query>> result) {
int phase = relation.getPhase();
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;
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);
this(variables.toArray(new Variable[variables.size()]), query);
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- super.collectFreeVariables(vars);
- for(Variable variable : variables)
- vars.remove(variable);
- }
-
@Override
public void checkType(TypingContext context) {
for(Variable var : variables)
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);
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;
this.thenQuery = thenQuery;
this.elseQuery = elseQuery;
}
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- condition.collectFreeVariables(vars);
- thenQuery.collectFreeVariables(vars);
- elseQuery.collectFreeVariables(vars);
- }
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
- condition.collectRefs(allRefs, refs);
- thenQuery.collectRefs(allRefs, refs);
- elseQuery.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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);
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) {
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;
this.parameters = parameters;
}
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- for(Expression parameter : parameters)
- parameter.collectFreeVariables(vars);
- }
-
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- for(Expression parameter : parameters)
- parameter.collectRefs(allRefs, refs);
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> allVars,
- TIntHashSet vars) {
- for(Expression parameter : parameters)
- parameter.collectVars(allVars, vars);
- }
-
@Override
public void checkType(TypingContext context) {
// Check parameter types
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) {
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;
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<Variable> vars);
- public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);
- public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
public abstract void checkType(TypingContext context);
public Query resolve(TranslationContext context) {
});
}
- public abstract void forVariables(VariableProcedure procedure);
-
public TIntObjectHashMap<ArrayList<Query>> splitToPhases() {
TIntObjectHashMap<ArrayList<Query>> result = new TIntObjectHashMap<ArrayList<Query>>(2);
splitToPhases(result);
}
public abstract Query accept(QueryTransformer transformer);
+
+ public void forVariables(VariableProcedure procedure) {
+ accept(new ForVariablesUsesVisitor(procedure));
+ }
+ public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+ accept(new CollectRefsVisitor(allRefs, refs));
+ }
+
+ public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
+ accept(new CollectVarsVisitor(allVars, vars));
+ }
}
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
*/
public ArrayList<Variable> extraVariables = new ArrayList<Variable>(2);
public ArrayList<Query> sideQueries = new ArrayList<Query>(2);
-
- @Override
- public void collectFreeVariables(THashSet<Variable> vars) {
- throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectFreeVariables.");
- }
@Override
public void checkType(TypingContext context) {
throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectConstraints.");
}
- @Override
- public void collectRefs(TObjectIntHashMap<Object> allRefs,
- TIntHashSet refs) {
- throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectRefs.");
- }
-
- @Override
- public void collectVars(TObjectIntHashMap<Variable> 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.");
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.");
- }
}
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;
+ }
}
public String toString() {
return name;
}
+
+ @Override
+ public Type getEnforceEffect() {
+ return Types.PROC;
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return Types.PROC;
+ }
}
long location,
Expression[] parameters,
Expression[] typeConstraintEvidenceParameters);
+ Type getEnforceEffect();
+ Type getQueryEffect();
}
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;
return new SCLRelation[] { baseRelation };
}
+ @Override
+ public Type getEnforceEffect() {
+ return baseRelation.getEnforceEffect();
+ }
+
+ @Override
+ public Type getQueryEffect() {
+ return baseRelation.getQueryEffect();
+ }
+
}
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);
public void log(CompilationError error) {
errors.add(error);
- if(error.severity == ErrorSeverity.ERROR)
+ if(error.severity != ErrorSeverity.WARNING)
++errorCount;
}
package org.simantics.scl.compiler.errors;
public enum ErrorSeverity {
- ERROR,
- WARNING
+ ERROR,
+ IMPORT_ERROR,
+ WARNING
}
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
}
// 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();
// 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();
SSABlock headBlock = getParent();
SSAFunction thisFunction = headBlock.getParent();
+ if(thisFunction == function)
+ return;
/*System.out.println("--- INLINING -------------------------------");
System.out.println(thisFunction);
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;
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);
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;
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()));
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;
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()));
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;
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;
}
};
for(QMapping mapping : decomposed.targetMappings)
- mapping.parameters[0].forVariables(check);
+ mapping.parameters[0].forVariableUses(check);
sourceVariables = sourceVariableList.toArray(new Variable[sourceVariableList.size()]);
}
}
else {
PatternAnalyzer analyzer = new PatternAnalyzer(variableSet, mappedVariableUseCount);
- expression.forVariables(analyzer);
+ expression.forVariableUses(analyzer);
if(analyzer.containsVariables)
semiopenMappings.add(mapping);
// Default action
final THashSet<Variable> dependences = new THashSet<Variable>();
- expression.forVariables(new VariableProcedure() {
+ expression.forVariableUses(new VariableProcedure() {
@Override
public void execute(long location, Variable variable) {
+++ /dev/null
-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);
-
-}
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
| (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
| 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
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); }
}
case 175: break;
case 81:
- { return sym(SCLTerminals.SELECT);
+ { return sym(supportCHR() ? SCLTerminals.CHR_SELECT : SCLTerminals.SELECT);
}
case 176: break;
case 82:
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;
"SELECT_DISTINCT",
"TRANSFORMATION",
"EQ",
+ "CHR_SELECT",
"ATTACHED_DOT",
"IN",
"THEN",
"accessor",
"case",
"queryBlock",
+ "verboseChrQuery",
"stringLiteral",
"symbolWithoutMinus",
"listQualifier",
"chrQuery",
- "verboseChrQuery",
- "constraintSpec",
+ "chrQueryPart",
"caseRhs",
"guardedExpArrow",
"equation",
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);
}
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:
*/
protected abstract Object reduceVerboseCHRStatement();
/**
- * statement ::= CONSTRAINT constructor (WHERE constraintSpec)?
+ * statement ::= CONSTRAINT constructor
*/
protected abstract Object reduceConstraintStatement();
/**
* 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
*/
* 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
*/
*/
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)?
*/
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;
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;
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<query.length;++i)
- query[i] = (ListQualifier)get(i*2);
- return query;
- }
-
/*
@Override
protected Object reduceWhen() {
new QConjunction((Query[])get(1)),
(Expression)get(3));
}*/
-
- @Override
- protected Object reduceVerboseCHRQuery() {
- ListQualifier[] query = new ListQualifier[(length()-1)/2];
- for(int i=0;i<query.length;++i)
- query[i] = (ListQualifier)get(i*2+1);
- return query;
- }
-
- @Override
- protected Object reduceVerboseCHRStatement() {
- return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));
- }
@Override
protected Object reduceDummy() {
return new IncludeStatement(name, value);
}
- @Override
+ /*@Override
protected Object reduceConstraintSpec() {
Expression[] expressions = new Expression[length()/2-1];
for(int i=0;i<expressions.length;++i)
expressions[i] = (Expression)get(2*i+1);
return expressions;
+ }*/
+
+ @Override
+ protected Object reduceCHRSelect() {
+ return new EPreCHRSelect((CHRAstQuery)get(3), (Expression)get(1));
+ }
+
+ @Override
+ protected Object reduceCHRAtom() {
+ return CHRAstAtom.atom((Expression)get(0));
+ }
+
+ @Override
+ protected Object reduceCHREquals() {
+ return new CHRAstEquals((Expression)get(0), (Expression)get(2));
+ }
+
+ @Override
+ protected Object reduceCHRBinds() {
+ return new CHRAstBinds((Expression)get(0), (Expression)get(2));
+ }
+
+ @Override
+ protected Object reduceCHRConjunction() {
+ CHRAstQuery[] conjuncts = new CHRAstQuery[(length()+1)/2];
+ for(int i=0;i<conjuncts.length;++i)
+ conjuncts[i] = (CHRAstQuery)get(i*2);
+ return CHRAstConjunction.conjunction(conjuncts);
+ }
+
+ @Override
+ protected Object reduceVerboseCHRConjunction() {
+ CHRAstQuery[] conjuncts = new CHRAstQuery[(length()-1)/2];
+ for(int i=0;i<conjuncts.length;++i)
+ conjuncts[i] = (CHRAstQuery)get(i*2+1);
+ return CHRAstConjunction.conjunction(conjuncts);
+ }
+
+ @Override
+ protected Object reduceVerboseCHRStatement() {
+ return new CHRStatement((CHRAstQuery)get(1), (CHRAstQuery)get(3));
+ }
+
+ @Override
+ protected Object reduceCHRStatement() {
+ return new CHRStatement((CHRAstQuery)get(0), (CHRAstQuery)get(2));
}
}
public static final int SELECT_DISTINCT = 61;
public static final int TRANSFORMATION = 62;
public static final int EQ = 63;
- public static final int ATTACHED_DOT = 64;
- public static final int IN = 65;
- public static final int THEN = 66;
- public static final int ELSE = 67;
- public static final int WITH = 68;
- public static final int RBRACKET = 69;
- public static final int DOTDOT = 70;
- public static final int AT = 71;
- public static final int SUSPEND_STRING = 72;
- public static final int CONTINUE_STRING = 73;
- public static final int BINDS = 74;
- public static final int IMPLIES = 75;
- public static final int THEN_AFTER_WHEN = 76;
- public static final int CONSTRAINT = 77;
- public static final int BY = 78;
- public static final int QUERY_OP = 79;
- public static final int FORALL = 80;
- public static final int COMMENT = 81;
- public static final int EOL = 82;
- public static final int EOF = 83;
+ public static final int CHR_SELECT = 64;
+ public static final int ATTACHED_DOT = 65;
+ public static final int IN = 66;
+ public static final int THEN = 67;
+ public static final int ELSE = 68;
+ public static final int WITH = 69;
+ public static final int RBRACKET = 70;
+ public static final int DOTDOT = 71;
+ public static final int AT = 72;
+ public static final int SUSPEND_STRING = 73;
+ public static final int CONTINUE_STRING = 74;
+ public static final int BINDS = 75;
+ public static final int IMPLIES = 76;
+ public static final int THEN_AFTER_WHEN = 77;
+ public static final int CONSTRAINT = 78;
+ public static final int BY = 79;
+ public static final int QUERY_OP = 80;
+ public static final int FORALL = 81;
+ public static final int COMMENT = 82;
+ public static final int EOL = 83;
+ public static final int EOF = 84;
}
-package org.simantics.scl.compiler.markdown.html;
+package org.simantics.scl.compiler.markdown.html;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
b.append("</td><td class=\"content\">\n");
}
addContentsTree(b, result);
- result.toHtml(b);
+ result.toHtml(HtmlGenerationContext.DEFAULT, b);
if(navigation != null)
b.append("</td></tr></table>\n");
--- /dev/null
+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);
+}
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;
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 {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("<a href=\"");
if(email)
b.append("mailto:");
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
public class BlockQuoteNode extends Node {
@Override
public boolean canContain(Node node) {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("<blockquote>\n");
- super.toHtml(b);
+ super.toHtml(context, b);
b.append("</blockquote>\n");
}
}
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 {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
if(infoString == null || infoString.isEmpty())
b.append("<pre><code>");
else {
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 {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("<code>");
b.append(HtmlEscape.escape(stringContent));
b.append("</code>");
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
public class EmphNode extends Node {
boolean strong;
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
if(strong)
b.append("<strong>");
else
b.append("<em>");
- super.toHtml(b);
+ super.toHtml(context, b);
if(strong)
b.append("</strong>");
else
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 {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("::").append(extension).append('[').append(content).append(']');
}
}
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("<br />\n");
}
}
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
public class HeaderNode extends Node {
public int level;
}
@Override
- public void toHtml(StringBuilder b) {
- b.append("<h").append(level).append(" id=\"");
- toPlainText(b);
- b.append("\">");
- super.toHtml(b);
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
+ b.append("<h").append(level);
+ if(context.generateAnchors) {
+ b.append(" id=\"");
+ toPlainText(b);
+ b.append("\">");
+ }
+ else
+ b.append('>');
+ super.toHtml(context, b);
b.append("</h").append(level).append(">\n");
}
}
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("<hr />\n");
}
}
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
public class HtmlNode extends Node {
public HtmlNode() {
}
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append(stringContent);
b.append('\n');
}
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);
}
}
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 {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("<img src=\"").append(HtmlEscape.escapeURL(url))
.append("\" alt=\"");
toPlainText(b);
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
public class ItemNode extends Node {
public int indentation;
return true;
}
- public void toHtml(StringBuilder b) {
- toHtml(b, true);
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
+ toHtml(context, b, true);
}
- public void toHtml(StringBuilder b, boolean tight) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b, boolean tight) {
if(firstChild == null) {
b.append("<li></li>\n");
return;
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 {
b.append('\n');
noNewline = false;
}
- child.toHtml(b);
+ child.toHtml(context, b);
}
}
b.append("</li>\n");
}
else {
b.append("<li>\n");
- super.toHtml(b);
+ super.toHtml(context, b);
b.append("</li>\n");
}
}
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 {
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("<a href=\"").append(HtmlEscape.escapeURL(url));
if(title.isEmpty())
b.append("\">");
b.append(HtmlEscape.escape(title));
b.append("\">");
}
- super.toHtml(b);
+ super.toHtml(context, b);
b.append("</a>");
}
}
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
public class ListNode extends Node {
public char bulletChar;
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
if(bulletChar == '+' || bulletChar == '-' || bulletChar == '*') {
b.append("<ul>\n");
for(Node child = firstChild; child != null; child = child.next)
- ((ItemNode)child).toHtml(b, tight);
+ ((ItemNode)child).toHtml(context, b, tight);
b.append("</ul>\n");
}
else {
else
b.append("<ol start=\"").append(start).append("\">\n");
for(Node child = firstChild; child != null; child = child.next)
- ((ItemNode)child).toHtml(b, tight);
+ ((ItemNode)child).toHtml(context, b, tight);
b.append("</ol>\n");
}
}
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;
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<HeaderNode> extractHeaders() {
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);
package org.simantics.scl.compiler.markdown.nodes;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
public class ParagraphNode extends Node {
@Override
return true;
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append("<p>");
- super.toHtml(b);
+ super.toHtml(context, b);
b.append("</p>\n");
}
}
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 {
this.stringContent = text;
}
@Override
- public void toHtml(StringBuilder b) {
+ public void toHtml(HtmlGenerationContext context, StringBuilder b) {
b.append(HtmlEscape.escape(stringContent));
}
@Override
}
}
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");
//builder.visualize();
- builder.printParseTable();
+ //builder.printParseTable();
return builder.getParseTable();
}
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;
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;
THashMap<String, ModuleSource> modules = new THashMap<String, ModuleSource>();
THashMap<String, String> documentations = new THashMap<String, String>();
+ THashMap<String, ArrayList<UpdateListener>> listeners = new THashMap<String, ArrayList<UpdateListener>>();
+
public MapModuleSourceRepository() {
}
public void addModuleDescriptor(ModuleSource descriptor) {
modules.put(descriptor.getModuleName(), descriptor);
+ synchronized (listeners) {
+ ArrayList<UpdateListener> list = listeners.get(descriptor.getModuleName());
+ if(list != null)
+ for(UpdateListener listener : list.toArray(new UpdateListener[list.size()]))
+ listener.notifyAboutUpdate();
+ }
}
public void addModule(Module module) {
@Override
public ModuleSource getModuleSource(String moduleName,
UpdateListener listener) {
+ if(listener != null) {
+ synchronized(listeners) {
+ ArrayList<UpdateListener> list = listeners.get(moduleName);
+ if(list == null) {
+ list = new ArrayList<UpdateListener>(2);
+ listeners.put(moduleName, list);
+ }
+ list.add(listener);
+ }
+ listener.addObservable(new Observable() {
+ @Override
+ public void removeListener(UpdateListener listener) {
+ synchronized(listeners) {
+ ArrayList<UpdateListener> list = listeners.get(moduleName);
+ if(list != null) {
+ list.remove(listener);
+ if(list.isEmpty())
+ listeners.remove(moduleName);
+ }
+ }
+ }
+ });
+ }
return modules.get(moduleName);
}
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;
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();
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;
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;
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<TCon, Name> DECORATION_MAP = new THashMap<TCon, Name>();
+
+ 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<TCon> concreteEffects = new ArrayList<TCon>();
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;
}
-
}
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: .
--- /dev/null
+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
--- /dev/null
+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);
+ }
+
+}
@JavaName create
createList :: [Resource] -> <WriteGraph> Resource
+
+ @JavaName create
+ createList :: Resource -> [Resource] -> <WriteGraph> Resource
@javaName insertBack
insertBack :: Resource -> [Resource] -> <WriteGraph> ()
"""
variable :: String -> <ReadGraph> Variable
+ @JavaName getPossibleVariable
+ possibleVariable :: String -> <ReadGraph> Maybe Variable
+
@JavaName getVariable
"""
Function **resourceVariable** converts a resource to a corresponding variable.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+.settings
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.simantics.scl.rest</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+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
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ scl/
--- /dev/null
+importJava "org.simantics.scl.rest.SCLRESTServer" where
+ start :: String -> Integer -> <Proc> ()
+ stop :: <Proc> ()
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * 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!");
+ }
+ }
+
+}
--- /dev/null
+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<String, CommandSessionWithModules> 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);
+ }
+}
--- /dev/null
+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<String, Object> buildJSONResponse(Object... keyValues) {
+ if ((keyValues.length % 2) != 0)
+ throw new IllegalArgumentException("Invalid amount of arguments! " + Arrays.toString(keyValues));
+ Map<String, Object> 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();
+ }
+
+}
--- /dev/null
+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;
+ }
+}
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
--- /dev/null
+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
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
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;
+ }
}
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,
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") );
}
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;
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;
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);
}
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;
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());
}
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 <code>position</code>.
+ *
+ * @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 <code>position</code>.
+ *
+ * @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);
+ }
+ }
+ }
+
}
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)
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
@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
--- /dev/null
+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 <code>IDocument</code> based implementation of
+ * <code>CharacterIterator</code> and <code>CharSequence</code>. Note that
+ * the supplied document is not copied; if the document is modified during the
+ * lifetime of a <code>DocumentCharacterIterator</code>, the methods
+ * returning document content may not always return the same values. Also, if
+ * accessing the document fails with a {@link BadLocationException}, any of
+ * <code>CharacterIterator</code> methods as well as <code>charAt</code>may
+ * 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 <code>first</code>.
+ *
+ * @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 <code>first</code> (inclusive) to
+ * <code>last</code> (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}
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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();
+ }
+ }
+}
--- /dev/null
+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.
+ * <p>
+ * A line break may be any of "\n", "\r", "\r\n", "\n\r".
+ * </p>
+ *
+ * @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 <code>true</code> if this run consumes <code>ch</code>,
+ * <code>false</code> otherwise. If <code>true</code> is returned,
+ * the length of the receiver is adjusted accordingly.
+ *
+ * @param ch the character to test
+ * @return <code>true</code> if <code>ch</code> 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 <code>consume</code>.
+ *
+ * @param ch the character to test
+ * @return <code>true</code> if <code>ch</code> 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 <code>ch</code>
+ */
+ 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$
+ }
+ }
+}
--- /dev/null
+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 <code>true</code> if the given sequence into the underlying text
+ * represents a delimiter, <code>false</code> otherwise.
+ *
+ * @param offset the offset
+ * @param exclusiveEnd the end offset
+ * @return <code>true</code> 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 <code>true</code> if the given sequence into the underlying text
+ * represents whitespace, but not a delimiter, <code>false</code> otherwise.
+ *
+ * @param offset the offset
+ * @param exclusiveEnd the end offset
+ * @return <code>true</code> 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 <code>CharSequence</code>.
+ * @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);
+ }
+
+}
--- /dev/null
+package org.simantics.scl.ui.editor2.iterator;
+
+import java.text.CharacterIterator;
+
+import org.eclipse.core.runtime.Assert;
+
+
+
+/**
+ * A <code>CharSequence</code> based implementation of <code>CharacterIterator</code>.
+ *
+ * @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();
+ }
+ }
+}
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");
}
});
--- /dev/null
+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<String,Bundle> findGoodBundles() {
+ BundleContext context = Activator.getInstance().getBundle().getBundleContext();
+ THashMap<String,Bundle> result = new THashMap<String,Bundle>();
+ 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<String,Bundle> 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;
+ }
+}
--- /dev/null
+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<String,Bundle> 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<Entry> entries = new ArrayList<Entry>(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();
+ }
+}
--- /dev/null
+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<moduleName.length();++i) {
+ char c = moduleName.charAt(i);
+ if(!Character.isLetter(c) && !Character.isDigit(c) && c != '_')
+ return false;
+ }
+ return true;
+ }
+}
--- /dev/null
+package org.simantics.scl.ui.modulebrowser;
+
+import java.util.Collection;
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
+import org.eclipse.ui.dialogs.SearchPattern;
+import org.osgi.framework.Bundle;
+import org.simantics.scl.ui.Activator;
+
+public class PluginSelectionDialog extends FilteredItemsSelectionDialog {
+
+ private static final String PLUGIN_SELECTION_DIALOG = "PLUGIN_SELECTION_DIALOG";
+
+ public static class Entry {
+ Bundle bundle;
+ int packageMatchLength;
+ public Entry(Bundle bundle, int packageMatchLength) {
+ this.bundle = bundle;
+ this.packageMatchLength = packageMatchLength;
+ }
+ }
+ Collection<Entry> entries;
+
+ public PluginSelectionDialog(Shell shell, Collection<Entry> 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<Entry> comparator = new Comparator<Entry>() {
+ @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();
+ }
+
+}
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;
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) {
}
});
+ // 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
localStateChange();
for(IExperimentListener listener : listeners.getListeners())
listener.stateChanged(newState);
+ EXPERIMENT_STATE_READ.run();
}
}
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);
}
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;
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();
}
@MOD.sclAction "createSTSTestAction"
ACTIONS.RunSTSTest
@MOD.sclAction "runSTSTestAction"
+ACTIONS.IgnoreSTSTest
+ @MOD.sclAction "ignoreSTSTestAction"
ACTIONS.NewSTSVariable
@MOD.sclAction "createSTSVariableAction"
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
importJava "org.simantics.tests.modelled.ui.TestsUIUtils" where
runSTSTestAction :: Resource -> <Proc> ()
+ ignoreSTSTestAction :: [Resource] -> <Proc> ()
createSTSSuiteAction :: Resource -> <Proc> ()
createSTSSuiteAction res = do
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 {
view.currentTest(test);
view.execute();
}
+
+ public static void ignoreSTSTestAction(List<Resource> 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);
+ }
+ }
+ });
+ }
}
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;
}
public List<CommandSessionVariable> run(List<CommandSessionVariable> 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() {
// // }
// // }
// return new ModuleCompilationOptions(coverage);
-// }
+ // }
// });
SCLReportingHandler handler = (SCLReportingHandler) SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER);
return result;
} finally {
// remember to flush this repository
- repo.flush();
+// repo.flush();
+ Builtins.flush();
+ JavaModule.flush();
}
}
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;
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
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;
+ }
}
VP.FailTest <T VP.Test
L0.HasDescription "A test that is compatible with all content types and always fails, i.e. returns false."
+
+VP.HasURITest <T VP.Test
+ L0.HasDescription "A test that checks the Resource or Variable given as input has a proper URI."
+
+VP.InDevelopmentModeTest <T VP.Test
+ L0.HasDescription "A test that directly invokes org.eclipse.runtime.core.Platform.inDevelopmentMode()."
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="com.fasterxml.jackson.core.jackson-annotations"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.fasterxml.jackson.core.jackson-databind"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
<feature
id="org.simantics.sdk"
label="Simantics SDK"
- version="1.30.0"
+ version="1.31.0"
provider-name="VTT Technical Research Centre of Finland">
<description url="http://www.example.com/description">
<li>Simantics R - <a href="https://www.simantics.org:8088/r/gitweb?p=simantics/r.git;a=summary">simantics/r.git</a></li>\r
<li>FMIL - <a href="https://www.simantics.org:8088/r/gitweb?p=simantics/fmil.git;a=summary">simantics/fmil.git</a></li>\r
<li>FMI Studio - <a href="https://www.simantics.org:8088/r/gitweb?p=members/fmi.git;a=summary">members/fmi.git</a></li>\r
-<li>Simupedia - <a href="https://www.simantics.org/svn/members/simupedia">Members SVN</a></li>\r
+<li>Simupedia - <a href="https://www.simantics.org:8088/r/gitweb?p=members/simupedia.git;a=summary">members/simupedia.git</a></li>\r
</ul>\r
<p>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.</p>\r
<hr />\r
<h2>Tag release/* branches</h2>\r
<p>When the release branches are ready for the release, tag them with the tag <code>vx.y.z[.w]</code>:</p>\r
<pre><code>git clone ssh://<user>@www.simantics.org:29418/simantics/platform.git\r
-cd platform \r
+cd platform\r
git checkout release/x.y.z[.w]\r
git tag vx.y.z[.w] -m "Simantics x.y.z[.w] simultaneous release"\r
git push origin --tags\r
</ul>\r
<h2>Disseminate information about the release</h2>\r
<ul>\r
-<li><a href="http://dev.simantics.org">Developer Wiki</a>: Update roadmap at http://dev.simantics.org/index.php/Roadmap</li>\r
-<li><a href="https://www.simantics.org/redmine/">Redmine</a>: Post news on the developer/user-visible changes here.</li>\r
+<li><a href="http://dev.simantics.org">Developer Wiki</a>: Update roadmap at <a href="http://dev.simantics.org/index.php/Roadmap">http://dev.simantics.org/index.php/Roadmap</a></li>\r
+<li><a href="https://www.simantics.org/redmine/">Redmine</a>: Post news on the developer/user-visible changes here</li>\r
<li><a href="https://www.simantics.org">simantics.org</a>: Post news on the release and a link to the redmine post</li>\r
<li><a href="https://www.simantics.org/members/">Members Wiki</a>: Update frame plan to reflect the realized dates and link to Redmine news</li>\r
<li><a href="mailto:simantics-developers@simantics.org">mailto:simantics-developers@simantics.org</a> Send "newsletter" to `simantics-developers@simantics.org:</li>\r
</ul>\r
<p><strong>Newsletter template:</strong></p>\r
<pre><code>Hello everyone,\r
- \r
+\r
Simantics release x.y.z[.w] has been released. Head over to\r
https://www.simantics.org/redmine/news/<news number>\r
for the release news.\r
<hr />\r
<h1>TODO</h1>\r
<ul>\r
+<li>Start using <a href="https://github.com/mbarbero/fr.obeo.releng.targetplatform">https://github.com/mbarbero/fr.obeo.releng.targetplatform</a> to generate <code>.target</code> files. <code>.tpd</code> files allow specifying version ranges instead of specific versions.</li>\r
+</ul>\r
+<ul>\r
<li>Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release\r
<ul>\r
<li>Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio</li>\r
</li>\r
</ul>\r
<ul>\r
-<li>\r
-<p>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</p>\r
-</li>\r
-<li>\r
-<p>Start using https://github.com/mbarbero/fr.obeo.releng.targetplatform to generate <code>.target</code> files. <code>.tpd</code> files allow specifying version ranges instead of specific versions.</p>\r
-</li>\r
+<li>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</li>\r
</ul>\r
\r
</body>\r
* 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.
## 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:
# 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
<unit id="com.fasterxml.jackson.core.jackson-annotations.source" version="2.8.4"/>
<unit id="com.fasterxml.jackson.core.jackson-core" version="2.8.8"/>
<unit id="com.fasterxml.jackson.core.jackson-core.source" version="2.8.8"/>
+<unit id="com.fasterxml.jackson.core.jackson-databind" version="2.8.8"/>
+<unit id="com.fasterxml.jackson.core.jackson-databind.source" version="2.8.8"/>
<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv" version="2.8.8"/>
<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv.source" version="2.8.8"/>
<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-xml" version="2.8.8"/>
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
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
<target name="Simantics 1.30.0 Oxygen" sequenceNumber="1500622610">
<unit id="com.fasterxml.jackson.core.jackson-annotations.source" version="2.8.4"/>
<unit id="com.fasterxml.jackson.core.jackson-core" version="2.8.8"/>
<unit id="com.fasterxml.jackson.core.jackson-core.source" version="2.8.8"/>
+ <unit id="com.fasterxml.jackson.core.jackson-databind" version="2.8.8"/>
+ <unit id="com.fasterxml.jackson.core.jackson-databind.source" version="2.8.8"/>
<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv" version="2.8.8"/>
<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-csv.source" version="2.8.8"/>
<unit id="com.fasterxml.jackson.dataformat.jackson-dataformat-xml" version="2.8.8"/>
<repository location="http://www.simantics.org/download/private/eclipse-4.7/external-components/manual"/>
</location>
<location includeMode="slicer" includeAllPlatforms="true" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
- <unit id="org.simantics.sdk.feature.group" version="1.30.0"/>
- <unit id="org.simantics.sdk.source.feature.group" version="1.30.0"/>
+ <unit id="org.simantics.sdk.feature.group" version="1.31.0"/>
+ <unit id="org.simantics.sdk.source.feature.group" version="1.31.0"/>
<repository location="http://www.simantics.org/download/private/eclipse-4.7/sdk"/>
</location>
</locations>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>org.simantics.sdk.repository</artifactId>
- <version>1.30.0-SNAPSHOT</version>
+ <version>1.31.0-SNAPSHOT</version>
<packaging>eclipse-repository</packaging>
<parent>
# 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
#sonar.language=cobol
# Additional parameters
-#sonar.my.property=value
\ No newline at end of file
+#sonar.my.property=value
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
-public class MemoryLeakTest {
+public class MemoryLeakExperiment {
ModuleRepository moduleRepository;
EnvironmentSpecification environmentSpecification;
@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(); }
@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(); }
@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(); }
--- /dev/null
+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());
+ }
+ }
+}
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;
}
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);
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
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
--- /dev/null
+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
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