]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merge branch 'master' into private/eclipse-4.7 19/819/5
authorMiro Richard Eklund <miro.eklund@semantum.fi>
Wed, 9 Aug 2017 06:53:38 +0000 (09:53 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 9 Aug 2017 09:43:11 +0000 (12:43 +0300)
Resolved Conflicts:
releng/org.simantics.sdk.build.targetdefinition/simantics.target

refs #7358

Change-Id: Idefea4e4c60de59664904bdd0a2a0a517af8db4c

304 files changed:
bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java
bundles/org.simantics.browsing.ui.model/adapters.xml
bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/HasURITest.java [new file with mode: 0644]
bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/InDevelopmentModeTest.java [new file with mode: 0644]
bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tooltips/DescriptionTooltipRule.java
bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java
bundles/org.simantics.db.impl/src/org/simantics/db/impl/ForEachObjectContextProcedure.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/DomainProcessor3.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSource.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Subgraphs.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/TGRepresentationUtils.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/RVI.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/IntHash.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ObjectTable.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTable.java
bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java
bundles/org.simantics.db/src/org/simantics/db/procedure/AsyncContextMultiProcedure.java
bundles/org.simantics.db/src/org/simantics/db/service/CollectionSupport.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/NodeRequest.java
bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/layer/GraphLayerManager.java
bundles/org.simantics.document.base.ontology/graph/ConnectionPoints.pgraph
bundles/org.simantics.document.server.io/META-INF/MANIFEST.MF
bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/CommandContextImpl.java
bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/ITreeTableCell.java
bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/JSONObjectUtils.java
bundles/org.simantics.document.server/src/org/simantics/document/server/DocumentServerUtils.java
bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java
bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequest.java
bundles/org.simantics.document.server/src/org/simantics/document/server/request/NodeRequestUtils.java
bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java
bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/AWTImage.java
bundles/org.simantics.g2d/src/org/simantics/g2d/participant/RulerPainter.java
bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java
bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java [new file with mode: 0644]
bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java
bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java
bundles/org.simantics.history/src/org/simantics/history/csv/URIs.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeverityRecursive.java
bundles/org.simantics.issues.common/src/org/simantics/issues/common/MaxIssueSeveritySingle.java
bundles/org.simantics.issues.ontology/graph/Issue.pgraph
bundles/org.simantics.layer0/graph/Layer0List.pgraph
bundles/org.simantics.modeling.ontology/graph/Modeling.pgraph
bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph
bundles/org.simantics.modeling.ui/adapters.xml
bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/e4/ImportSVGPNG.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromIssue.java
bundles/org.simantics.modeling/adapters.xml
bundles/org.simantics.modeling/scl/Simantics/Diagram.scl
bundles/org.simantics.modeling/src/org/simantics/modeling/ComponentTypeScriptRequest.java
bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java
bundles/org.simantics.modeling/src/org/simantics/modeling/actions/CopyURI.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java
bundles/org.simantics.modeling/src/org/simantics/modeling/svg/CreateSVGElement.java
bundles/org.simantics.platform.ui.ontology/graph/PlatformUIViews.pgraph
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ImageNode.java
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/RulerNode.java
bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/names/Names.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRQuery.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRuleset.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRQueryTranslationMode.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AccessFactOp.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/AssignOp.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/plan/PlanOp.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/planning/QueryPlanningContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/CHRConstraint.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/ExternalCHRRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/SpecialCHRRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/relations/UnresolvedCHRRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/ReplaceContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqBasic.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/EqGuard.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/equation/Equation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ASTExpression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Assignment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/DecoratingExpression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApply.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EApplyType.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAsPattern.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBind.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRuleset.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRRulesetConstructor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEnforce.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEquations.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EError.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EExternalConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EFieldAccess.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EGetConstraint.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIf.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EIntegerLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambda.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELambdaType.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELet.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListComprehension.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EListLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ELiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EMatch.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPlaceholder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreRuleset.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERealLiteral.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERuleset.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESelect.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLet.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETransformation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ETypeAnnotation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EVariable.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EWhen.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionTransformer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ExpressionVisitor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpressionGroup.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/ExpressionAccessor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/FieldAccessor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/IdAccessor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/accessor/StringAccessor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListAssignment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGenerator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListGuard.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListQualifier.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListSeq.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/list/ListThen.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/printing/ExpressionToStringVisitor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/records/FieldAssignment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectEffectsVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectRefsVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectVarsVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/ForVariablesUsesVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/StandardExpressionTransformer.java [moved from bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java with 74% similarity]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/StandardExpressionVisitor.java [moved from bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionVisitor.java with 67% similarity]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/CheckRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/DynamicConstructor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/EqRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ExecuteRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MemberRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/OptionalRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractCombiner.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAbstractModifier.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QAtom.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QExists.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QIf.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QMapping.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/pre/PreQuery.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/ConcreteRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/LocalRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/SCLRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/relations/TransitiveClosureRelation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorLog.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/ErrorSeverity.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetApply.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/MethodBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching/PatternMatchingCompiler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/matching2/PatternMatchingCompiler2.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/profiling/BranchPointInjector.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/TransformationBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/UnifiableFactory.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/utils/ExpressionDecorator.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.flex
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLTerminals.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlDocumentationGeneration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlGenerationContext.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/MarkdownParser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/AutolinkNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/BlockQuoteNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeBlockNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/CodeNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/EmphNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ExtensionBlockNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HardLineBreakNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HeaderNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HorizontalRuleNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/HtmlTagNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ImageNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ItemNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/LinkNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ListNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/Node.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/ParagraphNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/nodes/TextNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/generator/table/ParseTableBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/grammar/input/GrammarParser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/MapModuleSourceRepository.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ToplevelEffectDecorator.java
bundles/org.simantics.scl.data/META-INF/MANIFEST.MF
bundles/org.simantics.scl.data/scl/Data/JsonNode.scl [new file with mode: 0644]
bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JsonNodeHelper.java [new file with mode: 0644]
bundles/org.simantics.scl.db/scl/Simantics/DB.scl
bundles/org.simantics.scl.db/scl/Simantics/Variables.scl
bundles/org.simantics.scl.rest/.classpath [new file with mode: 0644]
bundles/org.simantics.scl.rest/.gitignore [new file with mode: 0644]
bundles/org.simantics.scl.rest/.project [new file with mode: 0644]
bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.scl.rest/build.properties [new file with mode: 0644]
bundles/org.simantics.scl.rest/scl/SCL/REST/Server.scl [new file with mode: 0644]
bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/Activator.java [new file with mode: 0644]
bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/AuthorizationFilter.java [new file with mode: 0644]
bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLAPI.java [new file with mode: 0644]
bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTAPI.java [new file with mode: 0644]
bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTServer.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/scl/Prelude.scl
bundles/org.simantics.scl.runtime/scl/SetUtils.scl [new file with mode: 0644]
bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/chr/CHRRuntimeRuleset.java
bundles/org.simantics.scl.ui/META-INF/MANIFEST.MF
bundles/org.simantics.scl.ui/icons/import_error.png [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/Activator.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor/completion/SCLCompletionProposal.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/SCLModuleEditor2DocumentProvider.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/DocumentCharacterIterator.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaBreakIterator.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaWordIterator.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/SequenceCharacterIterator.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/issues/SCLIssuesView.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleAction.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleDialog.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleValidator.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/PluginSelectionDialog.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/SCLModuleBrowser.java
bundles/org.simantics.simulation/src/org/simantics/simulation/experiment/Experiment.java
bundles/org.simantics.spreadsheet.common/src/org/simantics/spreadsheet/common/TreeTableCell.java
bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java
bundles/org.simantics.tests.modelled.ui.ontology/graph/TestsUI.pgraph
bundles/org.simantics.tests.modelled.ui/scl/Simantics/TestsUI.scl
bundles/org.simantics.tests.modelled.ui/src/org/simantics/tests/modelled/ui/TestsUIUtils.java
bundles/org.simantics.tests.modelled/src/org/simantics/tests/modelled/utils/ModelledSTSTest.java
bundles/org.simantics.ui/src/org/simantics/ui/workbench/e4/E4WorkbenchUtils.java
bundles/org.simantics.viewpoint.ontology/graph/ViewpointTests.pgraph
features/org.simantics.scl.feature/feature.xml
features/org.simantics.sdk.feature/feature.xml
releng/doc/release.html
releng/doc/release.md
releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target
releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd
releng/org.simantics.sdk.build.targetdefinition/simantics.target
releng/org.simantics.sdk.repository/pom.xml
sonar-simantics-platform-sdk.properties
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakExperiment.java [moved from tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakTest.java with 98% similarity]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/markdown/MarkdownTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR11.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR12.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR13.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect2.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect3.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Dynamic1.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursionBug.scl [new file with mode: 0644]
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl

index 450ad0618fe84445d68a39427a9095f464d8c81a..c69c7bea6fe7957bf3c408256a6d9f5cbfed16e4 100644 (file)
@@ -20,9 +20,13 @@ import org.simantics.acorn.lru.ClusterStreamChunk;
 import org.simantics.acorn.lru.ClusterUpdateOperation;
 import org.simantics.db.service.ClusterUID;
 import org.simantics.utils.logging.TimeLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MainProgram implements Runnable, Closeable {
 
+       private static final Logger LOGGER = LoggerFactory.getLogger(MainProgram.class);
+       
        private static final int CLUSTER_THREADS = 4;
        private static final int CHUNK_CACHE_SIZE = 100;
 
@@ -260,14 +264,32 @@ public class MainProgram implements Runnable, Closeable {
 
        public Exception runIdle(MainProgramRunnable runnable) {
                try {
-                       mutex.acquire();
-                       runnable.run();
-                       return null;
-               } catch (Exception e) {
-                       return e;
+                       long startTime = System.currentTimeMillis();
+                       while (true) {
+                               boolean hasMutex = false;
+                               try {
+                                       synchronized (MainProgram.this) {
+                                               if (hasMutex = mutex.tryAcquire()) {
+                                                       if (operations.isEmpty()) {
+                                                               runnable.run();
+                                                               return null;
+                                                       }
+                                               }
+                                       }
+                                       long endTime = System.currentTimeMillis(); 
+                                       if ((endTime - startTime) > 100) {
+                                               startTime = endTime; 
+                                               LOGGER.info("MainProgram.runIdle() retry mutex acquire!");
+                                       }
+                               } catch (Exception e) {
+                                       return e;
+                               } finally {
+                                       if (hasMutex)
+                                               mutex.release();
+                               }
+                       }
                } finally {
                        runnable.done();
-                       mutex.release();
                }
        }
        
@@ -297,7 +319,7 @@ public class MainProgram implements Runnable, Closeable {
 
                ClusterStreamChunk last = operations.isEmpty() ? null : operations.getLast();
         if (!alive) {
-            System.err.println("Trying to commit operation after MainProgram is closed! Operation is " + last);
+            LOGGER.error("Trying to commit operation after MainProgram is closed! Operation is " + last);
 //          return;
         }
                if(last != null) last.commit();
@@ -306,7 +328,7 @@ public class MainProgram implements Runnable, Closeable {
 
        public synchronized void schedule(ClusterUpdateOperation operation) throws IllegalAcornStateException {
            if (!alive) {
-               System.err.println("Trying to schedule operation after MainProgram is closed! Operation is " + operation);
+               LOGGER.error("Trying to schedule operation after MainProgram is closed! Operation is " + operation);
 //             return;
            }
                clusters.streamLRU.acquireMutex();
index 50b34347957672a684adf7fb9a5c3c3cc1807964..4276f3febe14de63daf3c8663ab4c7c87a721a17 100644 (file)
             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">
diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/HasURITest.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/HasURITest.java
new file mode 100644 (file)
index 0000000..3443625
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.browsing.ui.model.tests;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.exception.InvalidVariableException;
+import org.simantics.db.layer0.variable.Variable;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.30.0
+ */
+public enum HasURITest implements Test {
+    INSTANCE;
+
+    public static HasURITest get() {
+        return INSTANCE;
+    }
+
+    @Override
+    public boolean isCompatible(Class<?> contentType) {
+        return contentType.equals(Resource.class) || contentType.equals(Variable.class);
+    }
+
+    @Override
+    public boolean test(ReadGraph graph, Object content) throws DatabaseException {
+        if (content instanceof Resource) {
+            return graph.getPossibleURI((Resource) content) != null;
+        } else if (content instanceof Variable) {
+            try {
+                Variable v = (Variable) content;
+                return v.getURI(graph) != null;
+            } catch (InvalidVariableException e) {
+                return false;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/InDevelopmentModeTest.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/tests/InDevelopmentModeTest.java
new file mode 100644 (file)
index 0000000..fa85e25
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.browsing.ui.model.tests;
+
+import org.eclipse.core.runtime.Platform;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.exception.DatabaseException;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.30.0
+ */
+public enum InDevelopmentModeTest implements Test {
+    INSTANCE;
+
+    public static InDevelopmentModeTest get() {
+        return INSTANCE;
+    }
+
+    @Override
+    public boolean isCompatible(Class<?> contentType) {
+        return true;
+    }
+
+    @Override
+    public boolean test(ReadGraph graph, Object content) throws DatabaseException {
+        return Platform.inDevelopmentMode();
+    }
+
+}
index 7bef8e22c127bf00946f7c35f92c8c3f48bcb403..a9ebb9dfcbe26e2aa4e9ba1ff16d46be1ddb9699 100644 (file)
@@ -18,9 +18,9 @@ import org.simantics.db.layer0.variable.Variable;
 import org.simantics.layer0.Layer0;
 
 public class DescriptionTooltipRule implements TooltipRule {
-    
+
     public static final DescriptionTooltipRule INSTANCE = new DescriptionTooltipRule();
-    
+
     public DescriptionTooltipRule() {
     }
 
@@ -58,28 +58,26 @@ public class DescriptionTooltipRule implements TooltipRule {
     public boolean isCompatible(Class<?> contentType) {
         return (contentType == Resource.class || contentType == Variable.class);
     }
-    
+
     private static String getToolTipContent(ReadGraph graph, NodeContext nodeContext) throws DatabaseException {
         Object input = nodeContext.getConstant(BuiltinKeys.INPUT);
-        String content = null;
         if (input instanceof Variable) {
             Variable var = (Variable) input;
-            Resource res = var.getPredicateResource(graph);
-            Layer0 L0 = Layer0.getInstance(graph);
-            String description = graph.getPossibleRelatedValue2(res, L0.HasDescription);
-            return description;
+            Resource res = var.getPossiblePredicateResource(graph);
+            if (res != null) {
+                Layer0 L0 = Layer0.getInstance(graph);
+                return graph.getPossibleRelatedValue2(res, L0.HasDescription);
+            }
         } else if (input instanceof Resource) {
             Resource res = (Resource) input;
-
             Layer0 L0 = Layer0.getInstance(graph);
-            String description = graph.getPossibleRelatedValue2(res, L0.HasDescription);
-            return description;
+            return graph.getPossibleRelatedValue2(res, L0.HasDescription);
         }
-        return content;
+        return null;
     }
 
     @Override
-    public boolean shouldCreateToolTip(ReadGraph graph  , NodeContext context, Map<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;
index 8be698cf121dc124d4f85f5dc9c5474d54014291..15910147ae4d25a50837e50b03e2245b9136e107 100644 (file)
@@ -21,12 +21,13 @@ public class ListUtils {
             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);
@@ -36,12 +37,13 @@ public class ListUtils {
             WriteGraph g, Layer0 L0, Resource list, 
             Resource before, Resource after, 
             Resource[] elements) throws DatabaseException {
+        Resource elementPredicate = getElementPredicate(g, list);
         for(Resource item : elements) {
             Resource cur = g.newResource();
             g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
             g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
             g.claim(before, L0.List_Next, L0.List_Previous, cur);
-            g.claim(cur, L0.List_Element, item);
+            g.claim(cur, elementPredicate, item);
             before = cur;
         }  
         g.claim(before, L0.List_Next, L0.List_Previous, after);
@@ -97,15 +99,20 @@ public class ListUtils {
     }
     
     public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<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);
@@ -142,8 +149,9 @@ public class ListUtils {
 
         Resource node = getNode(g, list, element);
         if(node != null) {
+            Resource elementPredicate = getElementPredicate(g, list);
             g.deny(node, L0.List_Element);
-            g.claim(node, L0.List_Element, replacement);
+            g.claim(node, elementPredicate, replacement);
             return true;
         } else {
             return false;
@@ -191,7 +199,7 @@ public class ListUtils {
         while(!cur.equals(list)) {
             Resource el = g.getPossibleObject(cur, L0.List_Element);
             Resource next = g.getSingleObject(cur, L0.List_Next);
-            if(element.equals(el)) {                
+            if(element.equals(el)) {
                 g.deny(cur);
                 g.claim(prev, L0.List_Next, next);
                 return true;
@@ -213,7 +221,7 @@ public class ListUtils {
         while(!cur.equals(list)) {
             Resource el = g.getPossibleObject(cur, L0.List_Element);
             Resource next = g.getSingleObject(cur, L0.List_Next);
-            if(elements.contains(el)) {                
+            if(elements.contains(el)) {
                 g.deny(cur);
                 g.claim(prev, L0.List_Next, next);
                 removed = true;
@@ -264,7 +272,7 @@ public class ListUtils {
         Resource prev = g.getSingleObject(node, L0.List_Previous);
         if(list.equals(prev))
             return false;
-        swap(g, node, prev);
+        swap(g, list, node, prev);
         return true;
     }
     
@@ -276,11 +284,11 @@ public class ListUtils {
         Resource next = g.getSingleObject(node, L0.List_Next);
         if(list.equals(next))
             return false;
-        swap(g, node, next);
+        swap(g, list, node, next);
         return true;
     }
 
-    private static void swap(WriteGraph g, Resource a, Resource b) throws DatabaseException {
+    private static void swap(WriteGraph g, Resource list, Resource a, Resource b) throws DatabaseException {
         Layer0 L0 = Layer0.getInstance(g);
         Resource ea = g.getPossibleObject(a, L0.List_Element);
         Resource eb = g.getPossibleObject(b, L0.List_Element);
@@ -288,11 +296,26 @@ public class ListUtils {
         g.deny(a, L0.List_Element);
         g.deny(b, L0.List_Element);
         
+        Resource elementPredicate = getElementPredicate(g, list);
+        
         if(eb != null)
-            g.claim(a, L0.List_Element, eb);
+            g.claim(a, elementPredicate, eb);
         if(ea != null)
-            g.claim(b, L0.List_Element, ea);
+            g.claim(b, elementPredicate, ea);
     }
 
+    public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate);
+        if(predicate != null) return predicate;
+       return g.isInstanceOf(list, L0.ListWithInverses) ?
+                       L0.List_ElementWithInverse : L0.List_Element; 
+    }
+
+    public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+       return g.getSingleObject(element, L0.IsOwnedBy);
+    }
+    
     
 }
index 07d385235cfc7d32ccc633e95b66c4f14db8aeda..188917994a26881ccafe58a313ac6cb4559c2a67 100644 (file)
@@ -32,8 +32,8 @@ public final class ForEachObjectContextProcedure<C> implements AsyncContextMulti
        }
 
        @Override
-       public void finished(AsyncReadGraph graph) {
-               user.finished(graph);
+       public void finished(AsyncReadGraph graph, C context) {
+               user.finished(graph, context);
        }
 
        @Override
index 488545c5fec781c80876b9cf7035f8b0eed31c06..2347fa99e5c0e7331b3fbd12d04f3705371af52e 100644 (file)
@@ -70,58 +70,64 @@ public class EntityInstances implements Instances {
         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;
index 9ec12047c6c501a0dc2a58a836c3f69d073a10fe..4162f91636d0b39dfb193d7bb93c076e9885b849 100644 (file)
@@ -145,7 +145,7 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
                                }
 
                                @Override
-                               public void finished(AsyncReadGraph graph) {
+                               public void finished(AsyncReadGraph graph, Resource parent) {
                                }
 
                                @Override
index d910f13ff946a77e40d9b2dce830c2020c678f40..a2e64868f7c21d43c1456c4662810c20f6ca4ed6 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.db.layer0.util;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -17,22 +18,25 @@ import org.simantics.db.procedure.AsyncContextMultiProcedure;
 import org.simantics.db.procedure.Procedure;
 import org.simantics.db.service.DirectQuerySupport;
 import org.simantics.layer0.Layer0;
+import org.simantics.utils.datastructures.Pair;
 
 class ConsistsOfProcess {
 
        final List<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;
@@ -46,7 +50,7 @@ class ConsistsOfProcess {
                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
@@ -58,8 +62,16 @@ class ConsistsOfProcess {
                                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
@@ -76,9 +88,19 @@ class ConsistsOfProcess {
                        }
 
                        @Override
-                       public void finished(AsyncReadGraph graph) {
+                       public void finished(AsyncReadGraph graph, InternalEntry entry) {
+                           if(entry.valid) {
+                               if(entry.name != null) {
+                                   result.add(entry);
+                               } else {
+                                   // This one did not have a name - not a valid internal
+                                   childrenWithNoName.add(entry.resource);
+                               }
+                           } else {
+                               // Something wrong has happened. Do not treat as valid internal
+                               childrenWithNoName.add(entry.resource);
+                           }
                        }
-
                });
                
                structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncContextMultiProcedure<InternalEntry, Resource>() {
@@ -90,16 +112,14 @@ class ConsistsOfProcess {
                                
                                if(!ignoreVirtual || child.isPersistent()) {
                                        InternalEntry entry = new InternalEntry(parent, child, null);
-                                       if(result.add(entry)) {
-                                               dqs.forEachObjectCompiled(graph, child, entry, structure);
-                                               dqs.forEachObjectCompiled(graph, child, entry, names);
-                                       }
+                                       dqs.forEachObjectCompiled(graph, child, entry, structure);
+                                       dqs.forEachObjectCompiled(graph, child, entry, names);
                                }
                                
                        }
 
                        @Override
-                       public void finished(AsyncReadGraph graph) {
+                       public void finished(AsyncReadGraph graph, InternalEntry parent) {
                        }
 
                        @Override
index bd67680db6704f73bbe3a73d69aaa7774f8d3b5f..7a0a5f06bee35eb5c4eebf87691dd8e8bdf97c3a 100644 (file)
@@ -34,6 +34,7 @@ import org.simantics.db.service.TransferableGraphSupport;
 import org.simantics.graph.db.TransferableGraphSource;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.runtime.function.Function1;
+import org.simantics.utils.datastructures.Pair;
 
 import gnu.trove.list.array.TIntArrayList;
 import gnu.trove.map.hash.TIntIntHashMap;
@@ -504,7 +505,8 @@ public class DomainProcessor3 {
             this.datatypeBinding = Bindings.getBindingUnchecked(Datatype.class);
             this.datatypeSerializer = graph.getService(Databoard.class).getSerializerUnchecked(this.datatypeBinding);
 
-            state.internalEntries = ConsistsOfProcess.walk(graph, status, fringe, exclusions, ignoreVirtual); 
+            Pair<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;
@@ -518,6 +520,12 @@ public class DomainProcessor3 {
                 }
             }
 
+            for(Resource unnamedChild : pair.second) {
+                if (status.put(unnamedChild, ExtentStatus.INTERNAL) == null) {
+                    fringe.add(unnamedChild);
+                }
+            }
+            
             if (state.monitor.isCanceled())
                 throw new CancelTransactionException();
 
index f0a0893eb447d40455835d39fdd41cc40d6e3c5f..1d3cf61f54c6c6ad296b06a959f62dac66601537 100644 (file)
@@ -416,8 +416,12 @@ public class ModelTransferableGraphSource implements TransferableGraphSource {
                
                if(state.internalEntries != null) {
                        for(InternalEntry ie : state.internalEntries) {
-                               if(ie.parent != null && ie.name != null) {
-                                       procedure.execute(resolveInternal(graph, support, ie, internalMap));
+                           if(ie.parent != null) {
+                               if(ie.name != null) {
+                                   procedure.execute(resolveInternal(graph, support, ie, internalMap));
+                           } else {
+                               // In this case there is a child that has no HasName => this should be treated as a blank
+                               }
                                } else {
                                        throw new DatabaseException("Invalid internal entry " + ie);
                                }
index c7e697e6291773b58e44d8bd3a8c2afbf0952442..518efc882e45964dafb612ced7068636972a6f6b 100644 (file)
@@ -991,7 +991,8 @@ public class Subgraphs {
              * ï¿½ 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) {
@@ -1003,6 +1004,12 @@ public class Subgraphs {
                                }
                        }
                        
+                       for(Resource unnamedChild : pair.second) {
+                           if (status.put(unnamedChild, ExtentStatus.INTERNAL) == null) {
+                               fringe.add(unnamedChild);
+                           }
+                       }
+                       
                        /*
                         * This loop resolves the transitive closure of all p < IsRelatedTo such that p does not contain the SharedRange tag.
                         * Such resources are guaranteed to be internal.
index ffa39974315a1a06b50c57aada1816ae2677130e..0bd71af863fa4330b94b01969aff6e736c7c46b4 100644 (file)
@@ -14,6 +14,7 @@ package org.simantics.db.layer0.util;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.simantics.datatypes.literal.GUID;
 import org.simantics.db.ReadGraph;
@@ -26,6 +27,7 @@ import org.simantics.db.layer0.util.ConsistsOfProcess.InternalEntry;
 import org.simantics.db.layer0.util.DomainProcessor3.ExclusionDecision;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.runtime.function.Function1;
+import org.simantics.utils.datastructures.Pair;
 
 /**
  * @author Antti Villberg
@@ -63,7 +65,8 @@ public class TGRepresentationUtils {
                         return new GUIDExclusionFunction(graph);
 
                     // The root is OK - check everything beneath
-                    List<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);
index 3d527e03957509764e7daebf23ff27e01fd59999..d9366b132aa2a41e471bf0cd2ea7d1c9b19cef96 100644 (file)
@@ -302,7 +302,7 @@ public abstract class AbstractVariable implements Variable {
                if(Variables.TYPE.equals(key)) return getTypeVariable();
                else if(Variables.URI.equals(key)) return getURIVariable();
                
-                       return variable;
+                       return null;
                }
        
     }
index daae9b9c32f76cf5bc9a1c8b699aee6661f47f19..a5f22c83c1a44233bcce46550aefdab8a1b39dec 100644 (file)
@@ -407,8 +407,8 @@ public class RVI extends Bean {
                                        }
                                }
                        }
-                       if (str.indexOf(":", pos+1) > -1) {
-                           String x = str.substring(pos+1, end);
+                       if (str.indexOf(":", pos) > -1) {
+                           String x = str.substring(pos, end);
                            if (!x.isEmpty()) {
                                String[] parts = x.split(":");
                                if (parts.length == 3) {
index 355764d178138df429450ab7eac5ab565dac8d00..40b2530f2a569a4dedfdb7295095895871074f1d 100644 (file)
@@ -1139,11 +1139,14 @@ public final class ClusterTable implements IClusterTable {
         if(exist != null) return exist;
 
         ClusterI cluster = getClusterByResourceKey(id);
-        boolean result = cluster == null ? false : cluster.getImmutable();
-
-        markImmutable(cluster, result);
-        return result;
-
+        if(cluster == null) {
+               return false;
+        } else {
+               boolean result = cluster.getImmutable();
+               markImmutable(cluster, result);
+               return result;
+        }
+        
     }
 
     public void markImmutable(ClusterI cluster, boolean value) {
index 5f9a8993ec61b313c2f57ca2438da6277be71348..37c89ff5f4dee3d0ac0a8fd0abd6b2a21207702b 100644 (file)
@@ -633,6 +633,11 @@ public class CollectionSupportImpl implements CollectionSupport {
                this.backend = new TIntArrayList();
        }
 
+       ResourceList(SessionImplSocket session, int capacity) {
+               this.session = session;
+               this.backend = new TIntArrayList(capacity);
+       }
+
        ResourceList(SessionImplSocket session, Collection<Resource> rs) {
                this.session = session;
                this.backend = new TIntArrayList(rs.size());
@@ -853,6 +858,11 @@ public class CollectionSupportImpl implements CollectionSupport {
                return new ResourceList(session);
        }
 
+       @Override
+       public List<Resource> createList(int capacity) {
+               return new ResourceList(session, capacity);
+       }
+
     static final class StatementList implements Collection<Statement> {
        
        final private SessionImplSocket session;
index ea1c779faff615a3fdd256d69c8f95d8dcbb132d..1d3563fc1a3b5fca63688dca04a52c4805bdee50 100644 (file)
@@ -306,7 +306,7 @@ public class QuerySupportImpl implements QuerySupport {
                        
                 }
                        }
-                       procedure.finished(graph);
+                       procedure.finished(graph, context);
 //             graph.dec();
                return;
                
index 69450de7c8efc045e6aa6bab583e1c668f5a3507..c0ead5d073744444305acdf0247903c5f2593337 100644 (file)
@@ -304,7 +304,7 @@ public class IntHash extends IntHashTrait {
 
        }
        
-       procedure.finished(graph);
+       procedure.finished(graph, context);
 //     graph.dec();
        assert(size == count);
        
index 42ca6b018dd9348c5309f75e31084838c862ea73..da3b7903e7e270f2f1f6f5885ba12a3900700690 100644 (file)
@@ -167,7 +167,7 @@ public final class ObjectTable extends Table<int[]> {
        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;
         }
index 23d15dcfdb13fe6a10a7af104a5537fb18079d22..90519a36c3f6cb5916c7429c5af8e8ca41414deb 100644 (file)
@@ -477,7 +477,7 @@ public final class ResourceElementSmall {
         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
             int completeRef = getCompleteObjectRef(table, index);
             if (0 == completeRef) {
-                procedure.finished(graph);
+                procedure.finished(graph, context);
 //                graph.state.dec(0);
                 return; // no objects for given complete type
             }
@@ -496,19 +496,19 @@ public final class ResourceElementSmall {
             } else { // One complete type element. CompleteRef is resource reference.
                 ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index);
                 if (pCompleteType != rCompleteType) {
-                    procedure.finished(graph);
+                    procedure.finished(graph, context);
 //                    graph.state.dec(0);
                     return; // Complete predicate does not match.
                 }
                 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef)));
             }
-            procedure.finished(graph);
+            procedure.finished(graph, context);
 //            graph.state.dec(0);
             return; // loop finished
         }
         short p1 = getStm1Predicate(table, index);
         if (0 == p1) {
-            procedure.finished(graph);
+            procedure.finished(graph, context);
 //            graph.state.dec(0);
             return; // loop finished, no statements
         }
@@ -525,7 +525,7 @@ public final class ResourceElementSmall {
         }
         short p2 = getStm2Predicate(table, index);
         if (0 == p2 || pRef != p2) {
-            procedure.finished(graph);
+            procedure.finished(graph, context);
 //            graph.state.dec(0);
             return; // loop finished, one statements
         }
@@ -539,7 +539,7 @@ public final class ResourceElementSmall {
 //            return true; // loop broken by procedure
 //        return false; // loop finished
         procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2)));
-        procedure.finished(graph);
+        procedure.finished(graph, context);
 //        graph.state.dec(0);
     }
 
index 84090af415e944ce757687706c2b7f67d646f71d..e997b731870159486a38cfebab9a2b7eb64f7c36 100644 (file)
@@ -514,7 +514,7 @@ final class ResourceElement {
         if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
             int completeRef = getCompleteObjectRef(table, index);
             if (0 == completeRef) {
-                       procedure.finished(graph);
+                       procedure.finished(graph, context);
 //                     graph.state.dec(0);
                 return; // no objects for given complete type
             }
@@ -543,14 +543,14 @@ final class ResourceElement {
                 ForeachObject t = new ForeachObject();
                 // CompleteRef is complete object set index.
                 ct.foreachComplete(completeRef, t, null, support, modifier);
-                procedure.finished(graph);
+                procedure.finished(graph, context);
 //                graph.state.dec(0);
                 return; // loop finished
             }
             // one complete type element
             ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
             if (pCompleteType != completeType) {
-                       procedure.finished(graph);
+                       procedure.finished(graph, context);
 //                     graph.state.dec(0);
                 return;
             }
@@ -562,7 +562,7 @@ final class ResourceElement {
                 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
                 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(externalRef)));
             }
-               procedure.finished(graph);
+               procedure.finished(graph, context);
 //             graph.state.dec(0);
             return; // loop finished
         }
@@ -570,7 +570,7 @@ final class ResourceElement {
         long l = table[i];
         int p1 = (int) (l >>> 32);
         if (0 == p1) {
-               procedure.finished(graph);
+               procedure.finished(graph, context);
 //             graph.state.dec(0);
             return; // loop finished, no statements
         }
@@ -588,13 +588,13 @@ final class ResourceElement {
         long l2 = table[++i];
         int p2 = (int) (l2 >>> 32);
         if (pRef != p2) {
-               procedure.finished(graph);
+               procedure.finished(graph, context);
 //             graph.state.dec(0);
             return; // loop finished, one statements
         }
         int o2 = (int)l2;
         procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2)));
-               procedure.finished(graph);
+               procedure.finished(graph, context);
 //             graph.state.dec(0);
     }
     
index df5920c47b611463a08025aa9428c678666abf1d..2c57f3627323ebdfcb88d050df524c32fd09fcf3 100644 (file)
@@ -184,7 +184,7 @@ final class TableIntArraySet {
             
         }
         
-               procedure.finished(graph);
+               procedure.finished(graph, context);
 //             graph.state.dec(0);
         
     }
index 875ee37abe6dab1cb37e4a6e0568e2c883630bd1..c393d32dad8dc5d9753e8c02f32df2fe8755c687 100644 (file)
@@ -43,7 +43,7 @@ public interface AsyncContextMultiProcedure<Context, Result> {
      * 
      * @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
index aa522203d3a0a88eac043842a0deae436005a890..d5cebc8644d1e4bbf73fc4c9adfd3936a2cdfa20 100644 (file)
@@ -38,6 +38,7 @@ public interface CollectionSupport {
        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();
index a6f2e0a77f4f354c146f98d52e38072a0f1cb7fd..198b4b341114616aa75137b7a719f8162ccaf40d 100644 (file)
@@ -11,6 +11,8 @@
  *******************************************************************************/
 package org.simantics.diagram.adapter;
 
+import java.util.List;
+
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.primitiverequest.Adapter;
@@ -20,6 +22,7 @@ import org.simantics.db.procedure.Listener;
 import org.simantics.diagram.synchronization.ErrorHandler;
 import org.simantics.g2d.canvas.ICanvasContext;
 import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.SubstituteElementClass;
 import org.simantics.g2d.element.ElementClass;
 import org.simantics.g2d.element.IElement;
 import org.slf4j.Logger;
@@ -110,8 +113,12 @@ public class NodeRequest extends BaseRequest2<Resource, IElement> {
                             }
 
                             @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
index 41947ef993c49bc937b39eedddb0a0cbf3d25460..e92ce1b41da779df96b1d08359241a7b959fa6b1 100644 (file)
@@ -433,8 +433,10 @@ public class GraphLayerManager {
                 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() + "'");
@@ -452,8 +454,10 @@ public class GraphLayerManager {
                 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() + "'");
index cb396fc8440c1ac7cc5de97e8f28f8c2c92ed92c..655df56660a2e31d5d53178b549311c201820f4a 100644 (file)
@@ -189,14 +189,14 @@ defCommandConnectionPoint : L0.Template
 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"
index b860e19bf4c39d1784d18faa933d1b1fa1c0c1c5..4b14c09b66207393b5b1561f18bd1493697c8c08 100644 (file)
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 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
index 5b49810fad9f8109c5a4a637ab24444ea3bf059c..5fb3a283e93a0b635768e5517fc1b3e6f14ac50d 100644 (file)
@@ -66,6 +66,12 @@ public class CommandContextImpl implements CommandContextMutable {
                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());
                        }
index 9bf10fb3a67d4ad2c1dc7fb23a4bc56b81be9652..1849273d1d59bf41e693a46ad640dac4800698ac 100644 (file)
@@ -1,11 +1,9 @@
 package org.simantics.document.server.io;
 
 public interface ITreeTableCell extends ITableCell {
-    
-       int getParent();
-       
-        Object getData();
 
-     boolean isEditable();
+       int getParent();
+       Object getData();
+    boolean isEditable();
      
 }
index 558ee320459e519823852eac43d654763e90906f..004166dc0c39bf387dd471b9b8617bb8c8853885 100644 (file)
@@ -314,6 +314,26 @@ public class JSONObjectUtils {
         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")
index 4821bbd1ca0e4c48a1cbe71210d1e53acb2c20be..5e1f5cc30e798aff45343b8f8c5f4483b6d8a9cc 100644 (file)
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -324,8 +325,24 @@ public class DocumentServerUtils {
                        for(Variable attrib : statics) {
                                String name = attrib.getName(graph);
                                try {
-                                   Object value = DocumentServerUtils.getValue(graph, attrib);
-                                   object.addJSONField(name, value);
+                                       if (name.equals(NodeRequest.PROPERTY_VALUE_EXCEPTIONS)) {
+                                       @SuppressWarnings("unchecked")
+                                               Map<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)
index 6ccffbe973ddecdeef07e4a8bcbdaebe3acf52e2..13444fdba944701e2454fea1174283d89045f8ca 100644 (file)
@@ -62,6 +62,7 @@ import org.simantics.document.server.io.CommandContextImpl;
 import org.simantics.document.server.io.CommandContextMutable;
 import org.simantics.document.server.io.CommandResult;
 import org.simantics.document.server.io.IConsole;
+import org.simantics.document.server.request.NodeRequest;
 import org.simantics.document.server.request.ServerSCLHandlerValueRequest;
 import org.simantics.document.server.request.ServerSCLValueRequest;
 import org.simantics.document.server.serverResponse.ServerResponse;
@@ -117,7 +118,35 @@ public class Functions {
 
     @SCLValue(type = "VariableMap")
     public static VariableMap primitiveProperties = new VariableMapImpl() {
+       private void storePropertyValueAndExceptions(ReadGraph graph, Variable parent, String name, Variable property, Map<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);
@@ -126,6 +155,8 @@ public class Functions {
         @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);
@@ -136,9 +167,8 @@ public class Functions {
                 for(Variable property : procedural.getProperties(graph/*, DocumentationResource.URIs.Document_AttributeRelation*/)) {
                     if(property instanceof StandardAssertedGraphPropertyVariable) {
                         StandardAssertedGraphPropertyVariable ass = (StandardAssertedGraphPropertyVariable)property;
-                        if("datadefinitions".equals(ass.property.name) || "commands".equals(ass.property.name)  || "pollingFunction".equals(ass.property.name)) {
-                            Object value = property.getPossibleValue(graph);
-                            if(value != null) map.put(ass.property.name, new ConstantPropertyVariable(parent, ass.property.name, value, null));
+                        if("dataDefinitions".equals(ass.property.name) || "commands".equals(ass.property.name)  || "pollingFunction".equals(ass.property.name)) {
+                               storePropertyValueAndExceptions(graph, parent, ass.property.name, property, map);
                         }
                         continue;
                     }
@@ -146,56 +176,47 @@ public class Functions {
                     if(predicate != null) {
                         PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate));
                         if(info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) {
-                            Variable prop = parent.getProperty(graph, predicate);
-                            Object value = prop.getValue(graph);
-                            if(map == null) map = new HashMap<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;
 
         }
index 98bd0fb821dc0286238da7a310c85149247633a0..d9418db9947d482fecd4daf547d85359363bea5c 100644 (file)
@@ -16,7 +16,8 @@ import org.simantics.utils.datastructures.Pair;
 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);
        }
index ed0c54c968b8043e8fc7383655f8b9cf268a6236..00eb2a492ffd4243329e8b0d2706a7d4535d0d68 100644 (file)
@@ -24,10 +24,13 @@ public class NodeRequestUtils {
                if (t instanceof DocumentException) {
                        return t.getMessage();
                } else if (t instanceof MissingVariableException) {
-                       return "Evaluation of property '" + name + "' failed\n" +
-                                       t.getMessage();
+                       return name + ":\n" +
+                                       t.getMessage().replaceAll("(?m)^", "  ");
                } else if (t instanceof SCLDatabaseException) {
-                       return t.getMessage();
+                       StringBuilder sb = new StringBuilder();
+                       sb.append(name + ":\n");
+                       sb.append(t.getMessage().replaceAll("(?m)^", "  "));
+                       return sb.toString();
                } else if (t instanceof NotFoundException) {
                        return t.getMessage();
                } else if (t instanceof ImportFailureException) {
index d69ef69c69fadec257a3e07e2fc31a600cd5ed15..eb9e33607d5500197cc7c4fd8d0c061036d835c3 100644 (file)
@@ -1012,8 +1012,9 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos
         Shape shape = ElementUtils.getElementShapeOrBounds(e);
         Rectangle2D bounds = shape.getBounds2D();
         //System.out.println("selection bounds: "+bounds);
-        final double margin = 1;
-        bounds.setFrame(bounds.getMinX() - margin, bounds.getMinY() - margin, bounds.getWidth() + 2*margin, bounds.getHeight() + 2*margin);
+        final double marginX = 1 / selectionTransform.getScaleX();
+        final double marginY = 1 / selectionTransform.getScaleY();
+        bounds.setFrame(bounds.getMinX() - marginX, bounds.getMinY() - marginY, bounds.getWidth() + 2*marginX, bounds.getHeight() + 2*marginY);
 
         List<SelectionSpecification> ss = e.getElementClass().getItemsByClass(SelectionSpecification.class);
         if (!ss.isEmpty()) {
index e547a663e8e8844024f110485ee85ba81d7ee302..0fbe895be551d6a75650db1decf5f5651ad56db1 100644 (file)
@@ -34,13 +34,19 @@ public class AWTImage extends AbstractImage implements Image {
 
     BufferedImage bi;
     Rectangle2D rect;
+    float alpha;
 
-    public AWTImage(BufferedImage bi) {
+    public AWTImage(BufferedImage bi, float alpha) {
         assert(bi!=null);
         this.bi = bi;
+        this.alpha = alpha;
         rect = new Rectangle2D.Double(bi.getMinX(),bi.getMinY(),bi.getWidth(), bi.getHeight());
     }
 
+    public AWTImage(BufferedImage bi) {
+        this(bi, 1.0f);
+    }
+
     @Override
     public Rectangle2D getBounds() {
         return rect;
@@ -55,6 +61,8 @@ public class AWTImage extends AbstractImage implements Image {
     public Node init(G2DParentNode parent) {
         ImageNode node = parent.getOrCreateNode("image", ImageNode.class);
         node.setImage(bi);
+        node.setAlpha(alpha);
+        node.setZIndex(-100);
         return node;
     }
 
index e4f90791e2123b8fa1c01bf1566ae82de90ac0f7..bffe0c9df4862a160f95ac0e61610dffb1d2a1e1 100644 (file)
@@ -102,17 +102,21 @@ public class RulerPainter extends AbstractCanvasParticipant {
 
     @SGInit
     public void initSG(G2DParentNode parent) {
-        node = parent.addNode("ruler", RulerNode.class);
+        node = parent.addNode("ruler", getNodeClass());
         node.setZIndex(PAINT_PRIORITY);
         updateNode();
     }
 
+    protected Class<? extends RulerNode> getNodeClass() {
+        return RulerNode.class;
+    }
+
     @SGCleanup
     public void cleanupSG() {
         node.remove();
     }
 
-    void updateNode() {
+    protected void updateNode() {
         node.setEnabled(isPaintingEnabled());
         node.setGridSize(getGridSize());
     }
index 2d4171e1ce8855f097999eb033b77db3d158de2e..cb06d6addd1604bb13070f5249428816d120bf73 100644 (file)
@@ -11,7 +11,6 @@ import java.nio.file.Paths;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -64,6 +63,8 @@ public class PrettyPrintTG {
 
     private boolean ignoreIdentifiers;
 
+    private TransferableGraphQueries query;
+
     static class ResourceInfo {
         final boolean hasURI;
         String name;
@@ -104,43 +105,51 @@ public class PrettyPrintTG {
         }
     }
 
-    public PrettyPrintTG(StringBuilder b, boolean ignoreIdentifiers) throws NoSuchAlgorithmException {
+    public PrettyPrintTG(TransferableGraph1 tg, StringBuilder b, boolean ignoreIdentifiers) throws NoSuchAlgorithmException {
         output = b;
         m = MessageDigest.getInstance("SHA-256");
         this.ignoreIdentifiers = ignoreIdentifiers;
+        
+        this.query = new TransferableGraphQueries(tg);
     }
 
-    public PrettyPrintTG() throws NoSuchAlgorithmException {
-        this(new StringBuilder(), false);
+    public PrettyPrintTG(TransferableGraph1 tg) throws NoSuchAlgorithmException {
+        this(tg, new StringBuilder(), false);
     }
 
     TreeMap<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<>();
@@ -151,32 +160,32 @@ public class PrettyPrintTG {
         return results;
     }
 
-    void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) throws Exception {
+    void discoverBlank(int resource, TIntArrayList todo) throws Exception {
         // TIntArrayList statements =
         // TransferableGraphUtils.getStatements(graph, resource);
         // for(int i=0;i<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);
+                    }
                 }
             }
         }
@@ -188,10 +197,10 @@ public class PrettyPrintTG {
         return new BigInteger(1, m.digest()).toString(16);
     }
 
-    void discoverOwners(TransferableGraph1 graph, ResourceInfo info) {
+    void discoverOwners(ResourceInfo info) {
         log("Discovering owners for {}", info);
         int resource = info.resource;
-        TIntArrayList statements = TransferableGraphUtils.getStatements(graph, resource);
+        TIntArrayList statements = query.getStatements(resource);
         for (int i = 0; i < statements.size(); i += 2) {
             int predicate = statements.get(i);
             int object = statements.get(i + 1);
@@ -201,7 +210,7 @@ public class PrettyPrintTG {
 
                 // Check if predicate is inverse, this just resolves all
                 // predicates to be inverse with ending "Inverse"..
-                String predicateUri = rewritePredicateURI(graph, predicate);
+                String predicateUri = rewritePredicateURI(predicate);
                 if (!predicateUri.endsWith("Inverse") && !predicateUri.endsWith("Of")) {
                     existing.ownedResourcesWithPredicates.put(resource, predicate);
                     // if (predicateUri.endsWith("Of")) {
@@ -241,7 +250,7 @@ public class PrettyPrintTG {
         }
     }
 
-    public static String getExternalURI(TransferableGraph1 tg, External ext) {
+    public String getExternalURI(External ext) {
         String name = ext.name;
         if (name.contains(" "))
             name = name.replace(" ", "_").replaceAll("@", "_");// name = "\"" +
@@ -249,9 +258,9 @@ public class PrettyPrintTG {
         int parentId = ext.parent;
         // if(parentId == 0) return ext.name;
         // else {
-        Identity id = TransferableGraphUtils.getIdentity(tg, parentId);
+        Identity id = query.getIdentity(parentId);
         if (id.definition instanceof External) {
-            return getExternalURI(tg, (External) id.definition) + "/" + name;
+            return getExternalURI((External) id.definition) + "/" + name;
         } else if (id.definition instanceof Root) {
             Root root = (Root) id.definition;
             return "http:/" + root.name + "/" + name;
@@ -261,20 +270,20 @@ public class PrettyPrintTG {
         // }
     }
 
-    public static String getExternalURI(TransferableGraph1 tg, int resource) {
-        Identity id = TransferableGraphUtils.getIdentity(tg, resource);
+    public String getExternalURI(int resource) {
+        Identity id = query.getIdentity(resource);
         if (id == null)
             return null;
         if (id.definition instanceof External) {
             External ext = (External) id.definition;
-            return getExternalURI(tg, ext);
+            return getExternalURI(ext);
         }
         return null;
     }
 
-    String rewritePredicateURI(TransferableGraph1 graph, int predicate) {
+    String rewritePredicateURI(int predicate) {
 
-        String uri = getExternalURI(graph, predicate);
+        String uri = getExternalURI(predicate);
         if (uri == null) {
             ResourceInfo info = infos.get(predicate);
             if (info != null)
@@ -301,7 +310,7 @@ public class PrettyPrintTG {
             output.append("  ");
     }
 
-    String printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info, int indent) {
+    String printBlank(String predicateURI2, ResourceInfo info, int indent) {
 
         if (info.hasURI)
             return null;
@@ -328,7 +337,7 @@ public class PrettyPrintTG {
         if (info.ownedResourcesWithPredicates.isEmpty()) {
             if (DEBUG)
                 System.out.print("printBlank");
-            String uri = printURI(graph, info, false, indent, false);
+            String uri = printURI(info, false, indent, false);
             if (uri != null)
                 output.append(uri);
         }
@@ -354,14 +363,14 @@ public class PrettyPrintTG {
         return ((predicate & 0xffffffffL) << 32) | (object & 0xffffffffL);
     }
 
-    private void addInlineStatement(TransferableGraph1 graph, Map<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;
@@ -382,7 +391,7 @@ public class PrettyPrintTG {
         objects.add(object);
     }
 
-    String printURI(TransferableGraph1 graph, ResourceInfo info, boolean requireURI, int indent, boolean inline) {
+    String printURI(ResourceInfo info, boolean requireURI, int indent, boolean inline) {
 
         if (requireURI && !info.hasURI)
             return null;
@@ -393,8 +402,7 @@ public class PrettyPrintTG {
             return null;
 
         Map<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();
@@ -410,9 +418,9 @@ public class PrettyPrintTG {
             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);
@@ -442,32 +450,38 @@ public class PrettyPrintTG {
                 // 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);
             }
         }
 
@@ -547,46 +561,37 @@ public class PrettyPrintTG {
             }
         }
 
-        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 {
@@ -607,26 +612,26 @@ public class PrettyPrintTG {
         knownOntologies.put("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WORKBENCH");
     }
 
-    void prettyPrint(TransferableGraph1 graph) throws Exception {
+    void prettyPrint() throws Exception {
         log("Starting prettyPrint for TransferableGraph with {} resources, {} identities, {} statements and {} values",
-                graph.resourceCount, graph.identities, graph.statements.length, graph.values.length);
+                query.getGraph().resourceCount, query.getGraph().identities, query.getGraph().statements.length, query.getGraph().values.length);
 
-        for (Identity id : graph.identities) {
+        query.forIdentities(id -> {
+            int identityResource = id.resource;
             if (id.definition instanceof Internal) {
                 Internal internal = (Internal) id.definition;
-                Identity parent = TransferableGraphUtils.getIdentity(graph, internal.parent);
-                if (parent.definition instanceof External) {
+                Identity parent = query.getIdentity(internal.parent);
+                if (parent.definition instanceof External || parent.definition instanceof Root) {
                     log("Resolving internal identity {}", id);
                     String name = "BASE";
-                    ResourceInfo info = new ResourceInfo(true, name, id.resource, -1);
-                    info.aliasURI = TransferableGraphUtils.getURI(graph, id.resource);
+                    ResourceInfo info = new ResourceInfo(true, name, identityResource, -1);
+                    info.aliasURI = query.getURI(identityResource);
                     info.newResource = true;
                     orderedInfos.put(name, info);
                     // infos.put(id.resource, info);
                     log("    which parent is external {} and has an aliasURI {}", parent, info.aliasURI);
-                    for (Identity child : TransferableGraphUtils.getChildren(graph, id)) {
-                        recurseURI(graph, child, name, info.resource);
-                    }
+                    for (Identity child : query.getChildren(id))
+                        recurseURI(orderedInfos, child, name, identityResource);
                     log("    and has {} children", infos.size());
                 }
             } else if (id.definition instanceof External) {
@@ -640,7 +645,7 @@ public class PrettyPrintTG {
                     String prefix = ext.name.substring(0, index);
                     int index2 = ext.name.indexOf('/', index);
                     String ontology = index2 == -1 ? ext.name : ext.name.substring(0, index2);
-                    String uri = TransferableGraphUtils.getURI(graph, id.resource);
+                    String uri = query.getURI(identityResource);
 
                     log("    which was resolved as URI={} and prefix={}", uri, prefix);
 
@@ -648,7 +653,7 @@ public class PrettyPrintTG {
 
                 } else if (ext.name.contains("-")) {
                     log("Resolving possible ontology {}", ext);
-                    String uri = TransferableGraphUtils.getURI(graph, id.resource);
+                    String uri = query.getURI(identityResource);
                     Matcher m = versionExtractPattern.matcher(uri);
                     if (m.matches()) {
                         if (!ontologies.containsKey(uri)) {
@@ -660,7 +665,8 @@ public class PrettyPrintTG {
                     }
                 }
             }
-        }
+            return true;
+        });
 
         // Discover other resources
         log("Discovering other resources..");
@@ -675,10 +681,10 @@ public class PrettyPrintTG {
 
         while (!todo.isEmpty()) {
             int resource = todo.removeAt(todo.size() - 1);
-            discoverBlank(graph, resource, todo);
+            discoverBlank(resource, todo);
         }
         for (ResourceInfo info : infos.valueCollection())
-            discoverOwners(graph, info);
+            discoverOwners(info);
         // for(ResourceInfo info : infos.valueCollection())
         // fixInstanceOf(graph, info);
 
@@ -697,12 +703,15 @@ public class PrettyPrintTG {
 
                     @Override
                     public boolean execute(int owner, int predicate) {
+                       
                         ResourceInfo ownerInfo = infos.get(owner);
                         ownerInfo.owned.add(predicate);
                         ownerInfo.owned.add(info.resource);
                         return false;
                     }
                 });
+            } else {
+                System.err.println("Here we are with " + info);
             }
         }
 
@@ -717,21 +726,18 @@ public class PrettyPrintTG {
             }
         }
 
-        Identity routeGraphConn = TransferableGraphUtils.findExternal(graph,
-                "http://www.simantics.org/Diagram-2.2/RouteGraphConnection");
-        Identity instanceOf = TransferableGraphUtils.findExternal(graph,
-                "http://www.simantics.org/Layer0-1.1/InstanceOf");
-        Identity diagramConnetionToConnection = TransferableGraphUtils.findExternal(graph,
-                "http://www.simantics.org/Modeling-1.2/DiagramConnectionToConnection");
+        Identity routeGraphConn = query.findExternalByURI("http://www.simantics.org/Diagram-2.2/RouteGraphConnection");
+        Identity instanceOf = query.findExternalByURI("http://www.simantics.org/Layer0-1.1/InstanceOf");
+        Identity diagramConnetionToConnection = query.findExternalByURI("http://www.simantics.org/Modeling-1.2/DiagramConnectionToConnection");
 
+        Identity elemTo = query.findExternalByURI("http://www.simantics.org/Modeling-1.2/ElementToComponent");
         for (ResourceInfo infoo : infos.valueCollection()) {
-            Identity elemTo = TransferableGraphUtils.findExternal(graph, "http://www.simantics.org/Modeling-1.2/ElementToComponent");
             if (elemTo != null) {
-                int elemToComponent = TransferableGraphUtils.getPossibleObject2(graph, infoo.resource, elemTo);
+                int elemToComponent = query.getPossibleObject(infoo.resource, elemTo);
                 if (elemToComponent != TransferableGraphUtils.NOT_FOUND) {
 
-                    Identity component = TransferableGraphUtils.getIdentity(graph, elemToComponent);
-                    Identity internal = TransferableGraphUtils.getIdentity(graph, infoo.resource);
+                    Identity component = query.getIdentity(elemToComponent);
+                    Identity internal = query.getIdentity(infoo.resource);
                     if (internal.definition instanceof Internal && component.definition instanceof Internal) {
                         Internal iComponent = (Internal) component.definition;
                         infoo.name = infoo.name.substring(0, infoo.name.lastIndexOf(".") + 1) + iComponent.name;
@@ -740,29 +746,29 @@ public class PrettyPrintTG {
             }
 
             if (instanceOf != null) {
-                int instOf = TransferableGraphUtils.getPossibleObject2(graph, infoo.resource, instanceOf);
+                int instOf = query.getPossibleObject( infoo.resource, instanceOf);
                 if (instOf != TransferableGraphUtils.NOT_FOUND && routeGraphConn != null) {
                     if (instOf == routeGraphConn.resource) {
                         // Found routegraphconnection, change name
                         // Lets go to configuration
 
-                        int connection = TransferableGraphUtils.getPossibleObject2(graph, infoo.resource,
+                        int connection = query.getPossibleObject( infoo.resource,
                                 diagramConnetionToConnection);
                         if (connection != TransferableGraphUtils.NOT_FOUND) {
                             // Gather all inverse statements to construct unique
                             // name
                             List<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 {
@@ -771,7 +777,7 @@ public class PrettyPrintTG {
                                     } else if (possibleInverse.definition instanceof External) {
                                         External ePossibleInverse = (External) possibleInverse.definition;
                                         if (ePossibleInverse.name.equals("Inverse")) {
-                                            inverseRelation = TransferableGraphUtils.getPossibleObject2(graph,
+                                            inverseRelation = query.getPossibleObject(
                                                     connection, possibleInverse);
                                             parentId = ePossibleInverse.parent;
                                         } else {
@@ -782,8 +788,8 @@ public class PrettyPrintTG {
                                     }
                                     if (inverseRelation != TransferableGraphUtils.NOT_FOUND) {
                                         // Ok found something
-                                        Identity object = TransferableGraphUtils.getIdentity(graph, inverseRelation);
-                                        Identity parent = TransferableGraphUtils.getIdentity(graph, parentId);
+                                        Identity object = query.getIdentity(inverseRelation);
+                                        Identity parent = query.getIdentity(parentId);
                                         String objectName, parentName;
                                         if (object.definition instanceof Internal) {
                                             objectName = ((Internal) object.definition).name;
@@ -818,7 +824,6 @@ public class PrettyPrintTG {
                             infoo.name = infoo.name.substring(0, infoo.name.lastIndexOf(".") + 1) + name;
                         } else {
                             LOGGER.error("Could not find connection for " + infoo + ". Statements of graph below");
-                            LOGGER.error(Arrays.toString(graph.statements));
                             LOGGER.error("Subject -> Predicate : " + infoo.resource + " -> "
                                     + diagramConnetionToConnection.resource);
                         }
@@ -828,7 +833,7 @@ public class PrettyPrintTG {
         }
         for (ResourceInfo info : infos.valueCollection()) {
             if (info.name.startsWith("blank")) {
-                info.name = "blank" + findHash(graph, info);
+                info.name = "blank" + findHash(info);
             }
         }
 
@@ -839,7 +844,7 @@ public class PrettyPrintTG {
         for (ResourceInfo info : order.values()) {
             if (DEBUG)
                 System.out.print("info ");
-            String uri = printURI(graph, info, true, 0, false);
+            String uri = printURI(info, true, 0, false);
             if (uri != null)
                 output.append(uri);
         }
@@ -854,7 +859,7 @@ public class PrettyPrintTG {
                     // These will be printed later
                     rblanks.put(getBlankRewrite(info.name), info);
                 } else {
-                    String uri = printURI(graph, info, false, 0, false);
+                    String uri = printURI(info, false, 0, false);
                     if (uri != null)
                         output.append(uri);
                 }
@@ -865,7 +870,7 @@ public class PrettyPrintTG {
             if (!info.hasURI && info.ownedResourcesWithPredicates.size() != 1) {
                 if (DEBUG)
                     System.out.print("ownedResources ");
-                String uri = printURI(graph, info, false, 0, false);
+                String uri = printURI(info, false, 0, false);
                 if (uri != null)
                     output.append(uri);
             }
@@ -886,7 +891,7 @@ public class PrettyPrintTG {
 
     }
 
-    private String calculateHash(TransferableGraph1 graph, ResourceInfo info) {
+    private String calculateHash(ResourceInfo info) {
         StringBuilder statementHash = new StringBuilder();
         TreeSet<String> parts = new TreeSet<>();
         for (int i = 0; i < info.owned.size(); i += 2) {
@@ -895,7 +900,7 @@ public class PrettyPrintTG {
             // Lets resolve a unique name for this based on the statements this
             // one has
 
-            String predicatee = rewritePredicateURI(graph, predicate);
+            String predicatee = rewritePredicateURI(predicate);
             ResourceInfo objInfo = infos.get(object);
             parts.add(predicatee + "->" + objInfo.name + ";;;");
         }
@@ -921,14 +926,14 @@ public class PrettyPrintTG {
         return hash;
     }
 
-    private String findHash(TransferableGraph1 graph, ResourceInfo info) {
+    private String findHash(ResourceInfo info) {
         if (info.name.startsWith("blank")) {
             String hash = hashes.get(info.name);
             if (hash == null) {
                 String oldName = info.name;
                 if (DEBUG)
                     System.out.print("calculating hash for " + oldName + " ");
-                hash = calculateHash(graph, info);
+                hash = calculateHash(info);
                 if (hashes.put(oldName, hash) != null) {
                     System.err.println("!!!!A clash occured for " + info + " with hash " + hash);
                 }
@@ -943,19 +948,31 @@ public class PrettyPrintTG {
 
     public static String print(TransferableGraph1 tg, boolean ignoreIdentifiers) throws Exception {
         StringBuilder b = new StringBuilder();
-        new PrettyPrintTG(b, ignoreIdentifiers).prettyPrint(tg);
+        new PrettyPrintTG(tg, b, ignoreIdentifiers).prettyPrint();
         return b.toString();
     }
 
     public static void main(String[] args) throws Exception {
         if (args.length < 1) {
             System.out.println("Required arguments: <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();
         }
     }
 
diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphQueries.java
new file mode 100644 (file)
index 0000000..5d4c185
--- /dev/null
@@ -0,0 +1,205 @@
+package org.simantics.graph.representation;
+
+import java.util.Comparator;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import gnu.trove.impl.Constants;
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
+public class TransferableGraphQueries {
+
+    private static final int NOT_FOUND = TransferableGraphUtils.NOT_FOUND;
+
+    private final TransferableGraph1 tg;
+
+    private final TIntObjectHashMap<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;
+    }
+    
+}
index b210d8dd713348cb38fa846f6558509442d05276..10637ad65caf0d861d52e3d1adfffdee66d5f2ca 100644 (file)
@@ -16,156 +16,205 @@ import gnu.trove.map.hash.TIntObjectHashMap;
 
 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)
@@ -174,19 +223,19 @@ public class TransferableGraphUtils {
             }
         }
         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)
@@ -194,112 +243,112 @@ public class TransferableGraphUtils {
         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 + ">:";
+    }
 
 }
index 6610d17f2456081d73031797f44599f43cf01ffb..4e405e2acafff0ba2c81d06cb6a48d382a17d778 100644 (file)
@@ -12,9 +12,7 @@
 package org.simantics.history.csv;
 
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
-import java.net.URLDecoder;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.Format;
@@ -85,20 +83,12 @@ public class CSVFormatter {
                i.history = history;
                i.label = label!=null?label:"";
                i.variableReference = variableReference!=null?variableReference:"";
-               i.variableReference = unescape(i.variableReference);
+               i.variableReference = URIs.safeUnescape(i.variableReference);
                i.historyItemId = historyItemId;
                i.unit = unit;
                if ( !items.contains(i) ) items.add( i );
        }
 
-       private static String unescape(String url) {
-               try {
-                       return URLDecoder.decode(url, "UTF-8");
-               } catch (UnsupportedEncodingException e) {
-                       return url;
-               }
-       }
-
        /**
         * Sort items by variableId, label1, label2
         */
diff --git a/bundles/org.simantics.history/src/org/simantics/history/csv/URIs.java b/bundles/org.simantics.history/src/org/simantics/history/csv/URIs.java
new file mode 100644 (file)
index 0000000..57a819a
--- /dev/null
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.history.csv;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.30.0, 1.28.1
+ */
+class URIs {
+
+    public static String safeUnescape(String uri) {
+        try {
+            return unescape(uri);
+        } catch (IllegalArgumentException e) {
+            return uri;
+        }
+    }
+
+    public static String unescape(String uri) {
+        try {
+            if (!needsUnescaping(uri))
+                return uri;
+
+            int len = uri.length();
+            String unicode = uri;
+            char result[] = new char[len];
+            int in = 0;
+            int out = 0;
+            while (in < len) {
+                char inCh = unicode.charAt(in++);
+                if (inCh == '%' && in+1 < len) {
+                    char d1 = unicode.charAt(in);
+                    char d2 = unicode.charAt(in+1);
+                    if (d1 > 127 || d2 > 127)
+                        throw new IllegalArgumentException("Invalid hex digit escape sequence in " + uri + " at " + in);
+                    result[out++] = (char) (hexDecode(d1) * 16 | hexDecode(d2));
+                    in += 2;
+                } else {
+                    result[out++] = inCh;
+                }
+            }
+            return new String(result, 0, out);
+        } catch (IllegalArgumentException e) {
+            throw new IllegalArgumentException("Problem while unescaping string: " + uri, e);
+        } catch (IndexOutOfBoundsException ee) {
+            throw new IllegalArgumentException("Incomplete hex digit escape sequence in " + uri);
+        }
+    }
+
+    private static boolean needsUnescaping(String s) {
+        int l = s.length();
+        for (int i = -1; i < l;) {
+            i = s.indexOf('%', i+1);
+            if (i < 0)
+                break;
+            if (i+2 < l
+                    && isHexDigit(s.charAt(i+1))
+                    && isHexDigit(s.charAt(i+2)))
+                return true;
+        }
+        return false;
+    }
+
+    private static int hexDecode(char c) {
+        switch (c) {
+            case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+                return ((c) & 255) - 'a' + 10;
+            case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+                return c -  'A' + 10;
+            case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
+                return c -  '0';
+            default:
+                throw new IllegalArgumentException("Bad Hex escape character: " + ((c)&255) );
+        }
+    }
+
+    private static boolean isHexDigit(char c) {
+        return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+    }
+
+//    public static void main(String[] args) {
+//        System.out.println(unescape("%"));
+//        System.out.println(unescape("%.AI"));
+//        System.out.println(unescape("%6B"));
+//        System.out.println(unescape("%6g"));
+//        System.out.println(unescape("%g5"));
+//        System.out.println(unescape("%f5"));
+//        System.out.println(unescape("%A1"));
+//        System.out.println(unescape("%A"));
+//        System.out.println(unescape("%A."));
+//        System.out.println(unescape("%AI"));
+//    }
+
+}
index db537ee26ac6d4ed826773b39deb81bc122307fe..7646271e3d91443564d9d51fd47af401d2b9ca68 100644 (file)
@@ -12,6 +12,8 @@
 package org.simantics.issues.common;
 
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.Resource;
@@ -29,66 +31,71 @@ public class MaxIssueSeverityRecursive extends TernaryAsyncRead<Resource, Resour
     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);
+                }
+            });
+        }
     }
 
 }
index e8ed917aad52182f701f1060fb5a289ce49f1325..89816d6faa42fb2c3d70ae3443901ce3194d85bb 100644 (file)
@@ -14,8 +14,12 @@ package org.simantics.issues.common;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceAsyncRead;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.utils.ListUtils;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncMultiProcedure;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.issues.Severity;
@@ -52,11 +56,12 @@ public class MaxIssueSeveritySingle extends ResourceAsyncRead<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) {
                 
@@ -69,13 +74,54 @@ public class MaxIssueSeveritySingle extends ResourceAsyncRead<Severity>{
             }
             @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());
+        
     }
     
     /**
index 47a8160b55dd44b718033bfd5667a60486831247..c68e561f43abd47687828347037378d3366de08f 100644 (file)
@@ -27,12 +27,16 @@ ISSUE.ContinuousIssueSource <T ISSUE.IssueSource
 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
index 64d13dcf764b2bc5b2f36caf50efef2099499f68..659a8aa226b494e6837189c76a8d6ece50645a55 100644 (file)
@@ -7,6 +7,10 @@ L0.List <T L0.Value
     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
@@ -14,4 +18,6 @@ L0.List.Next <R L0.IsRelatedTo : L0.TotalFunction
 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
index e9b91f71aeaba0aedf6369bb4d8119a53e4d9bbd..fe566684dc1a183c7f00c7aa021ec26961f17c9a 100644 (file)
@@ -515,4 +515,6 @@ MOD.SVGTabContribution : SEL.SCLTabContribution
     "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
index 0255339ac7bda279053ca6e30b98d744f2362ac2..86171a31a445049705b104c7bfa9b89eb5e42d4c 100644 (file)
@@ -420,10 +420,23 @@ MOD.Contributions.Help : VP.ActionContribution
     VP.ActionContribution.HasCategory VP.EditActionCategory
     VP.ActionContribution.HasNodeType L0.Entity
     VP.ActionContribution.HasAction ACTIONS.Help
-              
+
+MOD.Contributions.CopyURI : VP.ActionContribution
+    L0.HasLabel "Copy URI"
+    VP.ActionContribution.HasImage SILK.clipboard
+    VP.ActionContribution.HasCategory VP.EditActionCategory
+    VP.ActionContribution.HasNodeType L0.Entity
+    VP.ActionContribution.HasNodeType MBC.Variable
+    VP.ActionContribution.HasAction ACTIONS.CopyURI
+    VP.ActionContribution.IsVisibleIf _ : VP.AndTest
+        VP.AndTest.HasTest
+            _ : VP.InDevelopmentModeTest
+            _ : VP.HasURITest
+
 // Actions
 MAC    
     VP.BrowseContext.HasActionContribution MOD.Contributions.Help
+    VP.BrowseContext.HasActionContribution MOD.Contributions.CopyURI
     VP.BrowseContext.HasActionContribution _ : VP.ActionContribution
         L0.HasLabel "Migrate"
         VP.ActionContribution.HasImage SILK.star
@@ -659,6 +672,7 @@ ACTIONS.CompilePGraphs : ACT.Action
 //ACTIONS.MigrateMasterTypical : ACT.Action
 ACTIONS.RenameDiagramComponents : ACT.Action
 ACTIONS.Help : ACT.Action
+ACTIONS.CopyURI : ACT.Action
 
 ACTIONS.NavigateToSubstructure
   @MOD.sclAction "navigateToSubstructureAction"
index 891ac0d46ba1cdbb77e37e8ce9803c1708068dc7..495e4e40631b91b140fef805b4d57c578bff3308 100644 (file)
                </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
index a662f57f4a47695501052d30dba1072e5d6ad66f..436557f31e613d10760f593a8b7288b5b64ef518 100644 (file)
@@ -97,7 +97,7 @@ importJava "org.simantics.browsing.ui.content.LabelDecorator" where
     Decorates the given label with the name of the UI column which the label is for and  the index of this label within its parenting INodeContext.
     Returns the decorated Label 
     """
-    decorateLabel :: LabelDecorator -> String -> String -> Integer -> <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
index 931bfdf3d60d073c0b63c271dbda2c163f060c41..b864c4bcf56b3eff3b9d5a30e7338d5d60645018 100644 (file)
@@ -36,7 +36,12 @@ import org.simantics.db.common.request.IndexRoot;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.request.Read;
+import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;
+import org.simantics.diagram.synchronization.SynchronizationHints;
+import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;
+import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager;
 import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.diagram.IDiagram;
 import org.simantics.g2d.participant.MouseUtil;
 import org.simantics.g2d.participant.MouseUtil.MouseInfo;
 import org.simantics.modeling.ModelingResources;
@@ -112,10 +117,12 @@ public class ImportSVGPNG {
         IResourceEditorInput input = (IResourceEditorInput)viewer.getEditorInput();
         Resource composite = input.getResource();
 
-        addSVG(mpos.getX(), mpos.getY(), composite);
+        IDiagram idiagram = viewer.getAdapter(IDiagram.class);
+
+        addSVG(mpos.getX(), mpos.getY(), composite, idiagram);
     }
 
-    public static void addSVG(final double mposX, final double mposY, final Resource composite) {
+    public static void addSVG(final double mposX, final double mposY, final Resource composite, IDiagram idiagram) {
 
         Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
 
@@ -135,9 +142,20 @@ public class ImportSVGPNG {
 
                 @Override
                 public void perform(WriteGraph g) throws DatabaseException {
-                    Commands.get(g, "Simantics/Diagram/createSVGElement")
+                    Object svg = Commands.get(g, "Simantics/Diagram/createSVGElementR")
                             .execute(g, g.syncRequest(new IndexRoot(composite)),
                                      composite, suffix(filename), data, mposX, mposY);
+
+                    if (svg != null && svg instanceof Resource) {
+                        Resource resource = (Resource) svg;
+                        // 7. Put the element on all the currently active layers if possible.
+                        IModifiableSynchronizationContext context = idiagram.getHint(SynchronizationHints.CONTEXT);
+                        GraphLayerManager glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER);
+                        if (glm != null) {
+                            glm.removeFromAllLayers(g, resource);
+                            glm.putElementOnVisibleLayers(idiagram, g, resource);
+                        }
+                    }
                 }
 
             });
index b5381917d4b8acd3dd2e03f571b8a334d273e6de..1762dea7f6108d34b0a265731387adc9325cb002 100644 (file)
@@ -727,9 +727,7 @@ public class DiagramViewer
         addKeyBindingParticipants(ctx);
 
         // Grid & Ruler & Background
-        ctx.add(new GridPainter());
-        ctx.add(new RulerPainter());
-        ctx.add(new BackgroundPainter());
+        addGridRulerBackgroundParticipants(ctx);
 
         h.setHint(Hints.KEY_DISPLAY_PAGE, diagramPreferences.get(DiagramPreferences.P_DISPLAY_PAGE_SIZE));
         h.setHint(Hints.KEY_DISPLAY_MARGINS, diagramPreferences.get(DiagramPreferences.P_DISPLAY_MARGINS));
@@ -776,6 +774,12 @@ public class DiagramViewer
         ctx.setLocked(false);
     }
 
+    protected void addGridRulerBackgroundParticipants(CanvasContext ctx) {
+        ctx.add(new GridPainter());
+        ctx.add(new RulerPainter());
+        ctx.add(new BackgroundPainter());
+    }
+
     protected void loadPageSettings(ICanvasContext ctx) {
         DiagramDesc diagramDesc = null;
 
index 6af1ff84b95cee9abd1f6324680f29ccf3339889..7fd13bbdddcbb023573651eee62b30bb9eddaa14 100644 (file)
@@ -14,12 +14,16 @@ package org.simantics.modeling.ui.diagramEditor;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ReadRequest;
-import org.simantics.db.common.utils.ListUtils;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
 import org.simantics.diagram.content.ConnectionUtil;
 import org.simantics.diagram.flag.FlagUtil;
 import org.simantics.diagram.stubs.DiagramResource;
@@ -27,8 +31,14 @@ import org.simantics.issues.ontology.IssueResource;
 import org.simantics.layer0.Layer0;
 import org.simantics.modeling.ModelingResources;
 import org.simantics.modeling.ui.Activator;
-import org.simantics.ui.SimanticsUI;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.ui.selection.AnyResource;
+import org.simantics.ui.selection.AnyVariable;
+import org.simantics.ui.selection.WorkbenchSelectionContentType;
+import org.simantics.ui.selection.WorkbenchSelectionElement;
 import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.ISelectionUtils;
 
 /**
  * @author Tuukka Lehtonen
@@ -38,7 +48,7 @@ public class OpenDiagramFromIssue extends AbstractResourceEditorAdapter {
     private static final String EDITOR_ID = "org.simantics.modeling.ui.plainDiagramEditor";
 
     public OpenDiagramFromIssue() {
-        super("Open Diagram Containing Referenced Element", Activator.COMPOSITE_ICON);
+        super("Open Diagram Containing Referenced Component", Activator.COMPOSITE_ICON);
     }
 
     protected String getEditorId() {
@@ -46,88 +56,147 @@ public class OpenDiagramFromIssue extends AbstractResourceEditorAdapter {
     }
 
     @Override
-    public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException {
-        return findElement(g, r) != null;
+    public boolean canHandle(ReadGraph g, Object input) throws DatabaseException {
+        return extractContext(g, input) != null;
     }
 
     @Override
-    public void openEditor(final Resource r) throws Exception {
-        SimanticsUI.getSession().asyncRequest(new ReadRequest() {
+    public void openEditor(Object input) throws Exception {
+        Simantics.getSession().asyncRequest(new ReadRequest() {
             @Override
             public void run(ReadGraph g) throws DatabaseException {
-               
-               Layer0 L0 = Layer0.getInstance(g);
-               ModelingResources MOD = ModelingResources.getInstance(g);
-               
-               Resource element = findElement(g, r);
-               if(element == null) return;
-               
-               System.err.println("element " + g.getURI(element));
-               
-               Resource diagram = g.getSingleObject(element, L0.PartOf);
-               Resource composite = g.getSingleObject(diagram, MOD.DiagramToComposite);
-                               
-                OpenDiagramFromConfigurationAdapter.openEditor(g, composite, getEditorId(), Collections.<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;
-    }    
+    }
     
 }
index 0e3870c356673adc721d392164649b8588d89b73..b74449f822ed4ad9eb5084f70f7a4992fe5f2085 100644 (file)
         </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">
index bf5c589e85f8f2a248d55a71c5244bc1332b2fae..0ee3e9d28ec03afeec9aff59d69097643472df72 100644 (file)
@@ -149,9 +149,15 @@ hasRandomIdentifier entity = runProc (claimRelatedValue_ entity L0.identifier GU
 
 """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 
@@ -805,8 +811,10 @@ setTransform element transform = claimRelatedValueWithType element DIA.HasTransf
     
 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> ()
index 53b601fa2820ea91c640a42d643daff539ca343d..e5ae639355b1087ff16aa48fdfe095a99f408ad7 100644 (file)
@@ -13,6 +13,7 @@ import org.simantics.db.request.Read;
 import org.simantics.scl.compiler.environment.LocalEnvironment;
 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
 import org.simantics.scl.compiler.errors.CompilationError;
+import org.simantics.scl.compiler.errors.ErrorSeverity;
 import org.simantics.scl.compiler.module.repository.ImportFailure;
 import org.simantics.scl.compiler.module.repository.ImportFailureException;
 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
@@ -47,7 +48,7 @@ public class ComponentTypeScriptRequest implements Read<ComponentTypeScriptResul
                 // 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);
             }
index 511eeb3fa0e41fb0894b866d293cc330812c3923..2afdac9927aea060858b0b30f3a30c3d59ddaf87 100644 (file)
@@ -91,6 +91,7 @@ import org.simantics.db.layer0.adapter.CopyHandler;
 import org.simantics.db.layer0.adapter.GenericRelationIndex;
 import org.simantics.db.layer0.adapter.Instances;
 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
+import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex;
 import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory;
 import org.simantics.db.layer0.genericrelation.IndexedRelations;
 import org.simantics.db.layer0.migration.MigrationUtils;
@@ -704,7 +705,7 @@ public class ModelingUtils {
     }
 
     public static List<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 {
@@ -721,7 +722,7 @@ public class ModelingUtils {
     }
 
     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 {
@@ -774,7 +775,7 @@ public class ModelingUtils {
     }
 
     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());
     }
 
        /**
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/CopyURI.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/CopyURI.java
new file mode 100644 (file)
index 0000000..cdb56be
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.actions;
+
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Display;
+import org.simantics.Simantics;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.db.layer0.request.PossibleURI;
+import org.simantics.db.layer0.request.VariableURI;
+import org.simantics.db.layer0.variable.Variable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Jani Simomaa
+ * @since 1.30.0
+ */
+public class CopyURI implements ActionFactory {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CopyURI.class);
+
+    @Override
+    public Runnable create(Object target) {
+        return () -> {
+            try {
+                String uri = getPossibleURI(target);
+                if (uri != null) {
+                    Clipboard cb = new Clipboard(Display.getCurrent());
+                    cb.setContents(new Object[] { uri }, new Transfer[] { TextTransfer.getInstance() });
+                }
+            } catch (Exception e) {
+                LOGGER.error("Could not get URI for input {} to copy to clipboard", target, e);
+            }
+        };
+    }
+
+    private String getPossibleURI(Object input) throws DatabaseException {
+        if (input instanceof Resource) {
+            return Simantics.getSession().syncRequest(new PossibleURI((Resource) input));
+        } else if (input instanceof Variable) {
+            return Simantics.getSession().syncRequest(new VariableURI((Variable) input));
+        }
+        return null;
+    }
+
+}
index 307a32cccb1c6664cc7cc4dbf3fd96ea70f9a639..a4c1c4b2ace8530a593531a3b094ce6590162cc6 100644 (file)
@@ -153,4 +153,14 @@ public class GraphPropertyRelation implements SCLRelation {
                 w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE),
                 parameters[1].toVal(compilationContext, w));
     }
+    
+    @Override
+    public Type getEnforceEffect() {
+        return Types.WRITE_GRAPH;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.READ_GRAPH;
+    }
 }
index 331cef2cb280b282260754cc0a0427747f606e21..f1c8a79f8b9fcc6c1d8a596d7f78b2ef9a55f65e 100644 (file)
@@ -183,4 +183,14 @@ public class GraphRelation implements SCLRelation {
                 w.getModuleWriter().getExternalConstant(relation, Types.RESOURCE),
                 parameters[1].toVal(compilationContext, w));
     }
+    
+    @Override
+    public Type getEnforceEffect() {
+        return Types.WRITE_GRAPH;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.READ_GRAPH;
+    }
 }
index 994d417c99b815ba4c3deae54511777a84e8fc05..1f302a64db4c2b7262339366bdb438123e7b3d11 100644 (file)
@@ -19,6 +19,10 @@ import org.simantics.utils.FileUtils;
 public class CreateSVGElement {
 
     public static void createSVGElement(WriteGraph g, Resource diagram, String suffix, byte[] data, double mposX, double mposY) throws DatabaseException {
+        createSVGElement(g, diagram, suffix, data, mposX, mposY);
+    }
+
+    public static Resource createSVGElementR(WriteGraph g, Resource diagram, String suffix, byte[] data, double mposX, double mposY) throws DatabaseException {
 
         Layer0 L0 = Layer0.getInstance(g);
         DiagramResource DIA = DiagramResource.getInstance(g);
@@ -50,19 +54,22 @@ public class CreateSVGElement {
             throw new DatabaseException("Unknown image format " + suffix);
         OrderedSetUtils.addFirst(g, diagram, element);
         g.claim(diagram, L0.ConsistsOf, element);
-
+        return element;
     }
-    
+
     public static void importSVGElement(WriteGraph graph, Resource diagram, File file, double posX, double posY) throws DatabaseException, IOException {
-        
+        importSVGElementR(graph, diagram, file, posX, posY);
+    }
+
+    public static Resource importSVGElementR(WriteGraph graph, Resource diagram, File file, double posX, double posY) throws DatabaseException, IOException {
         final byte[] data = FileUtils.readFile(file);
-        createSVGElement(graph, diagram, suffix(file.getName()), data, posX, posY);
+        return createSVGElementR(graph, diagram, suffix(file.getName()), data, posX, posY);
     }
-    
+
     private static String suffix(String fileName) {
         int len = fileName.length();
         if(len < 3) return null;
         else return fileName.substring(len-3,len).toLowerCase();
     }
-    
+
 }
index a265df8b136b86e9711d84843e5b8417d3e9cba3..eeab91d816030948d4c98212a87b9dcca30915eb 100644 (file)
@@ -101,7 +101,7 @@ VIEWS.SharedLibraryContribution : SWT.TypedVariableTabContribution
 
 //VIEWS.SharedLibraryContribution2 : SWT.TypedVariableTabContribution
 //    SEL.AbstractVariableTabContribution.HasPriority 1
-//    SEL.AbstractTypedVariableTabContribution.HasType L0.SharedOntology
+//    SEL.AbstractTypedTabContribution.HasType L0.SharedOntology
 //    SWT.TypedVariableTabContribution.HasView SharedLibraries
 //    L0.HasLabel "Shared Libraries"
 
index df35e968ef41501bd537425e97a513759719d747..43cf64eb0a2159f9d1fce6f12b4ed6351dfe6dd3 100644 (file)
@@ -11,6 +11,8 @@
  *******************************************************************************/
 package org.simantics.scenegraph.g2d.nodes;
 
+import java.awt.AlphaComposite;
+import java.awt.Composite;
 import java.awt.Graphics2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Rectangle2D;
@@ -28,6 +30,7 @@ public class ImageNode extends G2DNode {
 
     protected Boolean visible = Boolean.TRUE;
     protected BufferedImage img = null;
+    protected float alpha = 1.0f;
 
     @SyncField("visible")
     public void setVisible(Boolean visible) {
@@ -50,6 +53,10 @@ public class ImageNode extends G2DNode {
         img = src;
     }
 
+    public void setAlpha(float alpha) {
+        this.alpha = Math.max(0.0f, Math.min(alpha, 1.0f));
+    }
+
     @Override
     public void render(Graphics2D g) {
         if (!visible || img == null) return;
@@ -65,8 +72,17 @@ public class ImageNode extends G2DNode {
 //            Rectangle2D b = parent.getBoundsInLocal();
 //            g.drawImage(img, (int)b.getMinX(), (int)b.getMinY(), (int)b.getWidth()+(int)b.getMinX(), (int)b.getHeight()+(int)b.getMinY(), 0, 0, img.getWidth(), img.getHeight(), null);
 //        }
+
+        Composite old = null;
+        if (alpha < 1.0f) {
+            old = g.getComposite();
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+        }
+
         g.drawImage(img, 0, 0, null);
 
+        if (old != null)
+            g.setComposite(old);
         if (ot != null)
             g.setTransform(ot);
     }
index f7e0d1e5c6b5cb05d280b9a5ae514758723b2370..27c1c1fd2bae4c1d2469ea24af1d0259647b152c 100644 (file)
@@ -57,7 +57,7 @@ public class RulerNode extends G2DNode {
     public void render(Graphics2D g) {
         if (!enabled)
             return;
-
+        
         AffineTransform tr = g.getTransform();
         double scaleX = Math.abs(tr.getScaleX());
         double scaleY = Math.abs(tr.getScaleY());
@@ -109,7 +109,9 @@ public class RulerNode extends G2DNode {
         // Vertical ruler
         for(double x = offsetX%stepX-stepX; x < bounds.getMaxX(); x+=stepX) {
             if(x > 20) {
-                String str = formatValue((x-offsetX)/scaleX);
+                double val = (x-offsetX)/scaleX / getTransform().getScaleX();
+                double modifiedValue = modifyHorizontalValue(val);
+                String str = formatValue(modifiedValue);
                 FontMetrics fm = g.getFontMetrics();
                 Rectangle2D r = fm.getStringBounds(str, g);
                 if((x-r.getWidth()/2) > previousText) {
@@ -140,10 +142,9 @@ public class RulerNode extends G2DNode {
         previousText = -100;
         for(double y = offsetY%stepY-stepY; y < bounds.getMaxY(); y+=stepY) {
             if(y > 20) {
-                double val = (y-offsetY)/scaleY;
-                if (MAP_Y_SCALING)
-                    val = Math.toDegrees(Math.atan(Math.sinh(Math.toRadians(val))));
-                String str = formatValue(val);
+                double val = (y-offsetY)/scaleY / getTransform().getScaleY();
+                double modifiedValue = modifyVerticalValue(val);
+                String str = formatValue(modifiedValue);
                 FontMetrics fm = g.getFontMetrics();
                 Rectangle2D r = fm.getStringBounds(str, g);
                 if(y-1+r.getHeight()/2 > previousText) {
@@ -175,6 +176,26 @@ public class RulerNode extends G2DNode {
         g.setTransform(tr);
     }
 
+    /**
+     * A method for subclasses to alter the actual X-value of the ruler 
+     * 
+     * @param value
+     * @return possibly modified X-value 
+     */
+    protected double modifyHorizontalValue(double value) {
+        return value;
+    }
+
+    /**
+     * A method for subclasses to alter the actual Y-value of the ruler 
+     * 
+     * @param value
+     * @return possibly modified Y-value 
+     */
+    protected double modifyVerticalValue(double value) {
+        return value;
+    }
+
     private static final transient int    MAX_DIGITS = 5;
     private static final transient double EPSILON    = 0.01;
     private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 4);
index 10a24ddce9b324f127f628c017734b8079a6fd5e..1007cf675ad96610a625a8d228e9f09c174c9582 100644 (file)
@@ -32,6 +32,7 @@ Export-Package: org.cojen.classfile,
  org.simantics.scl.compiler.elaboration.expressions.block,
  org.simantics.scl.compiler.elaboration.expressions.lhstype,
  org.simantics.scl.compiler.elaboration.expressions.list,
+ org.simantics.scl.compiler.elaboration.expressions.visitors,
  org.simantics.scl.compiler.elaboration.fundeps,
  org.simantics.scl.compiler.elaboration.java,
  org.simantics.scl.compiler.elaboration.macros,
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSessionWithModules.java
new file mode 100644 (file)
index 0000000..57858a5
--- /dev/null
@@ -0,0 +1,89 @@
+package org.simantics.scl.compiler.commands;
+
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.simantics.scl.compiler.errors.Failable;
+import org.simantics.scl.compiler.errors.Failure;
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.repository.ModuleRepository;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.source.StringModuleSource;
+import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
+import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CommandSessionWithModules {
+    private static final Logger LOGGER = LoggerFactory.getLogger(CommandSessionWithModules.class);
+    
+    private MapModuleSourceRepository localModuleSourceRepository;
+    private ModuleRepository moduleRepository;
+    private CommandSession commandSession;
+    
+    private static final SCLReportingHandler DEFAULT_REPORTING_HANDLER = new AbstractSCLReportingHandler() {
+        @Override
+        public void print(String text) {
+            CommandSessionWithModules.LOGGER.info(text);
+        }
+    };
+    
+    public CommandSessionWithModules(ModuleRepository parentRepository) {
+        this.localModuleSourceRepository = new MapModuleSourceRepository();
+        this.moduleRepository = new ModuleRepository(parentRepository, localModuleSourceRepository);
+        this.commandSession = new CommandSession(moduleRepository, DEFAULT_REPORTING_HANDLER);
+        this.commandSession.setDependenciesListener(new UpdateListener() {
+            @Override
+            public void notifyAboutUpdate() {
+                commandSession.updateRuntimeEnvironment(true);
+            }
+        });
+    }
+    
+    public CommandSession getCommandSession() {
+        return commandSession;
+    }
+    
+    /**
+     * Puts the given module to the local module repository. Returns null, if the
+     * compilation of the module succeeded or a string containing the compilation
+     * errors, if it failed.
+     */
+    public String putModule(String moduleName, String moduleText) {
+        StringModuleSource moduleSource = new StringModuleSource(moduleName, moduleText);
+        synchronized(localModuleSourceRepository) {
+            localModuleSourceRepository.addModuleDescriptor(moduleSource);
+        }
+        Failable<Module> 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);
+    }
+}
index 50729430db70e2a07f7cfa894424b82cfdc058b4..183d857967ea4cbcc3504df734ecefcf33764550 100644 (file)
@@ -20,6 +20,7 @@ public class Names {
     public static final Name JavaBuiltin_unsafeCoerce = Name.create("JavaBuiltin", "unsafeCoerce");
     public static final Name MList_add = Name.create("MList", "add");
     public static final Name MList_create = Name.create("MList", "create");
+    public static final Name MList_freeze = Name.create("MList", "freeze");
     public static final Name MList_removeLast = Name.create("MList", "removeLast");
     public static final TCon MList_T = Types.con("MList", "T");
     public static final Name MSet_add = Name.create("MSet", "add");
index fccf2681507466ef7f4c9b6f44dc6aab04f76b04..ff5ee3b2902fa0384258f246776d534dbed0d617 100644 (file)
@@ -61,7 +61,9 @@ import org.simantics.scl.compiler.environment.AmbiguousNameException;
 import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.environment.EnvironmentFactory;
 import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.errors.CompilationError;
 import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.errors.ErrorSeverity;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
 import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
@@ -179,7 +181,7 @@ public class Elaboration {
             compilationContext.environment = new EnvironmentOfModule(importedEnvironment, module);
         } catch (ImportFailureException e) {
             for(ImportFailure failure : e.failures)
-                errorLog.log(failure.location, failure.toString());
+                errorLog.log(new CompilationError(failure.location, failure.toString(), ErrorSeverity.IMPORT_ERROR));
             return;
         }
         for(ImportDeclaration importAst : importsAst)
@@ -1113,6 +1115,7 @@ public class Elaboration {
             int constructorTag = 0;
             for(Constructor constructor : dataType.constructors) {
                 SCLValue value = new SCLValue(constructor.name);
+                value.definitionLocation = constructor.loc;
                 SCLConstructor sclConstructor = 
                         new SCLConstructor(
                                 constructor.name.name,
index 58bb98a417e0d9255e77310c74d5f6feb6c8430a..52b8692d8f9fcc72394af1bbd0b059399367f077 100644 (file)
@@ -408,7 +408,7 @@ public class TypeChecking {
                 for(TransformationRule rule : module.getRules())
                     for(Query[] queries : rule.sections.values())
                         for(Query query : queries)
-                            query.collectRefs(allRefs, refs);                
+                            query.collectRefs(allRefs, refs);
             }
             
             @Override
index 7de438d151e57844f05c9c065435870ed6f129c7..336ed04e3d47afe546bdaf0c649e2bc59ac26f5b 100644 (file)
@@ -8,7 +8,7 @@ import org.simantics.scl.compiler.types.Type;
 
 public class LocalVariableConstant extends Constant {
 
-    LocalVariable var;
+    public LocalVariable var;
     
     public LocalVariableConstant(Type type, LocalVariable var) {
         super(type);
index f44609e6c1b13552b9311025f2872c740a10978c..e0921dc106fa67f50944ef6ebd9c14c3080972bf 100644 (file)
@@ -5,6 +5,7 @@ import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.chr.relations.ExternalCHRRelation;
 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
 import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext.ExistentialFrame;
@@ -12,7 +13,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
 import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
@@ -24,7 +24,6 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class CHRLiteral extends Symbol {
@@ -38,15 +37,20 @@ public class CHRLiteral extends Symbol {
     public boolean negated;
     public boolean passive = true;
     
-    public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean remove, boolean negated) {
+    public CHRLiteral(long location, CHRRelation relation, Expression[] parameters, boolean killAfterMatch, boolean negated) {
         this.location = location;
         this.relation = relation;
         this.parameters = parameters;
-        this.killAfterMatch = remove;
+        this.killAfterMatch = killAfterMatch;
         this.negated = negated;
     }
 
     public void resolve(TranslationContext context) {
+        if(relation == SpecialCHRRelation.ASSIGN) {
+            parameters[1] = parameters[1].resolve(context);
+            parameters[0] = parameters[0].resolveAsPattern(context);
+            return;
+        }
         if(parameters != null) {
             for(int i=0;i<parameters.length;++i)
                 parameters[i] = parameters[i].resolve(context);
@@ -108,14 +112,6 @@ public class CHRLiteral extends Symbol {
         }
     }
 
-    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)
@@ -123,6 +119,11 @@ public class CHRLiteral extends Symbol {
             parameters[0] = parameters[0].checkIgnoredType(context);
             typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
         }
+        else if(relation == SpecialCHRRelation.ASSIGN) {
+            parameters[1] = parameters[1].inferType(context);
+            parameters[0] = parameters[0].checkTypeAsPattern(context, parameters[1].getType());
+            typeConstraintEvidenceParameters = Expression.EMPTY_ARRAY;
+        }
         else {
             TVar[] typeVariables = relation.getTypeVariables();
             typeParameters = typeVariables.length == 0 ? Type.EMPTY_ARRAY : new Type[typeVariables.length];
@@ -147,22 +148,6 @@ public class CHRLiteral extends Symbol {
                 parameter.collectVars(allVars, vars);
     }
 
-    public void forVariables(VariableProcedure procedure) {
-        for(Expression parameter : parameters)
-            parameter.forVariables(procedure);
-        if(typeConstraintEvidenceParameters != null)
-            for(Expression parameter : typeConstraintEvidenceParameters)
-                parameter.forVariables(procedure);
-    }
-
-    public void collectFreeVariables(THashSet<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;
@@ -186,9 +171,14 @@ public class CHRLiteral extends Symbol {
         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;
     }
 }
index 9e2bf6f343c026637ff5dfd0db3ae2af6663c512..2d97ab51819e4d271cea111e42050878da58c6a2 100644 (file)
@@ -3,18 +3,18 @@ package org.simantics.scl.compiler.elaboration.chr;
 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 {
@@ -29,11 +29,6 @@ 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);
@@ -43,17 +38,7 @@ public class CHRQuery extends Symbol {
         for(CHRLiteral literal : literals)
             literal.collectVars(allVars, vars);
     }
-
-    public void forVariables(VariableProcedure procedure) {
-        for(CHRLiteral literal : literals)
-            literal.forVariables(procedure);
-    }
-
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        for(CHRLiteral literal : literals)
-            literal.collectFreeVariables(vars);
-    }
-
+    
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
             this.location = loc;
@@ -62,7 +47,7 @@ public class CHRQuery extends Symbol {
         }
     }
     
-    public boolean createQueryPlan(QueryPlanningContext context, Expression inputFact, int activeLiteralId) {
+    public boolean createQueryPlan(QueryPlanningContext context, Expression inputFact, int activeLiteralId, CHRConstraint initConstraint) {
         for(int i=0;i<literals.length;++i) {
             CHRLiteral literal = literals[i];
             if(i == activeLiteralId)
@@ -70,6 +55,9 @@ public class CHRQuery extends Symbol {
             else
                 context.add(literal, i);
         }
+        if(activeLiteralId == -1 && inputFact != null) {
+            context.addInitFact(initConstraint, inputFact);
+        }      
         return context.createQueryPlan();
     }
     
@@ -91,4 +79,11 @@ public class CHRQuery extends Symbol {
         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);
+    }
 }
index 3daae67a94a348681d489f19915bf7ba36020e23..5436fae95a2204e884f9828e7beef2ec7d70200f 100644 (file)
@@ -6,6 +6,8 @@ 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.set.hash.THashSet;
+
 public interface CHRRelation {
     public static final TVar A = Types.var(Kinds.STAR);
     
@@ -15,4 +17,6 @@ public interface CHRRelation {
     default String[] getFieldNames() {
         return null;
     }
+    void collectEnforceEffects(THashSet<Type> effects);
+    void collectQueryEffects(THashSet<Type> effects);
 }
index 0c81daafd8d3ddfa3b36b5ec327b5ca73f0c8a43..78224ebb0d75d876f0da2528a4ab8fba56a33129 100644 (file)
@@ -11,7 +11,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
@@ -19,7 +18,6 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class CHRRule extends Symbol {
@@ -45,6 +43,10 @@ public class CHRRule extends Symbol {
         this.body = body;
         this.existentialVariables = existentialVariables;
     }
+    
+    public CHRRule(long location, CHRQuery head, CHRQuery body) {
+        this(location, head, body, null);
+    }
 
     public void resolve(TranslationContext context) {
         context.pushExistentialFrame();
@@ -54,11 +56,6 @@ public class CHRRule extends Symbol {
         existentialVariables = context.popExistentialFrame();
     }
 
-    public void collectRefs(TObjectIntHashMap<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));
@@ -71,16 +68,6 @@ public class CHRRule extends Symbol {
         body.collectVars(allVars, vars);
     }
 
-    public void forVariables(VariableProcedure procedure) {
-        head.forVariables(procedure);
-        body.forVariables(procedure);
-    }
-
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        head.collectFreeVariables(vars);
-        body.collectFreeVariables(vars);
-    }
-
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
             this.location = loc;
@@ -104,7 +91,7 @@ public class CHRRule extends Symbol {
             
             Variable activeFact = new Variable("activeFact", constraint.factType);
             QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
-            if(!head.createQueryPlan(context, new EVariable(activeFact), i))
+            if(!head.createQueryPlan(context, new EVariable(activeFact), i, initConstraint))
                 return;
             body.createEnforcePlan(context, priority);
             addPlan(new CHRSearchPlan(constraint, activeFact, context.getPlanOps()));
@@ -115,7 +102,7 @@ public class CHRRule extends Symbol {
         if(!hasLocalActiveLiteral) {
             Variable activeFact = new Variable("activeFact", initConstraint.factType);
             QueryPlanningContext context = new QueryPlanningContext(compilationContext, existentialVariables);
-            if(!head.createQueryPlan(context, null, -1))
+            if(!head.createQueryPlan(context, new EVariable(activeFact), -1, initConstraint))
                 return;
             body.createEnforcePlan(context, priority);
             /*System.out.println(this);
index d670300cbe1a4253758ee5731a766ddc42cac0aa..55bbcfe34f9c245968083ab39e374b9814fc8908 100644 (file)
@@ -23,7 +23,6 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
 import org.simantics.scl.compiler.environment.AmbiguousNameException;
 import org.simantics.scl.compiler.errors.Locations;
@@ -43,7 +42,6 @@ import org.simantics.scl.compiler.types.Types;
 
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class CHRRuleset extends Symbol {
@@ -123,13 +121,6 @@ public class CHRRuleset extends Symbol {
         }*/
     }
 
-    public void collectRefs(TObjectIntHashMap<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);
@@ -144,20 +135,6 @@ public class CHRRuleset extends Symbol {
             rule.collectVars(allVars, vars);
     }
 
-    public void forVariables(VariableProcedure procedure) {
-        for(IncludeStatement include : includes)
-            include.value.forVariables(procedure);
-        for(CHRRule rule : rules)
-            rule.forVariables(procedure);
-    }
-
-    public void collectFreeVariables(THashSet<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;
@@ -283,7 +260,7 @@ public class CHRRuleset extends Symbol {
                     methodWriter.return_(BooleanConstant.TRUE);
             }
         }
-        if(!includes.isEmpty()) {
+        if(!includes.isEmpty() || extensible) {
             {
                 CodeWriter methodWriter = object.createMethod(w.getModuleWriter(), TVar.EMPTY_ARRAY, Types.PROC, Types.UNIT, new Type[] {Types.CHRContext});
                 initializer = methodWriter.getFunction();
@@ -292,6 +269,10 @@ public class CHRRuleset extends Symbol {
                             new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}),
                             object.getTarget(), methodWriter.getParameters()[0], include.storeVar);
                 }
+                if(extensible)
+                       methodWriter.apply(Locations.NO_LOCATION,
+                               new JavaMethod(true, runtimeRulesetClassName, "register", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}),
+                               object.getTarget(), methodWriter.getParameters()[0]);
                 methodWriter.return_(NoRepConstant.UNIT);
             }
             {
@@ -302,6 +283,10 @@ public class CHRRuleset extends Symbol {
                             new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext, include.ruleset.runtimeRulesetType}),
                             object.getTarget(), methodWriter.getParameters()[0], include.storeVar);
                 }
+                if(extensible)
+                       methodWriter.apply(Locations.NO_LOCATION,
+                               new JavaMethod(true, runtimeRulesetClassName, "unregister", Types.PROC, Types.UNIT, new Type[] {runtimeRulesetType, Types.CHRContext}),
+                               object.getTarget(), methodWriter.getParameters()[0]);
                 methodWriter.return_(NoRepConstant.UNIT);
             }
         }
@@ -324,15 +309,6 @@ public class CHRRuleset extends Symbol {
         return runtimeRulesetVariable;
     }
 
-    public void collectEffects(THashSet<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;
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java
new file mode 100644 (file)
index 0000000..7b5f4ff
--- /dev/null
@@ -0,0 +1,148 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EBinary;
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ERecord;
+import org.simantics.scl.compiler.elaboration.expressions.EVar;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
+import org.simantics.scl.compiler.environment.AmbiguousNameException;
+import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.types.Types;
+
+public class CHRAstAtom extends CHRAstQuery {
+    public Expression expression;
+    public boolean remove;
+
+    public CHRAstAtom(Expression expression, boolean remove) {
+        this.expression = expression;
+        this.remove = remove;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+    
+    public static CHRAstQuery atom(Expression expression) {
+        boolean remove = false;
+        if(expression instanceof EVar) {
+            EVar var = (EVar)expression;
+            if(var.name.equals("True")) {
+                CHRAstConjunction query = new CHRAstConjunction(Collections.emptyList());
+                query.location = expression.location;
+                return query;
+            }
+        }
+        else if(expression instanceof EBinary) {
+            EBinary binary = (EBinary)expression;
+            if(binary.negation != null && binary.rights.isEmpty()) {
+                remove = true;
+                expression = binary.left;
+            }
+            // If query is marked for removal, it must be an atom
+        }
+        else if(expression instanceof EApply) {
+            EApply apply = (EApply)expression;
+            if(apply.function instanceof EVar && ((EVar)apply.function).name.equals("not")) {
+                Expression subExpression;
+                if(apply.parameters.length == 1)
+                    subExpression = apply.parameters[0];
+                else
+                    subExpression = new EApply(
+                            Locations.combine(apply.parameters[0].location, apply.parameters[apply.parameters.length-1].location),
+                            apply.parameters[0],
+                            Arrays.copyOfRange(apply.parameters, 1, apply.parameters.length));
+                CHRAstNegation query = new CHRAstNegation(atom(subExpression));
+                query.location = expression.location;
+                return query;
+            }
+            else if(apply.function instanceof EConstant) {
+                Name valueName = ((EConstant)apply.function).getValue().getName();
+                if(valueName.module.equals(Types.BUILTIN) && valueName.name.startsWith("(")) {
+                    CHRAstQuery[] conjuncts = new CHRAstQuery[apply.parameters.length];
+                    for(int i=0;i<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;
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java
new file mode 100644 (file)
index 0000000..2f2654c
--- /dev/null
@@ -0,0 +1,29 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+
+public class CHRAstBinds extends CHRAstQuery {
+    public Expression left;
+    public Expression right;
+    
+    public CHRAstBinds(Expression left, Expression right) {
+        this.left = left;
+        this.right = right;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+    
+    @Override
+    protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList<CHRLiteral> literals) {
+        literals.add(new CHRLiteral(location, SpecialCHRRelation.MEMBER,
+                new Expression[] { left, right }, false, false));
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java
new file mode 100644 (file)
index 0000000..1aadb69
--- /dev/null
@@ -0,0 +1,40 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+
+public class CHRAstConjunction extends CHRAstQuery {
+    public List<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);
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java
new file mode 100644 (file)
index 0000000..6c5e6e8
--- /dev/null
@@ -0,0 +1,29 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+
+public class CHRAstEquals extends CHRAstQuery {
+    public Expression left;
+    public Expression right;
+    
+    public CHRAstEquals(Expression left, Expression right) {
+        this.left = left;
+        this.right = right;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    @Override
+    protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList<CHRLiteral> literals) {
+        literals.add(new CHRLiteral(location, mode.isHead ? SpecialCHRRelation.EQUALS : SpecialCHRRelation.ASSIGN,
+                new Expression[] { left, right }, false, false));
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java
new file mode 100644 (file)
index 0000000..4f73d66
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+
+public class CHRAstNegation extends CHRAstQuery {
+    public CHRAstQuery subquery;
+    
+    public CHRAstNegation(CHRAstQuery subquery) {
+        this.subquery = subquery;
+    }
+
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    @Override
+    protected void translate(TranslationContext context, CHRQueryTranslationMode mode, ArrayList<CHRLiteral> literals) {
+        context.getCompilationContext().errorLog.log(location, "CHR negation is not yet supported.");
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java
new file mode 100644 (file)
index 0000000..e655c78
--- /dev/null
@@ -0,0 +1,20 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+
+public abstract class CHRAstQuery extends Symbol {
+    public CHRQuery translate(TranslationContext context, CHRQueryTranslationMode mode) {
+        ArrayList<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);
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java
new file mode 100644 (file)
index 0000000..3c7b425
--- /dev/null
@@ -0,0 +1,9 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+public interface CHRAstQueryVisitor {
+    void visit(CHRAstAtom query);
+    void visit(CHRAstBinds query);
+    void visit(CHRAstConjunction query);
+    void visit(CHRAstEquals query);
+    void visit(CHRAstNegation query);
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRQueryTranslationMode.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRQueryTranslationMode.java
new file mode 100644 (file)
index 0000000..483c028
--- /dev/null
@@ -0,0 +1,13 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+public enum CHRQueryTranslationMode {
+    RULE_HEAD(true),
+    QUERY_HEAD(true),
+    RULE_BODY(false);
+    
+    public final boolean isHead;
+
+    private CHRQueryTranslationMode(boolean isHead) {
+        this.isHead = isHead;
+    }
+}
index 4874c14fe57f4c71533045e8484549f3a11f98cd..ab37d253a50dbcfdf709553a13230f9f1f89fe54 100644 (file)
@@ -47,5 +47,4 @@ public class AccessFactOp extends PlanOp {
         if(end != null)
             end.return_(BooleanConstant.FALSE);
     }
-
 }
index 5ef54ea82ac414b071e516d0e6308317ee342769..730caba73302d88ea74e660370fd2508cf17d3ce 100644 (file)
@@ -25,6 +25,4 @@ public class AssignOp extends PlanOp {
         variable.setVal(expression.toVal(context, w));
         planContext.nextOp(w);
     }
-
-    
 }
index a792256049a1551900d5c26de0f6552c7967f70f..aa317a2b27ee372568a982c138daa2bcaa625eb1 100644 (file)
@@ -17,6 +17,6 @@ public abstract class PlanOp {
         return b.toString();
     }
 
-    public abstract void toString(StringBuilder b);
+    public void toString(StringBuilder b) {}
     public abstract void generateCode(CompilationContext context, PlanContext planContext, CodeWriter w);
 }
index 537a2aa9dca73a0495b7eb794d8f7c5abf16bef0..56d436f5573f592325a99e5ca93042c2656a7c0f 100644 (file)
@@ -8,6 +8,7 @@ import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
 import org.simantics.scl.compiler.elaboration.chr.plan.AccessFactOp;
 import org.simantics.scl.compiler.elaboration.chr.plan.ClaimOp;
 import org.simantics.scl.compiler.elaboration.chr.plan.ExecuteOp;
+import org.simantics.scl.compiler.elaboration.chr.plan.MatchOp;
 import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;
 import org.simantics.scl.compiler.elaboration.chr.planning.items.CheckPrePlanItem;
 import org.simantics.scl.compiler.elaboration.chr.planning.items.EqualsPrePlanItem;
@@ -22,6 +23,7 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.errors.Locations;
 
 import gnu.trove.impl.Constants;
 import gnu.trove.map.hash.TObjectIntHashMap;
@@ -64,6 +66,8 @@ public class QueryPlanningContext {
             case MEMBER:
                 addMember(literal.location, literal.parameters[0], literal.parameters[1], secondaryPriority);
                 return;
+            case ASSIGN:
+                throw new InternalCompilerError(literal.location, "ASSIGN constraint is not allowed in query compilation.");
             case EXECUTE:
                 throw new InternalCompilerError(literal.location, "EXECUTE constraint is not allowed in query compilation.");
             }
@@ -223,6 +227,10 @@ public class QueryPlanningContext {
         for(int i=0;i<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) {
@@ -234,6 +242,9 @@ public class QueryPlanningContext {
             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,
index ee73477912e3d8ff385f83a29e33562eae8ce0a2..8b7c122a98458b1a8fa5fbac7e745ae36edb72cf 100644 (file)
@@ -30,6 +30,7 @@ import org.simantics.scl.compiler.types.Type;
 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;
@@ -235,4 +236,14 @@ public class CHRConstraint extends Symbol implements CHRRelation {
     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);
+    }
 }
index 6f44bc2ab6852bd0211f6f508f5b629ff8fda4a2..fdfa195ac53158f9e4f94606ef676e102e296b16 100644 (file)
@@ -6,6 +6,8 @@ import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 
+import gnu.trove.set.hash.THashSet;
+
 public class ExternalCHRRelation implements CHRRelation {
     public final SCLRelation relation;
 
@@ -37,4 +39,14 @@ public class ExternalCHRRelation implements CHRRelation {
     public String[] getFieldNames() {
         return relation.getFieldNames();
     }
+
+    @Override
+    public void collectEnforceEffects(THashSet<Type> effects) {
+        effects.add(relation.getEnforceEffect());
+    }
+
+    @Override
+    public void collectQueryEffects(THashSet<Type> effects) {
+        effects.add(relation.getQueryEffect());
+    }
 }
index c5dbe3c4190b54cf7aff3c08101168a6b50626b5..8abf73b3eae2827c16efc30d17b302ccfcb243af 100644 (file)
@@ -6,11 +6,14 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.set.hash.THashSet;
+
 public enum SpecialCHRRelation implements CHRRelation {    
-    EQUALS(A, A),
-    MEMBER(A, Types.list(A)),
-    CHECK(Types.BOOLEAN),
-    EXECUTE(Types.UNIT);
+    EQUALS(A, A), // only in head
+    ASSIGN(A, A), // only in body
+    MEMBER(A, Types.list(A)), // only in head
+    CHECK(Types.BOOLEAN), // only in head
+    EXECUTE(Types.UNIT); // only in body
     
     private final TVar[] typeVariables;
     private final Type[] parameterTypes;
@@ -33,4 +36,12 @@ public enum SpecialCHRRelation implements CHRRelation {
     public TPred[] getTypeConstraints() {
         return TPred.EMPTY_ARRAY;
     }
+
+    @Override
+    public void collectEnforceEffects(THashSet<Type> effects) {
+    }
+
+    @Override
+    public void collectQueryEffects(THashSet<Type> effects) {
+    }
 }
index c852062fb3e2b1b236f83a1656b853a04efb5929..6cf2930de5a7adb2c4f954195da6e76e0aa5abd3 100644 (file)
@@ -6,6 +6,9 @@ import org.simantics.scl.compiler.internal.parsing.Symbol;
 import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+import gnu.trove.set.hash.THashSet;
 
 public class UnresolvedCHRRelation extends Symbol implements CHRRelation {
     public String name;
@@ -28,4 +31,14 @@ public class UnresolvedCHRRelation extends Symbol implements CHRRelation {
     public TPred[] getTypeConstraints() {
         throw new InternalCompilerError("Encountered unresolved CHRRelation during type checking.");
     }
+
+    @Override
+    public void collectEnforceEffects(THashSet<Type> effects) {
+        effects.add(Types.PROC);
+    }
+
+    @Override
+    public void collectQueryEffects(THashSet<Type> effects) {
+        effects.add(Types.PROC);
+    }
 }
index 367960dfafc0a35f5f2ddb0d9870bd9152c6924c..260927b74c6c3659e12997035a80cfd5c5fb167a 100644 (file)
@@ -3,10 +3,8 @@ package org.simantics.scl.compiler.elaboration.chr.translation;
 import java.util.ArrayList;
 import java.util.Arrays;
 
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
-import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
 import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
@@ -16,7 +14,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EBinary;
 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
 import org.simantics.scl.compiler.elaboration.expressions.EVar;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
@@ -131,24 +128,22 @@ public class CHRTranslation {
         }
     }
 
-    public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) {
-        ArrayList<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));
index 1bb40c5faa2acb72e3fa0e8f1856767d811c226e..b526cb3f0950d647cc8002661766abe982be87a7 100644 (file)
@@ -3,8 +3,10 @@ package org.simantics.scl.compiler.elaboration.contexts;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
 
 import gnu.trove.map.hash.THashMap;
 
@@ -37,4 +39,28 @@ public class ReplaceContext {
     public ReplaceContext(TypingContext typingContext) {
         this(new THashMap<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;
+    }
 }
index ac9299d77f968a3a7623c5974005eacd5502f87c..b533e922d252d0bcd73c07324564b9e3cde8236a 100644 (file)
@@ -75,6 +75,8 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
     TIntArrayList chrConstraintFrames = new TIntArrayList();
     ArrayList<CHRConstraintEntry> chrConstraintEntries = new ArrayList<CHRConstraintEntry>();
     
+    public CHRRuleset currentRuleset;
+    
     static class Entry {
         String name;
         Variable variable;
index 80d2a7578f216e9a364c3491d3476f9ac49566e2..785c27da0e6286e9f81222d266331cd6c4808815 100644 (file)
@@ -4,15 +4,7 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public class EqBasic extends Equation {
     public Expression left;
@@ -37,48 +29,12 @@ public class EqBasic extends Equation {
         }
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        left.forVariables(procedure);
-        right.forVariables(procedure);
-    }
-
-    @Override
-    public void collectFreeVariables(THashSet<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);
index c8bf5c12024ff43219f93447dd52b04039f5c95e..c72d9433f8e835f0f8adff9455743671668e0364 100644 (file)
@@ -4,15 +4,7 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public class EqGuard extends Equation {
     public Expression guard;
@@ -34,41 +26,11 @@ public class EqGuard extends Equation {
         }
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        guard.forVariables(procedure);
-    }
-
-    @Override
-    public void collectFreeVariables(THashSet<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);
index dbd22037ff8425f7685996ff67d6cac4500c3af5..cb801a33d6f03c2455b05d6755df339130687190 100644 (file)
@@ -3,28 +3,14 @@ package org.simantics.scl.compiler.elaboration.equation;
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
-import org.simantics.scl.compiler.types.Type;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public abstract class Equation extends Symbol {
     public static final Equation[] EMPTY_ARRAY = new Equation[0];    
 
     public abstract void setLocationDeep(long loc);
 
-    public abstract void forVariables(VariableProcedure procedure);
-    public abstract void collectFreeVariables(THashSet<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);
index fbc0a79014dcb107c3b17842ef5bbb06fddaac8b..c96218b6524d74b37dbe1bd1882071bb300239b2 100644 (file)
@@ -3,14 +3,10 @@ package org.simantics.scl.compiler.elaboration.expressions;
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public abstract class ASTExpression extends SimplifiableExpression {
     public ASTExpression() {
     }
@@ -20,41 +16,18 @@ public abstract class ASTExpression extends SimplifiableExpression {
         throw new InternalCompilerError(getClass().getSimpleName() + " does not support simplify.");
     }
     
-    @Override
-    final public void collectFreeVariables(THashSet<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.");
     }
     
@@ -71,8 +44,8 @@ public abstract class ASTExpression extends SimplifiableExpression {
     }
     
     @Override
-    public void forVariables(VariableProcedure procedure) {
-        throw new InternalCompilerError("Class " + 
-                getClass().getSimpleName() + " does not implement method forVariables.");
+    public void setLocationDeep(long loc) {
+        if(location == Locations.NO_LOCATION)
+            location = loc;
     }
 }
index 7cc70aaa77bed69f6328ce0a5055f884301f201b..cb525a9adfdef3bde0c5ab1b8dfdae5d63e51a19 100644 (file)
@@ -1,7 +1,6 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 
 public class Assignment {
@@ -25,17 +24,8 @@ public class Assignment {
         return new Assignment(newPattern, newValue);
     }
 
-    public void decorate(ExpressionDecorator decorator) {
-        pattern = pattern.decorate(decorator);
-        value = value.decorate(decorator);
-    }
-
     public void setLocationDeep(long loc) {
         pattern.setLocationDeep(loc);
         value.setLocationDeep(loc);
     }
-
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-    }
 }
index 4a34cebcf4b283dbc146b111f6c7e9d5474e097a..a50bcc2ddf926b37b02b04f39dce0273088c721c 100644 (file)
@@ -5,14 +5,9 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 import org.simantics.scl.compiler.types.Type;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class Case extends Symbol {
     public Expression[] patterns;
     public Expression value;
@@ -36,21 +31,6 @@ public class Case extends Symbol {
         return lhs;
     }
 
-       public void collectRefs(TObjectIntHashMap<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)
@@ -110,14 +90,4 @@ public class Case extends Symbol {
             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);
-    }
 }
index 3d2031ee5af6154cb9a1f89b071358a4c91410b3..4563e241ed1e2104b02d445dd1e9a7ac6180180c 100644 (file)
@@ -12,14 +12,9 @@ import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
 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;
     
@@ -28,27 +23,11 @@ public abstract class DecoratingExpression extends SimplifiableExpression {
         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);
@@ -87,17 +66,6 @@ public abstract class DecoratingExpression extends SimplifiableExpression {
     public int getFunctionDefinitionPatternArity() throws NotPatternException {
         return expression.getFunctionDefinitionPatternArity();
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        expression = expression.decorate(decorator);
-        return this;
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        expression.collectEffects(effects);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -107,11 +75,6 @@ public abstract class DecoratingExpression extends SimplifiableExpression {
         }
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        expression.forVariables(procedure);
-    }
-
     @Override
     public IVal toVal(CompilationContext context, CodeWriter w) {
         throw new InternalCompilerError("Cannot generate code for " + getClass().getSimpleName() + ".");
index 6121a57b19d66d4480bc5eec74b1da13bff55b33..09397ba058a297f7c3ce8c146eb8a28e5cad9613 100644 (file)
@@ -6,7 +6,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Skeletons;
 import org.simantics.scl.compiler.types.TMetaVar;
 import org.simantics.scl.compiler.types.Type;
@@ -17,9 +16,6 @@ import org.simantics.scl.compiler.types.util.TypeListener;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
 import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public class EAmbiguous extends SimplifiableExpression {
     public static final boolean DEBUG = false;
@@ -28,7 +24,7 @@ public class EAmbiguous extends SimplifiableExpression {
     boolean[] active;
     int activeCount;
     transient TypingContext context;
-    Expression resolvedExpression;
+    public Expression resolvedExpression;
     
     public abstract static class Alternative {
         public abstract Type getType();
@@ -43,20 +39,6 @@ public class EAmbiguous extends SimplifiableExpression {
         this.activeCount = alternatives.length;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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();
@@ -94,7 +76,7 @@ public class EAmbiguous extends SimplifiableExpression {
         StringBuilder b = new StringBuilder();
         b.append("Expected <");
         requiredType.toString(new TypeUnparsingContext(), b);
-        b.append(">, but no alteratives match the type: ");
+        b.append(">, but no alternatives match the type: ");
         for(int i=0;i<alternatives.length;++i) {
             b.append("\n    ");
             b.append(alternatives[i]);
@@ -173,10 +155,6 @@ public class EAmbiguous extends SimplifiableExpression {
         listenType();
         return this;
     }
-    
-    @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
-    }
 
     @Override
     public Expression resolve(TranslationContext context) {
@@ -189,19 +167,9 @@ public class EAmbiguous extends SimplifiableExpression {
             location = loc;
     }
 
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return this;
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        // TODO Auto-generated method stub
-    }
-
     @Override
     public void accept(ExpressionVisitor visitor) {
-        // TODO Auto-generated method stub
+        visitor.visit(this);
     }
     
     @Override
index c7bce466759d62eaf154c4a0a415b634249903cf..02c7dff4585c95e0d55d7bf485266f90327b31e6 100644 (file)
@@ -19,7 +19,6 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IApply;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.interpreted.IListLiteral;
@@ -33,14 +32,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.MultiFunction;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EApply extends Expression {
     public Expression function;
     public Expression[] parameters;
-    Type effect = Types.NO_EFFECTS;
+    public Type effect = Types.NO_EFFECTS;
     
     public EApply(Expression function, Expression ... parameters) {
         this.function = function;
@@ -76,22 +71,9 @@ public class EApply extends Expression {
     public Expression[] getParameters() {
         return parameters;
     }
-    
 
-    public void collectRefs(TObjectIntHashMap<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]))
@@ -110,13 +92,6 @@ public class EApply extends Expression {
         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) {
@@ -194,13 +169,6 @@ public class EApply extends Expression {
         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) {
@@ -303,16 +271,6 @@ public class EApply extends Expression {
             return new ESimpleLet(location, null, this, new ELiteral(NoRepConstant.PUNIT));
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        if(decorator.decorateSubstructure(this)) {
-            function = function.decorate(decorator);
-            for(int i=0;i<parameters.length;++i)
-                parameters[i] = parameters[i].decorate(decorator);
-        }
-        return decorator.decorate(this);
-    }
     
     public Type getLocalEffect() {
         return effect;
@@ -358,14 +316,6 @@ public class EApply extends Expression {
         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);
@@ -380,13 +330,6 @@ public class EApply extends Expression {
             return false;
         }
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        function.forVariables(procedure);
-        for(Expression parameter : parameters)
-            parameter.forVariables(procedure);
-    }
     
     @Override
     public boolean isPattern(int arity) {
index d07b6d13bc17d6f6702c2ca7050f9e0916c69272..30d1209cea12b692c3575337033d31bfe29ac5bd 100644 (file)
@@ -9,19 +9,14 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EApplyType extends Expression {    
-    Expression expression;
+    public Expression expression;
     Type parameter;
     
     public EApplyType(Expression expression, Type parameter) {
@@ -51,30 +46,17 @@ public class EApplyType extends Expression {
         return parameter;
     }
 
-       public void collectRefs(TObjectIntHashMap<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);
@@ -90,11 +72,6 @@ public class EApplyType extends Expression {
         expression = expression.resolve(context);
         return this;
     }
-    
-    @Override
-    public void removeFreeVariables(THashSet<Variable> vars) {
-        expression.removeFreeVariables(vars);
-    }
 
     @Override
     public Expression replace(ReplaceContext context) {
@@ -111,22 +88,11 @@ public class EApplyType extends Expression {
     public Expression inferType(TypingContext context) {
         throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + ".");
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        expression = expression.decorate(decorator);
-        return decorator.decorate(this);
-    }
     
     @Override
     public boolean isEffectful() {
        return expression.isEffectful();
     }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        expression.collectEffects(effects);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -140,11 +106,6 @@ public class EApplyType extends Expression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        expression.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 62cea76d8fbcfc8e7d8b3591f1d529fc7c0e010b..21248179f9a7711732edf31c359c41d799f1b8fb 100644 (file)
@@ -9,19 +9,14 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EAsPattern extends Expression {
 
-    Variable var;
-    EVar eVar;
-    Expression pattern;
+    public Variable var;
+    public EVar eVar;
+    public Expression pattern;
 
     public EAsPattern(EVar eVar, Expression pattern) {
         this.eVar = eVar;
@@ -40,32 +35,6 @@ public class EAsPattern extends Expression {
     public Expression getPattern() {
         return pattern;
     }
-
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -109,12 +78,6 @@ public class EAsPattern extends Expression {
         var.setType(pattern.getType());
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        pattern = pattern.decorate(decorator);
-        return decorator.decorate(this);
-    }
     
     @Override
     public Expression replace(ReplaceContext context) {
@@ -130,11 +93,6 @@ public class EAsPattern extends Expression {
         
         return result;
     }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        pattern.collectEffects(effects);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -150,12 +108,6 @@ public class EAsPattern extends Expression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        procedure.execute(eVar.location, var);
-        pattern.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index d950e7b738eb07124ae4e6549437c7b9ffb7dfb1..5c4a729e2e15fb748a7a17e7793c48d4257e196b 100644 (file)
@@ -9,22 +9,17 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EBind extends SimplifiableExpression {
     public Expression pattern;
     public Expression value;
     public Expression in;
-    private EVariable monadEvidence;
+    public EVariable monadEvidence;
     SCLValue bindFunction;
     Type monadType;
     Type valueContentType;
@@ -44,19 +39,6 @@ public class EBind extends SimplifiableExpression {
         this.value = value;
         this.in = in;
     }
-
-    @Override
-    public void collectRefs(final TObjectIntHashMap<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 {
@@ -117,13 +99,6 @@ public class EBind extends SimplifiableExpression {
         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);
@@ -138,21 +113,6 @@ public class EBind extends SimplifiableExpression {
         return this; 
     }
     
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        pattern = pattern.decorate(decorator);
-        value = value.decorate(decorator);
-        in = in.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        pattern.collectEffects(effects);
-        value.collectEffects(effects);
-        in.collectEffects(effects);
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -167,14 +127,6 @@ public class EBind extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        pattern.forVariables(procedure);
-        value.forVariables(procedure);
-        if(monadEvidence != null)
-            monadEvidence.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 2c70bd90742ef6562d8c9f141bd705838264dc82..ea47c57b23a5cb90fe33be40fd626590ee910261 100644 (file)
@@ -3,7 +3,9 @@ package org.simantics.scl.compiler.elaboration.expressions;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRQueryTranslationMode;
 import org.simantics.scl.compiler.elaboration.chr.translation.CHRTranslation;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
@@ -18,7 +20,7 @@ import org.simantics.scl.compiler.errors.Locations;
 
 public class EBlock extends ASTExpression {
 
-    ArrayList<Statement> statements = new ArrayList<Statement>();
+    public ArrayList<Statement> statements = new ArrayList<Statement>();
     boolean monadic;
     
     public EBlock() {
@@ -92,8 +94,12 @@ public class EBlock extends ASTExpression {
         ruleset.location = Locations.combine(statements.get(begin).location, statements.get(end-1).location);
         for(int i=begin;i<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)
index 9a8aa78b929199b8e6aad3b4db405d4e9e2e2b15..e3fc0a4f2c5a56279d2580981b02a924b01ddcaf 100644 (file)
@@ -8,62 +8,47 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class 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
@@ -74,16 +59,7 @@ public class ECHRRuleset extends Expression {
             in.setLocationDeep(loc);
         }
     }
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        in = in.decorate(decorator);
-        return this;
-    }
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        ruleset.collectEffects(effects);
-        in.collectEffects(effects);
-    }
+    
     @Override
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
index 7965b50114c7b9f31a6f0c625f6ed7fdadab4abf..431bd850dd4e8225f74d3c13284073a60b9d588a 100644 (file)
@@ -9,47 +9,27 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ECHRRulesetConstructor extends Expression {
-    CHRRuleset ruleset;
+    public CHRRuleset ruleset;
     
     public ECHRRulesetConstructor(CHRRuleset ruleset) {
         this.ruleset = ruleset;
     }
-    
-    @Override
-    public void collectRefs(TObjectIntHashMap<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();
@@ -67,14 +47,6 @@ public class ECHRRulesetConstructor extends Expression {
         }
     }
     @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);
     }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ECHRSelect.java
new file mode 100644 (file)
index 0000000..db65168
--- /dev/null
@@ -0,0 +1,128 @@
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.compilation.CompilationContext;
+import org.simantics.scl.compiler.constants.NoRepConstant;
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
+import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanOp;
+import org.simantics.scl.compiler.elaboration.chr.plan.PlanRealizer;
+import org.simantics.scl.compiler.elaboration.chr.planning.QueryPlanningContext;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+public class ECHRSelect extends Expression {
+    public CHRQuery query;
+    public Variable[] existentialVariables;
+    public Expression expression;
+    private ArrayList<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;
+    }
+}
index 6b99e6d37f4ad320077cd91a4735103ff9e86b7b..b33ebcf2551ca99ad34612bd2a978d53ce975025 100644 (file)
@@ -1,6 +1,8 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
 
 import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.common.precedence.Precedence;
@@ -13,11 +15,11 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
+import org.simantics.scl.compiler.elaboration.java.DynamicConstructor;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IConstant;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -31,12 +33,8 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.MultiFunction;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EConstant extends Expression {
-    SCLValue value;
+    public SCLValue value;
     Type[] typeParameters;
     
     public EConstant(SCLValue value, Type ... typeParameters) {
@@ -83,24 +81,18 @@ public class EConstant extends Expression {
             setType(Types.instantiate(getType(), type));
         return this;
     }
-
-       public void collectRefs(TObjectIntHashMap<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));
@@ -113,17 +105,13 @@ public class EConstant extends Expression {
         setType(Types.instantiate(value.getType(), typeParameters));
     }
     
-       @Override
-       public IVal toVal(CompilationContext context, CodeWriter w) {
-           IVal val = value.getValue();                
-           if(typeParameters.length > 0) {
-               val = val.createSpecialization(typeParameters);
-           }
-           return val;
-    }
-
     @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
+    public IVal toVal(CompilationContext context, CodeWriter w) {
+        IVal val = value.getValue();           
+        if(typeParameters.length > 0) {
+            val = val.createSpecialization(typeParameters);
+        }
+        return val;
     }
 
     @Override
@@ -158,10 +146,6 @@ public class EConstant extends Expression {
     public Expression resolveAsPattern(TranslationContext context) {
         return this;
     }
-       
-    @Override
-    public void removeFreeVariables(THashSet<Variable> vars) {     
-    }
 
     @Override
     public Expression replace(ReplaceContext context) {
@@ -207,7 +191,7 @@ public class EConstant extends Expression {
             context.recursiveReferences.add(placeholder);
             return placeholder;
         }
-        else if(context.isInPattern()) {
+        else if(context.isInPattern() && value.getValue() != DynamicConstructor.INSTANCE /* HACK!! */) {
             /* This is little hackish code that handles the following kind of constructors:
              *   data Thunk a = Thunk s (a -> s)
              * in
@@ -234,19 +218,10 @@ public class EConstant extends Expression {
         else
             return applyPUnit(context);
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return decorator.decorate(this);
-    }
     
     @Override
     public boolean isEffectful() {
-       return false;
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
+        return false;
     }
     
     @Override
@@ -264,10 +239,6 @@ public class EConstant extends Expression {
     public Precedence getPrecedence() {
         return value.getPrecedence();
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-    }
     
     @Override
     public boolean isPattern(int arity) {
index 53d9037e28fde54d67afbb45935d24bb397504ff..8e1adf7849c51b2b41bcb56bdc6df95e60f5b112 100644 (file)
@@ -9,18 +9,12 @@ import org.simantics.scl.compiler.elaboration.query.QExists;
 import org.simantics.scl.compiler.elaboration.query.Query;
 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EEnforce extends SimplifiableExpression {
     
-    Query query;
+    public Query query;
     
     public EEnforce(Query query) {
         this.query = query;
@@ -30,23 +24,6 @@ public class EEnforce extends SimplifiableExpression {
         return query;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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));
@@ -63,11 +40,6 @@ public class EEnforce extends SimplifiableExpression {
         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);
@@ -84,11 +56,6 @@ public class EEnforce extends SimplifiableExpression {
             query = new QExists(variables, query);
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {     
-        return decorator.decorate(this);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -102,11 +69,6 @@ public class EEnforce extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        query.forVariables(procedure);
-    }
     
     @Override
     public Expression replace(ReplaceContext context) {
index 3d3132cf9db7d29b07aabca403556c2c1aaa5ef1..7773a5346c00820cfe2c9a09dc3ecab2cc0cec64 100644 (file)
@@ -6,15 +6,10 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.equation.Equation;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EEquations extends SimplifiableExpression {
 
     public Equation[] equations;
@@ -50,50 +45,11 @@ public class EEquations extends SimplifiableExpression {
         return transformer.transform(this);
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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);
index b329beb1937e636a2d0f44dc445b1a5317fd3d63..997a5723b66b05a501c5b38eabdf088cc19ce684 100644 (file)
@@ -8,16 +8,11 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EError extends Expression {
 
     public EError(long loc, Type type) {
@@ -25,33 +20,21 @@ public class EError extends Expression {
         setType(type);
     }
     
-    public EError() {     
+    public EError() {
     }
     
     public EError(long loc) {
         this(loc, Types.metaVar(Kinds.STAR));
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -68,15 +51,6 @@ public class EError extends Expression {
     public Expression inferType(TypingContext context) {
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return this;
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -93,10 +67,6 @@ public class EError extends Expression {
     public Expression replace(ReplaceContext context) {
         return this;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 4777b2dfb670650ecff46e9b258a3c271ab419b1..788483dbe475ba82d33c41496e1e0bef5ef08feb 100644 (file)
@@ -8,12 +8,10 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
-import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
 import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IConstant;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -21,10 +19,6 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EExternalConstant extends Expression {
     Object value;
     
@@ -37,34 +31,21 @@ public class EExternalConstant extends Expression {
         return value;
     }
 
-       public void collectRefs(TObjectIntHashMap<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;
@@ -90,23 +71,10 @@ public class EExternalConstant extends Expression {
         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) {
@@ -123,10 +91,6 @@ public class EExternalConstant extends Expression {
     public IExpression toIExpression(ExpressionInterpretationContext context) {
         return new IConstant(value);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index a8d117f5df94d93d265c140355ebc8ea417fd65e..04a5840f5c731b24bfcf8cf0b71f17d832676d72 100644 (file)
@@ -11,22 +11,17 @@ import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous.Alternative
 import org.simantics.scl.compiler.elaboration.expressions.accessor.FieldAccessor;
 import org.simantics.scl.compiler.elaboration.expressions.accessor.IdAccessor;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.header.ModuleHeader;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EFieldAccess extends SimplifiableExpression {
 
     private static final Type VARIABLE = Types.con("Simantics/Variables", "Variable");
     
-    Expression parent;
-    FieldAccessor accessor;
+    public Expression parent;
+    public FieldAccessor accessor;
     boolean lastAccessor = true;
 
     public EFieldAccess(Expression parent, FieldAccessor accessor) {
@@ -36,20 +31,6 @@ public class EFieldAccess extends SimplifiableExpression {
                ((EFieldAccess)parent).lastAccessor = false;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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();
     }
@@ -120,12 +101,6 @@ public class EFieldAccess extends SimplifiableExpression {
         return this;
     }
 
-    @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        parent.collectFreeVariables(vars);
-        accessor.collectFreeVariables(vars);
-    }
-
     @Override
     public Expression simplify(SimplificationContext context) {
         // Simplify subexpressions
@@ -166,17 +141,6 @@ public class EFieldAccess extends SimplifiableExpression {
         accessor.resolve(context);
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        // FIXME
-        effects.add(Types.READ_GRAPH);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -191,12 +155,6 @@ public class EFieldAccess extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        parent.forVariables(procedure);
-        accessor.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index cd34db4b597de5ae6d3ff9caf909ef4ff651ec2d..24ff0a149344a928ef453773e653bb0c8ea0d0b4 100644 (file)
@@ -4,35 +4,17 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.TPred;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EGetConstraint extends SimplifiableExpression {
     TPred constraint;
-    EVariable evidence;
+    public EVariable evidence;
         
     public EGetConstraint(long loc, TPred constraint) {
         super(loc);
         this.constraint = constraint;
     }
-
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -49,12 +31,6 @@ public class EGetConstraint extends SimplifiableExpression {
         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);
@@ -65,15 +41,6 @@ public class EGetConstraint extends SimplifiableExpression {
         return this;
     }
     
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {     
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -87,11 +54,6 @@ public class EGetConstraint extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        evidence.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 661de4261e260c09b1cd543f3ac5e2dc97df7339..fe6216fe153c3bb8fec3da0e83c86940aa8a9269 100644 (file)
@@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IConstant;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.interpreted.IIf;
@@ -18,10 +17,6 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.runtime.tuple.Tuple0;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EIf extends Expression {
     public Expression condition;
     public Expression then_;
@@ -40,29 +35,13 @@ public class EIf extends Expression {
         this.else_ = else_;
     }
 
-       public void collectRefs(TObjectIntHashMap<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();
@@ -83,14 +62,6 @@ public class EIf extends Expression {
         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);
@@ -136,27 +107,10 @@ public class EIf extends Expression {
         return this;
     }
     
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        condition = condition.decorate(decorator);
-        then_ = then_.decorate(decorator);
-        if(else_ != null)
-            else_ = else_.decorate(decorator);        
-        return decorator.decorate(this);
-    }
-    
     @Override
     public boolean isEffectful() {
        return condition.isEffectful() || then_.isEffectful() || (else_ != null && else_.isEffectful());
     }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        condition.collectEffects(effects);
-        then_.collectEffects(effects);
-        if(else_ != null)
-            else_.collectEffects(effects);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -180,13 +134,6 @@ public class EIf extends Expression {
                 else_ != null ? else_.toIExpression(target) : new IConstant(Tuple0.INSTANCE));
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        condition.forVariables(procedure);
-        then_.forVariables(procedure);
-        if(else_ != null)
-            else_.forVariables(procedure);
-    }
     @Override
     public Expression accept(ExpressionTransformer transformer) {
         return transformer.transform(this);
index 0fbb6a506ac54780279f50b02444480d5d6f5e9e..dc265934a75383dc7f017f794880726dacd71ea9 100644 (file)
@@ -12,32 +12,17 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EIntegerLiteral extends SimplifiableExpression {
     public String value;
-    EVariable constraint;
+    public EVariable constraint;
 
     public EIntegerLiteral(String value) {
         this.value = value;
     }
-
-    @Override
-    public void collectRefs(TObjectIntHashMap<Object> allRefs,
-            TIntHashSet refs) {
-    }
-
-    @Override
-    public void collectVars(TObjectIntHashMap<Variable> allVars,
-            TIntHashSet vars) {
-    }
     
     public String getValue() {
         return value;
@@ -80,10 +65,6 @@ public class EIntegerLiteral extends SimplifiableExpression {
         throw new InternalCompilerError();
     }
 
-    @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
-    }
-
     @Override
     public Expression simplify(SimplificationContext context) {
         try {
@@ -118,20 +99,11 @@ public class EIntegerLiteral extends SimplifiableExpression {
         copy.constraint = (EVariable)constraint.replace(context);
         return copy;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {     
-        return decorator.decorate(this);
-    }
     
     @Override
     public boolean isEffectful() {
        return false;
     }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -146,12 +118,6 @@ public class EIntegerLiteral extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        if(constraint != null)
-            constraint.forVariables(procedure);
-    }
     
     @Override
     public boolean isPattern(int arity) {
index 67a7e147653ef9ce916858e60ab8554a27b57767..ccf86bbf5110204bcdf63bedf130dbc4e5327265 100644 (file)
@@ -5,7 +5,6 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
@@ -13,10 +12,6 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.MultiFunction;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ELambda extends SimplifiableExpression {
     public Case[] cases;
     Type effect = Types.NO_EFFECTS;
@@ -38,20 +33,8 @@ public class ELambda extends SimplifiableExpression {
         this(loc, new Case(new Expression[] {pat}, exp));
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -104,12 +87,6 @@ public class ELambda extends SimplifiableExpression {
            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)
@@ -173,39 +150,16 @@ public class ELambda extends SimplifiableExpression {
         context.popEffectUpperBound();
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        if(decorator.decorateSubstructure(this))
-            for(Case case_ : cases)
-                case_.decorate(decorator);
-        return decorator.decorate(this);
-    }
     
     @Override
     public boolean isEffectful() {
        return false;
     }
-
-    @Override
-    public void collectEffects(THashSet<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) {
index 23733bac61165c31e178d2e960af9dcc92e38d3d..73e38397da334145d852cd26fdc41d2f447c773e 100644 (file)
@@ -9,18 +9,12 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
 import org.simantics.scl.compiler.types.TVar;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ELambdaType extends Expression {
     public TVar[] parameters;
     public Expression value;
@@ -31,31 +25,16 @@ public class ELambdaType extends Expression {
         this.value = value;
     }
 
-       public void collectRefs(TObjectIntHashMap<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);
@@ -93,16 +72,6 @@ public class ELambdaType extends Expression {
         throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + ".");
     }
     
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        value = value.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -115,11 +84,6 @@ public class ELambdaType extends Expression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 2b9e8e2c0d9cc71a71f59ff3f37d798f199a5167..23c5b0be282d7fbd4a0a840cd00dd6b43fb4cce5 100644 (file)
@@ -14,7 +14,6 @@ import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
 import org.simantics.scl.compiler.internal.codegen.writer.RecursiveDefinitionWriter;
 import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
@@ -22,9 +21,11 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
+/**
+ * Generated maily from EPreLet
+ */
 public class ELet extends Expression {
     public Assignment[] assignments;
     public Expression in;
@@ -34,21 +35,6 @@ public class ELet extends Expression {
         this.assignments = assignments;
         this.in = in;
     }
-
-    @Override
-    public void collectRefs(final TObjectIntHashMap<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 {
@@ -123,15 +109,6 @@ public class ELet extends Expression {
         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.");
@@ -209,23 +186,6 @@ public class ELet extends Expression {
         in = in.checkIgnoredType(context);
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        in = in.decorate(decorator);
-        for(Assignment assignment : assignments)
-            assignment.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        for(Assignment assignment : assignments) {
-            assignment.pattern.collectEffects(effects);
-            assignment.value.collectEffects(effects);
-        }
-        in.collectEffects(effects);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -241,13 +201,6 @@ public class ELet extends Expression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Assignment assignment : assignments)
-            assignment.forVariables(procedure);
-        in.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 860bc7f8cda677281df58b13baa01f18d8d96ebe..78f7ce115c24b6b22eb06df747cb2ca7890df050 100644 (file)
@@ -6,15 +6,10 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.list.CompiledQualifier;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EListComprehension extends SimplifiableExpression {
 
     public Expression head;
@@ -31,20 +26,6 @@ public class EListComprehension extends SimplifiableExpression {
         this.head = head;
         this.qualifier = qualifier;
     }
-
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -65,12 +46,6 @@ public class EListComprehension extends SimplifiableExpression {
         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);
@@ -101,19 +76,6 @@ public class EListComprehension extends SimplifiableExpression {
         return this;
     }
 
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        head = head.decorate(decorator);
-        qualifier.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        head.collectEffects(effects);
-        qualifier.collectEffects(effects);
-    }
-
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -127,12 +89,6 @@ public class EListComprehension extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        head.forVariables(procedure);
-        qualifier.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index b1075a949af456d30caf21c2e95610d9f6456729..0f9ae5a15327da2fe4329c7760c8ebb234b5f22f 100644 (file)
@@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.java.Builtins;
 import org.simantics.scl.compiler.elaboration.java.ListConstructor;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.interpreted.IListLiteral;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -16,13 +15,9 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EListLiteral extends SimplifiableExpression {
 
-    Expression[] components;
+    public Expression[] components;
     Type componentType;
 
     public EListLiteral(Expression[] components) {
@@ -38,26 +33,6 @@ public class EListLiteral extends SimplifiableExpression {
         return components;
     }
     
-    @Override
-    public void collectRefs(TObjectIntHashMap<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);
@@ -114,19 +89,6 @@ public class EListLiteral extends SimplifiableExpression {
         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) {
@@ -148,12 +110,6 @@ public class EListLiteral extends SimplifiableExpression {
             componentExpressions[i] = components[i].toIExpression(target);
         return new IListLiteral(componentExpressions);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Expression component : components)
-            component.forVariables(procedure);
-    }
     
     @Override
     public Expression replace(ReplaceContext context) {
index b11c0d66746ffd328d095cc0ae763de7fbc701d9..bef28f20ff298a75b65f594cf4bbea08446017d7 100644 (file)
@@ -1,6 +1,8 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
 
 import org.simantics.scl.compiler.compilation.CompilationContext;
 import org.simantics.scl.compiler.constants.Constant;
@@ -11,18 +13,12 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IConstant;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ELiteral extends Expression {
     Constant value;
     
@@ -39,34 +35,26 @@ public class ELiteral extends Expression {
     public Constant getValue() {
         return value;
     }
-
-       public void collectRefs(TObjectIntHashMap<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;
@@ -92,10 +80,6 @@ public class ELiteral extends Expression {
         return new ELiteral(value);
     }
     
-    @Override
-    public void removeFreeVariables(THashSet<Variable> vars) {     
-    }
-    
     @Override
     public IExpression toIExpression(ExpressionInterpretationContext target) {
         return new IConstant(value.realizeValue(target.localClassBuilder));
@@ -105,15 +89,6 @@ public class ELiteral extends Expression {
     public Expression inferType(TypingContext context) {
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -125,10 +100,6 @@ public class ELiteral extends Expression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-    }
     
     @Override
     public boolean isPattern(int arity) {
index eef72f9de4f192f4ca44725a519024fb3add2bda..279815ecfd1b19227483a7b363bc6e137af63303 100644 (file)
@@ -13,15 +13,10 @@ import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
 import org.simantics.scl.compiler.internal.elaboration.matching.PatternMatchingCompiler;
 import org.simantics.scl.compiler.internal.elaboration.matching.Row;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EMatch extends Expression {
 
     public Expression[] scrutinee;
@@ -42,51 +37,27 @@ public class EMatch extends Expression {
         this.cases = cases;
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -163,26 +134,6 @@ public class EMatch extends Expression {
         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) {
@@ -196,14 +147,6 @@ public class EMatch extends Expression {
     public Case[] getCases() {
         return cases;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Expression s : scrutinee)
-            s.forVariables(procedure);
-        for(Case case_ : cases)
-            case_.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index bd03b30b9799a750c7f8a5f4b8b517fa104d7e46..feecc905c372a50ba64478db7adf2a67c446b0d2 100644 (file)
@@ -2,7 +2,6 @@ package org.simantics.scl.compiler.elaboration.expressions;
 
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 
 public class EPlaceholder extends DecoratingExpression {
     public EPlaceholder(long loc, Expression expression) {
@@ -33,9 +32,4 @@ public class EPlaceholder extends DecoratingExpression {
     public Expression resolveAsPattern(TranslationContext context) {
         return expression.resolveAsPattern(context);
     }
-    
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return expression.decorate(decorator);
-    }
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java
new file mode 100644 (file)
index 0000000..318a407
--- /dev/null
@@ -0,0 +1,20 @@
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRQueryTranslationMode;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+
+public class EPreCHRSelect extends ASTExpression {
+    CHRAstQuery query;
+    Expression expression;
+    
+    public EPreCHRSelect(CHRAstQuery query, Expression expression) {
+        this.query = query;
+        this.expression = expression;
+    }
+
+    @Override
+    public Expression resolve(TranslationContext context) {
+        return new ECHRSelect(expression, query.translate(context, CHRQueryTranslationMode.QUERY_HEAD)).resolve(context);
+    }
+}
index 035a2cadca6a02413575095ccd83112662961117..1578928aae032cb3a9386415e4b6a3b1f8368292 100644 (file)
@@ -13,10 +13,13 @@ import org.simantics.scl.compiler.errors.Locations;
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.procedure.TObjectObjectProcedure;
 
+/**
+ * Generated mainly from EBlock
+ */
 public class EPreLet extends ASTExpression {
 
-    List<LetStatement> assignments;
-    Expression in;
+    public List<LetStatement> assignments;
+    public Expression in;
     
     public EPreLet(List<LetStatement> assignments, Expression in) {
         this.assignments = assignments;
index 41880a0224bd2fb960f9acd7cc3f05bf03c0c093..c287f3ba1a26e73b66f8a84390cbee35cc8c1ef3 100644 (file)
@@ -10,8 +10,8 @@ import gnu.trove.map.hash.THashMap;
 
 public class EPreRuleset extends ASTExpression {
 
-    RuleStatement[] statements;
-    Expression in;
+    public RuleStatement[] statements;
+    public Expression in;
     
     public EPreRuleset(RuleStatement[] statements, Expression in) {
         this.statements = statements;
index 2f85269ac30c2b8d0613a455e2e56d71c284af80..90cc94bef87437deeb4869dfb87bd7781838690f 100644 (file)
@@ -11,33 +11,18 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ERealLiteral extends SimplifiableExpression {
     public String value;
-    EVariable constraint;
+    public EVariable constraint;
 
     public ERealLiteral(String value) {
         this.value = value;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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)));
@@ -74,10 +59,6 @@ public class ERealLiteral extends SimplifiableExpression {
     protected void updateType() throws MatchException {
         throw new InternalCompilerError("TODO");
     }
-    
-    @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
-    }
 
     @Override
     public Expression simplify(SimplificationContext context) {
@@ -108,15 +89,6 @@ public class ERealLiteral extends SimplifiableExpression {
         return copy;
     }
     
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {     
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -134,12 +106,6 @@ public class ERealLiteral extends SimplifiableExpression {
     public String getValue() {
         return value;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        if(constraint != null)
-            constraint.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index e784813d69fec37c9793ccae98a5ccd38fcc2756..9663a2a724bfc7f4184e3d870d6340b98c80c125 100644 (file)
@@ -32,7 +32,6 @@ import org.simantics.scl.compiler.elaboration.query.compilation.DerivateExceptio
 import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.elaboration.utils.ForcedClosure;
 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
@@ -44,13 +43,12 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import gnu.trove.impl.Constants;
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class ERuleset extends SimplifiableExpression {
     LocalRelation[] relations;
-    DatalogRule[] rules;
-    Expression in;
+    public DatalogRule[] rules;
+    public Expression in;
     
     public ERuleset(LocalRelation[] relations, DatalogRule[] rules, Expression in) {
         this.relations = relations;
@@ -95,12 +93,6 @@ public class ERuleset extends SimplifiableExpression {
             visitor.visit(this);
             return b.toString();
         }
-
-        public void forVariables(VariableProcedure procedure) {
-            for(Expression headParameter : headParameters)
-                headParameter.forVariables(procedure);
-            body.forVariables(procedure);
-        }
     }
     
     private void checkRuleTypes(TypingContext context) {
@@ -137,50 +129,6 @@ public class ERuleset extends SimplifiableExpression {
         return compile(context);
     }
     
-    @Override
-    public void collectFreeVariables(THashSet<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();
@@ -406,13 +354,6 @@ public class ERuleset extends SimplifiableExpression {
     public Expression getIn() {
         return in;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(DatalogRule rule : rules)
-            rule.forVariables(procedure);
-        in.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 7316fe307798a2d1467d013e21d9a7088dc888ac..e7014a8657fb091d011ec0432626b55c73c606da 100644 (file)
@@ -20,25 +20,20 @@ import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilation
 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationMode;
 import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.parser.SCLTerminals;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ESelect extends SimplifiableExpression {
 
     private final Type ARRAY_LIST = Types.con("ArrayList", "T"); 
     
     int selectVariant;
-    Expression expression;
-    Query query;
-    Variable[] variables;
+    public Expression expression;
+    public Query query;
+    public Variable[] variables;
     
     public ESelect(int selectVariant, Expression expression, Query query) {
         this.selectVariant = selectVariant;
@@ -46,25 +41,6 @@ public class ESelect extends SimplifiableExpression {
         this.query = query;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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 
@@ -141,14 +117,6 @@ public class ESelect extends SimplifiableExpression {
         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();
@@ -157,11 +125,6 @@ public class ESelect extends SimplifiableExpression {
         variables = context.popExistentialFrame();
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        return decorator.decorate(this);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -176,12 +139,6 @@ public class ESelect extends SimplifiableExpression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        expression.forVariables(procedure);
-        query.forVariables(procedure);
-    }
     
     @Override
     public Expression simplify(SimplificationContext context) {
index 2e5d4c364c743ab24345141e8752a5227e11f990..833e3e9e345d427e6037179e7f2b3bd1ef6469ec 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
+import java.util.Set;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.compilation.CompilationContext;
@@ -11,7 +12,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.interpreted.ILambda;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -23,10 +23,6 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.MultiFunction;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ESimpleLambda extends Expression {
     public Variable parameter;
     public Expression value;
@@ -56,36 +52,20 @@ public class ESimpleLambda extends Expression {
         this.effect = effect;
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -148,7 +128,7 @@ public class ESimpleLambda extends Expression {
         
         // 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;
@@ -198,22 +178,11 @@ public class ESimpleLambda extends Expression {
         return this;
     }
 
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        if(decorator.decorateSubstructure(this))
-            value = value.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
     @Override
     public boolean isEffectful() {
        return false;
     }
     
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -234,11 +203,6 @@ public class ESimpleLambda extends Expression {
     public Variable getParameter() {
         return parameter;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index e8fd9cf940b1b3f41dfa34cfc6cf800de3c887e9..aedb05d4b118906355728558f6598a3ee3f3641d 100644 (file)
@@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.interpreted.ILet;
 import org.simantics.scl.compiler.internal.interpreted.ISeq;
@@ -16,14 +15,10 @@ import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ESimpleLet extends Expression {
-    Variable variable; // may be null
-    Expression value;
-    Expression in;
+    public Variable variable; // may be null
+    public Expression value;
+    public Expression in;
     
     public ESimpleLet(Variable variable, Expression value, Expression in) {
         if(value == null)
@@ -46,36 +41,17 @@ public class ESimpleLet extends Expression {
         this.in = in;
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -175,19 +151,6 @@ public class ESimpleLet extends Expression {
         in = in.checkIgnoredType(context);
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        value = value.decorate(decorator);
-        in = in.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        value.collectEffects(effects);
-        in.collectEffects(effects);
-    }
     
     @Override
     public void accept(ExpressionVisitor visitor) {
@@ -206,12 +169,6 @@ public class ESimpleLet extends Expression {
         return in;
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-        in.forVariables(procedure);
-    }
-    
     @Override
     public Expression accept(ExpressionTransformer transformer) {
         return transformer.transform(this);
index 65b3f9b2f74b4e971808d6fe93c6384dfa437f7e..b96907ea3b9e4b3b69907f0cd53b766e6d8d07e2 100644 (file)
@@ -10,16 +10,10 @@ import org.simantics.scl.compiler.elaboration.query.Query;
 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.elaboration.transformations.TransformationBuilder;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ETransformation extends SimplifiableExpression {
     public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object();
     
@@ -31,32 +25,10 @@ public class ETransformation extends SimplifiableExpression {
         this.seed = seed;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -102,26 +74,10 @@ public class ETransformation extends SimplifiableExpression {
         }
     }
 
-    @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) {
index 654b4ef1f47555395924b0ac3f7db94a22417cbc..713342ed568cedd6b1e747743a394d967158d64d 100644 (file)
@@ -4,17 +4,12 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ETypeAnnotation extends SimplifiableExpression {
-    Expression value;
+    public Expression value;
     Type type;
     TypeAst typeAst;
         
@@ -29,24 +24,9 @@ public class ETypeAnnotation extends SimplifiableExpression {
         this.type = type;
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -72,17 +52,6 @@ public class ETypeAnnotation extends SimplifiableExpression {
     public Expression inferType(TypingContext context) {
         return value.checkType(context, type);
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        value = value.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        value.collectEffects(effects);
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -100,11 +69,6 @@ public class ETypeAnnotation extends SimplifiableExpression {
     public Expression getValue() {
         return value;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-    }
     
     @Override
     public Expression accept(ExpressionTransformer transformer) {
index 5311de2f17b4dcc7c9edf2c5ed68e0f2346c0593..7fe0e0a92d3220ceaf604c24715d9a48a0865044 100644 (file)
@@ -1,6 +1,8 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.compilation.CompilationContext;
@@ -11,7 +13,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.interpreted.IVariable;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -21,14 +22,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EVariable extends Expression {
     public static final EVariable[] EMPTY_ARRAY = new EVariable[0];
     
-    Variable variable;
+    public Variable variable;
     
     public EVariable(Variable variable) {
         this.variable = variable;
@@ -47,34 +44,26 @@ public class EVariable extends Expression {
         this.variable = variable;
     }
 
-       public void collectRefs(TObjectIntHashMap<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
@@ -96,11 +85,6 @@ public class EVariable extends Expression {
             ArrayList<Expression> parameters) {
     }
     
-    @Override
-    public void removeFreeVariables(THashSet<Variable> vars) {
-        vars.remove(variable);
-    }
-    
     @Override
     public Expression resolveAsPattern(TranslationContext context) {
         return this;
@@ -162,20 +146,11 @@ public class EVariable extends Expression {
             return context.subsume(this, requiredType);
     }
     
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {     
-        return decorator.decorate(this);
-    }
-    
     @Override
     public boolean isEffectful() {
        return false;
     }
     
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION)
@@ -186,12 +161,6 @@ public class EVariable extends Expression {
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        if(variable != null)
-            procedure.execute(location, variable);
-    }
     
     @Override
     public boolean isPattern(int arity) {
index a08ed3923570719faccb76eb06690d8d1dec24a7..4957f7c856360ac1b19fc15a5fff5bdc1bd24954 100644 (file)
@@ -8,16 +8,10 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.MultiFunction;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EViewPattern extends Expression {
     public Expression expression;
     public Expression pattern;
@@ -26,24 +20,6 @@ public class EViewPattern extends Expression {
         this.expression = expression;
         this.pattern = pattern;
     }
-
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -73,17 +49,6 @@ public class EViewPattern extends Expression {
         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?");
@@ -106,17 +71,6 @@ public class EViewPattern extends Expression {
         }
     }
 
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        expression = expression.decorate(decorator);
-        return this;
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        expression.collectEffects(effects);
-    }
-
     @Override
     public void accept(ExpressionVisitor visitor) {
         visitor.visit(this);
index bf47759de8569cc5596664e0cb1f94edfb5d5deb..df6d56888d22013fe9ff38a836ace4ecc188d836 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
@@ -11,22 +10,17 @@ import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilation
 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationMode;
 import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class EWhen extends SimplifiableExpression {
 
     public Query query;
     public Expression action;
-    Variable[] variables;
+    public Variable[] variables;
     
     public EWhen(Query query, Expression action) {
         this.query = query;
@@ -44,25 +38,6 @@ public class EWhen extends SimplifiableExpression {
         this.variables = variables;
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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);
@@ -97,14 +72,6 @@ public class EWhen extends SimplifiableExpression {
         }
     }
 
-    @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();
@@ -113,11 +80,6 @@ public class EWhen extends SimplifiableExpression {
         variables = context.popExistentialFrame();
         return this;
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {     
-        return decorator.decorate(this);
-    }
     
     @Override
     public Expression replace(ReplaceContext context) {
@@ -155,12 +117,6 @@ public class EWhen extends SimplifiableExpression {
     public Expression getAction() {
         return action;
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        query.forVariables(procedure);
-        action.forVariables(procedure);
-    }
     
     @Override
     public Expression simplify(SimplificationContext context) {
index 2b75f61cd0c236a2d37a5f7dae20e26224281362..3a2f845fe88191cb594022c5e0c49f60197b1db5 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
+import java.util.Set;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.common.precedence.Precedence;
@@ -14,12 +15,17 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectEffectsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectFreeVariablesVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectVarsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor;
 import org.simantics.scl.compiler.elaboration.query.QAtom;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
 import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -34,7 +40,6 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Typed;
 
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public abstract class Expression extends Symbol implements Typed {
@@ -56,10 +61,10 @@ public abstract class Expression extends Symbol implements Typed {
             try {
                 updateType();
             } catch (MatchException e) {
-                throw new InternalCompilerError(e);
+                throw new InternalCompilerError(location, e);
             }
             if(type == null)
-                throw new InternalCompilerError(getClass().getSimpleName() + 
+                throw new InternalCompilerError(location, getClass().getSimpleName() + 
                         ".updateType couldn't compute its type.");
         }
         return type;
@@ -103,23 +108,23 @@ public abstract class Expression extends Symbol implements Typed {
             expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT));
         return expression;
     }
-       
-       /**
-        * Checks the type of the expression against the given type. Adds type
-        * applications and lambdas if needed.
-        */
-       public final Expression checkType(TypingContext context, Type requiredType) {
-           //System.out.println("checkType: " + this + " :: " + requiredType);
-           if(!context.isInPattern()) {
-               requiredType = Types.canonical(requiredType);
-           if(requiredType instanceof TForAll) {
+
+    /**
+     * Checks the type of the expression against the given type. Adds type
+     * applications and lambdas if needed.
+     */
+    public final Expression checkType(TypingContext context, Type requiredType) {
+        //System.out.println("checkType: " + this + " :: " + requiredType);
+        if(!context.isInPattern()) {
+            requiredType = Types.canonical(requiredType);
+            if(requiredType instanceof TForAll) {
                 TForAll forAll = (TForAll)requiredType;
                 TVar var = forAll.var;
                 TVar newVar = Types.var(var.getKind());
                 requiredType = Types.canonical(forAll.type).replace(var, newVar);
                 return new ELambdaType(new TVar[] {newVar}, checkType(context, requiredType));
             }
-           while(requiredType instanceof TFun) {
+            while(requiredType instanceof TFun) {
                 TFun fun = (TFun)requiredType;
                 if(fun.domain instanceof TPred) { // No need to canonicalize
                     ArrayList<Variable> constraints = new ArrayList<Variable>(2);
@@ -143,7 +148,7 @@ public abstract class Expression extends Symbol implements Typed {
                     context.pushEffectUpperBound(location, fun.effect);
                     Expression expr = checkType(context, fun.range);
                     context.popEffectUpperBound();       
-                    
+
                     // Wrap
                     Variable var = new Variable("punit", Types.PUNIT);
                     return new ESimpleLambda(location, var, fun.effect, expr);
@@ -151,15 +156,23 @@ public abstract class Expression extends Symbol implements Typed {
                 else
                     break;
             }
-           }
-           return checkBasicType(context, requiredType); 
-       }
+        }
+        return checkBasicType(context, requiredType); 
+    }
 
-       public abstract void collectRefs(TObjectIntHashMap<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;
     }
 
@@ -204,8 +217,6 @@ public abstract class Expression extends Symbol implements Typed {
         return new ELambdaType(vars, this);
        }
     
-    public abstract void collectFreeVariables(THashSet<Variable> vars);
-    
     public Expression simplify(SimplificationContext context) {
         System.out.println("#############################");
         System.out.println(this);
@@ -231,32 +242,31 @@ public abstract class Expression extends Symbol implements Typed {
 
     public void getParameters(TranslationContext translationContext,
             ArrayList<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)
@@ -272,7 +282,7 @@ public abstract class Expression extends Symbol implements Typed {
     }
 
     public Expression replace(ReplaceContext context) {
-        throw new InternalCompilerError(getClass().getSimpleName() + " does not support replace.");
+        throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support replace.");
     }
     
     public static Expression[] replace(ReplaceContext context, Expression[] expressions) {
@@ -328,8 +338,6 @@ public abstract class Expression extends Symbol implements Typed {
     public Expression applyType(Type type) {
         return new EApplyType(location, this, type);
     }
-    
-    public abstract Expression decorate(ExpressionDecorator decorator);
 
        public boolean isEffectful() {
                return true;
@@ -343,12 +351,10 @@ public abstract class Expression extends Symbol implements Typed {
         return false;
     }
     
-    public abstract void collectEffects(THashSet<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);
index 4cf513c542647b1ccc3c8e1dd7cc8f020447c66d..c0c329ba315cca0f90d4a04cd30c74e51be3fb69 100644 (file)
@@ -9,6 +9,7 @@ public interface ExpressionTransformer {
     Expression transform(EBinary expression);
     Expression transform(EBind expression);
     Expression transform(EBlock expression);
+    Expression transform(ECHRSelect expression);
     Expression transform(ECHRRuleset expression);
     Expression transform(ECHRRulesetConstructor expression);
     Expression transform(EConstant expression);
index ad32098baadb7538d27c699c41d4dcf906df486a..7dbcf69e2af48a1a93976dff5eefeda2d074911e 100644 (file)
@@ -2,12 +2,14 @@ package org.simantics.scl.compiler.elaboration.expressions;
 
 
 public interface ExpressionVisitor {
+    void visit(EAmbiguous eAmbiguous);
     void visit(EApply expression);
     void visit(EApplyType expression);
     void visit(EAsPattern expression);
     void visit(EBinary expression);
     void visit(EBind expression);
     void visit(EBlock expression);
+    void visit(ECHRSelect expression);
     void visit(ECHRRuleset expression);
     void visit(ECHRRulesetConstructor expression);
     void visit(EConstant expression);
index 9791b068a5cc4791154da76a6c726f574e2627d1..f1e62b2f7d61930e3832c8d93bdab673c5546832 100644 (file)
@@ -2,7 +2,6 @@ package org.simantics.scl.compiler.elaboration.expressions;
 
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 
 public class GuardedExpression extends Symbol {
@@ -20,12 +19,6 @@ public class GuardedExpression extends Symbol {
                 value.replace(context));
     }
 
-    public void decorate(ExpressionDecorator decorator) {
-        for(int i=0;i<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;
@@ -34,10 +27,4 @@ public class GuardedExpression extends Symbol {
             value.setLocationDeep(loc);
         }
     }
-
-    public void forVariables(VariableProcedure procedure) {
-        for(Expression guard : guards)
-            guard.forVariables(procedure);
-        value.forVariables(procedure);
-    }
 }
index 23b2f62246478fe44758d65cc0bf8c5301031c00..48283a887a2dc883ded12c0632faf800d434b097 100644 (file)
@@ -10,15 +10,10 @@ import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
 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;
 
@@ -26,26 +21,6 @@ public class GuardedExpressionGroup extends Expression {
         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());
@@ -63,15 +38,6 @@ public class GuardedExpressionGroup extends Expression {
         //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) {
@@ -137,22 +103,6 @@ public class GuardedExpressionGroup extends Expression {
             newExpressions[i] = expressions[i].replace(context);
         return new GuardedExpressionGroup(newExpressions);            
     }
-
-    @Override
-    public Expression decorate(ExpressionDecorator decorator) {
-        for(GuardedExpression expression : expressions)
-            expression.decorate(decorator);
-        return decorator.decorate(this);
-    }
-
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        for(GuardedExpression ge : expressions) {
-            for(Expression guard : ge.guards)
-                guard.collectEffects(effects);
-            ge.value.collectEffects(effects);
-        }
-    }
     
     @Override
     public void setLocationDeep(long loc) {
@@ -168,12 +118,6 @@ public class GuardedExpressionGroup extends Expression {
         visitor.visit(this);
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(GuardedExpression expression : expressions)
-            expression.forVariables(procedure);
-    }
-
     @Override
     public Expression accept(ExpressionTransformer transformer) {
         return transformer.transform(this);
index e3a1333c08de375b92397972273ea15ba2e6c10d..3df40521a6e061cb677b7b67d001b644c8fdbd96 100644 (file)
@@ -4,16 +4,9 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.Types;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ExpressionAccessor extends FieldAccessor {
     public Expression fieldName;
 
@@ -22,28 +15,6 @@ public class ExpressionAccessor extends FieldAccessor {
         this.fieldName = fieldName;
     }
     
-    @Override
-    public void collectFreeVariables(THashSet<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);
@@ -76,9 +47,4 @@ public class ExpressionAccessor extends FieldAccessor {
     public void accept(FieldAccessorVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        fieldName.forVariables(procedure);
-    }
 }
index ce56da39f4c827819f66ae673e581dbc35590ef8..de02aa695b38fec1405658a39a8c35437e575e0d 100644 (file)
@@ -4,15 +4,8 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public abstract class FieldAccessor extends Symbol {
     public char accessSeparator;
     
@@ -20,27 +13,13 @@ public abstract class FieldAccessor extends Symbol {
         this.accessSeparator = accessSeparator;
     }
 
-    public void collectRefs(TObjectIntHashMap<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();
@@ -52,6 +31,4 @@ public abstract class FieldAccessor extends Symbol {
     public abstract void setLocationDeep(long loc);
 
     public abstract void accept(FieldAccessorVisitor visitor);
-
-    public abstract void forVariables(VariableProcedure procedure);
 }
index 9cb37e58ff12c610207aad0a828a7dc2a8fabd60..920a816061e39a3344e6d9745b7762db7dfbe457 100644 (file)
@@ -3,7 +3,6 @@ package org.simantics.scl.compiler.elaboration.expressions.accessor;
 import org.simantics.scl.compiler.constants.StringConstant;
 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
 
 public class IdAccessor extends FieldAccessor {
@@ -34,8 +33,4 @@ public class IdAccessor extends FieldAccessor {
     public void accept(FieldAccessorVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-    }
 }
index d08a4383fa8816b11c641d3518586ec189b668b9..ac038d12c1877a876583c875672f84036116de46 100644 (file)
@@ -3,7 +3,6 @@ package org.simantics.scl.compiler.elaboration.expressions.accessor;
 import org.simantics.scl.compiler.constants.StringConstant;
 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
 
 public class StringAccessor extends FieldAccessor {
@@ -29,8 +28,4 @@ public class StringAccessor extends FieldAccessor {
     public void accept(FieldAccessorVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-    }
 }
index d58f9c360e79c072eeb2723b8216466913a4c8b5..0c41b513a6c502a13a4eb62d631c8f46a544fa6d 100644 (file)
@@ -1,17 +1,17 @@
 package org.simantics.scl.compiler.elaboration.expressions.block;
 
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
 import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
 import org.simantics.scl.compiler.errors.Locations;
 
 public class CHRStatement extends Statement {
 
-    public ListQualifier[] head;
-    public ListQualifier[] body;
+    public CHRAstQuery head;
+    public CHRAstQuery body;
 
-    public CHRStatement(ListQualifier[] head, ListQualifier[] body) {
+    public CHRStatement(CHRAstQuery head, CHRAstQuery body) {
         this.head = head;
         this.body = body;
     }
@@ -23,13 +23,8 @@ public class CHRStatement extends Statement {
 
     @Override
     public void setLocationDeep(long loc) {
-        if(location == Locations.NO_LOCATION) {
+        if(location == Locations.NO_LOCATION)
             location = loc;
-            for(ListQualifier lq : head)
-                lq.setLocationDeep(loc);
-            for(ListQualifier lq : body)
-                lq.setLocationDeep(loc);
-        }
     }
 
     @Override
index 89de0ebc399e05a9cd27f4d8cb1ca495f13c0100..cddcffc77bdedb7f95f9896c3f223f0a1d2b94e4 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;
 
+import java.util.Set;
+
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
@@ -7,14 +9,7 @@ import org.simantics.scl.compiler.elaboration.expressions.Case;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public class ListAssignment extends ListQualifier {
     public Expression pattern;
@@ -31,30 +26,12 @@ public class ListAssignment extends ListQualifier {
         pattern.checkTypeAsPattern(context, value.getType());
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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)
@@ -80,18 +57,6 @@ public class ListAssignment extends ListQualifier {
         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) {
@@ -106,11 +71,6 @@ public class ListAssignment extends ListQualifier {
         visitor.visit(this);
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-    }
-
     @Override
     public ListQualifier accept(ListQualifierTransformer transformer) {
         return transformer.transform(this);
index 7f480d8df889dbd7973ac160aab17f729482b70d..e0401e6dcc0cad39c9b822b21bee82ea411980e7 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;
 
+import java.util.Set;
+
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
@@ -7,18 +9,11 @@ import org.simantics.scl.compiler.elaboration.expressions.Case;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.TMetaVar;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ListGenerator extends ListQualifier {
     public Expression pattern;
     public Expression value;
@@ -35,30 +30,12 @@ public class ListGenerator extends ListQualifier {
         pattern.checkTypeAsPattern(context, componentType);
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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)
@@ -85,19 +62,7 @@ public class ListGenerator extends ListQualifier {
         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) {
@@ -112,11 +77,6 @@ public class ListGenerator extends ListQualifier {
         visitor.visit(this);
     }
     
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        value.forVariables(procedure);
-    }
-    
     @Override
     public ListQualifier accept(ListQualifierTransformer transformer) {
         return transformer.transform(this);
index fdd1592351e82de0b7d6681d5c9f1da1d7d8a972..e5e8ee9d47cdca494a9224a088519426fe684f81 100644 (file)
@@ -4,17 +4,9 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ListGuard extends ListQualifier {
     public Expression condition;
 
@@ -27,23 +19,6 @@ public class ListGuard extends ListQualifier {
         condition.checkType(context, Types.BOOLEAN);
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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(
@@ -53,19 +28,9 @@ public class ListGuard extends ListQualifier {
 
     @Override
     public void resolve(TranslationContext context) {
-        condition = condition.resolve(context);        
+        condition = condition.resolve(context);
     }
 
-    @Override
-    public void decorate(ExpressionDecorator decorator) {
-        condition = condition.decorate(decorator);
-    }
-    
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        condition.collectEffects(effects);
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -79,11 +44,6 @@ public class ListGuard extends ListQualifier {
         visitor.visit(this);
     }
     
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        condition.forVariables(procedure);
-    }
-    
     @Override
     public ListQualifier accept(ListQualifierTransformer transformer) {
         return transformer.transform(this);
index 67d20374e26cc6619266c53299de7dc6943dc8c9..69818ef01266e952632cca67a50c49af849c661c 100644 (file)
@@ -3,29 +3,18 @@ package org.simantics.scl.compiler.elaboration.expressions.list;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
-import org.simantics.scl.compiler.types.Type;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public abstract class ListQualifier extends Symbol {
 
     public abstract void checkType(TypingContext context);
-    public abstract void collectRefs(TObjectIntHashMap<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);
     
 }
index 16fc84f892582db8337ff6e271248efc8c4ab548..f1126121f3de197cc8bc6bb892987b487c7fdc64 100644 (file)
@@ -5,14 +5,7 @@ import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
-import org.simantics.scl.compiler.types.Type;
-
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 public class ListSeq extends ListQualifier {
     public ListQualifier a;
@@ -28,26 +21,6 @@ public class ListSeq extends ListQualifier {
         a.checkType(context);
         b.checkType(context);  
     }
-    
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -76,18 +49,6 @@ public class ListSeq extends ListQualifier {
         b.resolve(context);
     }
     
-    @Override
-    public void decorate(ExpressionDecorator decorator) {
-        a.decorate(decorator);
-        b.decorate(decorator);
-    }
-    
-    @Override
-    public void collectEffects(THashSet<Type> effects) {
-        a.collectEffects(effects);
-        b.collectEffects(effects);
-    }
-    
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -102,12 +63,6 @@ public class ListSeq extends ListQualifier {
         visitor.visit(this);
     }
     
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        a.forVariables(procedure);
-        b.forVariables(procedure);
-    }
-    
     @Override
     public ListQualifier accept(ListQualifierTransformer transformer) {
         return transformer.transform(this);
index f8f3c3dd9db0aabeada7612326b362bcf246e235..df1d1f2b0772802e8ebcae20e6a25029be1873be 100644 (file)
@@ -4,20 +4,13 @@ import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.TMetaVar;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class ListThen extends ListQualifier {
     public ListQualifier left;
     public Expression transformer;
@@ -49,32 +42,6 @@ public class ListThen extends ListQualifier {
         }
     }
 
-    @Override
-    public void collectRefs(TObjectIntHashMap<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);
@@ -100,22 +67,6 @@ public class ListThen extends ListQualifier {
             by = by.resolve(context);
     }
 
-    @Override
-    public void decorate(ExpressionDecorator decorator) {
-        transformer = transformer.decorate(decorator);
-        if(by != null)
-            by = by.decorate(decorator);
-        left.decorate(decorator);
-    }
-
-    @Override
-    public void collectEffects(THashSet<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) {
@@ -131,14 +82,6 @@ public class ListThen extends ListQualifier {
     public void accept(ListQualifierVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        left.forVariables(procedure);
-        transformer.forVariables(procedure);
-        if(by != null)
-            by.forVariables(procedure);
-    }
     
     @Override
     public ListQualifier accept(ListQualifierTransformer transformer) {
index 3f6da74cb9ffd9f7cf0daddd78f4dfe4bbc775ba..b1a05d70e2e42a6541d180bfe38d085d8dc9d319 100644 (file)
@@ -8,6 +8,7 @@ import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.expressions.Assignment;
 import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
@@ -16,6 +17,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EBind;
 import org.simantics.scl.compiler.elaboration.expressions.EBlock;
 import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
 import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
 import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
@@ -329,7 +331,12 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito
     public void visit(ESelect expression) {
         b.append("ESelect");
     }
-
+    
+    @Override
+    public void visit(ECHRSelect expression) {
+        b.append("ECHRSelect");
+    }
+    
     @Override
     public void visit(ESimpleLambda expression) {
         b.append('\\');
@@ -606,4 +613,9 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito
         }
         b.append('"');
     }
+
+    @Override
+    public void visit(EAmbiguous eAmbiguous) {
+        b.append("EAmbigious");
+    }
 }
index a26cd857b111af631ea267cbcbc813fcadc7d57b..af84130f8f6cb8d2310fcc27c40655c1f2c7d60a 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.elaboration.expressions.records;
 
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 
@@ -11,4 +12,8 @@ public class FieldAssignment extends Symbol {
         this.name = name;
         this.value = value;
     }
+
+    public FieldAssignment replace(ReplaceContext context) {
+        return new FieldAssignment(name, value == null ? null : value.replace(context));
+    }
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectEffectsVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectEffectsVisitor.java
new file mode 100644 (file)
index 0000000..10190d5
--- /dev/null
@@ -0,0 +1,71 @@
+package org.simantics.scl.compiler.elaboration.expressions.visitors;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
+import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
+import org.simantics.scl.compiler.elaboration.expressions.ELambda;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+import gnu.trove.set.hash.THashSet;
+
+public class CollectEffectsVisitor extends StandardExpressionVisitor {
+    public final THashSet<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()]));
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectFreeVariablesVisitor.java
new file mode 100644 (file)
index 0000000..04f6791
--- /dev/null
@@ -0,0 +1,184 @@
+package org.simantics.scl.compiler.elaboration.expressions.visitors;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.expressions.Assignment;
+import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EBind;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
+import org.simantics.scl.compiler.elaboration.expressions.ELet;
+import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;
+import org.simantics.scl.compiler.elaboration.expressions.ESelect;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EWhen;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
+import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
+import org.simantics.scl.compiler.elaboration.query.QExists;
+
+import gnu.trove.set.hash.THashSet;
+
+public class CollectFreeVariablesVisitor extends StandardExpressionVisitor {
+    private THashSet<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;
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectRefsVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectRefsVisitor.java
new file mode 100644 (file)
index 0000000..5445f08
--- /dev/null
@@ -0,0 +1,55 @@
+package org.simantics.scl.compiler.elaboration.expressions.visitors;
+
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
+import org.simantics.scl.compiler.elaboration.query.QAtom;
+import org.simantics.scl.compiler.elaboration.relations.CompositeRelation;
+import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class CollectRefsVisitor extends StandardExpressionVisitor {
+    private final TObjectIntHashMap<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);
+        }
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectVarsVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/CollectVarsVisitor.java
new file mode 100644 (file)
index 0000000..7c4bee0
--- /dev/null
@@ -0,0 +1,35 @@
+package org.simantics.scl.compiler.elaboration.expressions.visitors;
+
+import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class CollectVarsVisitor extends StandardExpressionVisitor {
+    private final TObjectIntHashMap<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);
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/ForVariablesUsesVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/visitors/ForVariablesUsesVisitor.java
new file mode 100644 (file)
index 0000000..57befad
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.scl.compiler.elaboration.expressions.visitors;
+
+import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
+
+public class ForVariablesUsesVisitor extends StandardExpressionVisitor {
+    VariableProcedure procedure;
+    
+    public ForVariablesUsesVisitor(VariableProcedure procedure) {
+        this.procedure = procedure;
+    }
+    
+    @Override
+    public void visit(EVariable expression) {
+        if(expression.variable != null)
+            procedure.execute(expression.location, expression.variable);
+    }
+    @Override
+    public void visit(EAsPattern expression) {
+        expression.pattern.accept(this);
+        procedure.execute(expression.eVar.location, expression.var);
+    }
+}
@@ -1,12 +1,72 @@
-package org.simantics.scl.compiler.elaboration.expressions;
+package org.simantics.scl.compiler.elaboration.expressions.visitors;
 
 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstNegation;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQueryVisitor;
 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
 import org.simantics.scl.compiler.elaboration.equation.Equation;
 import org.simantics.scl.compiler.elaboration.equation.EquationVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.Assignment;
+import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
+import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EBinary;
+import org.simantics.scl.compiler.elaboration.expressions.EBinaryRightSide;
+import org.simantics.scl.compiler.elaboration.expressions.EBind;
+import org.simantics.scl.compiler.elaboration.expressions.EBlock;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRulesetConstructor;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRSelect;
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;
+import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
+import org.simantics.scl.compiler.elaboration.expressions.EEquations;
+import org.simantics.scl.compiler.elaboration.expressions.EError;
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
+import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
+import org.simantics.scl.compiler.elaboration.expressions.EGetConstraint;
+import org.simantics.scl.compiler.elaboration.expressions.EIf;
+import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ELambda;
+import org.simantics.scl.compiler.elaboration.expressions.ELambdaType;
+import org.simantics.scl.compiler.elaboration.expressions.ELet;
+import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
+import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.EMatch;
+import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
+import org.simantics.scl.compiler.elaboration.expressions.EPreLet;
+import org.simantics.scl.compiler.elaboration.expressions.EPreRuleset;
+import org.simantics.scl.compiler.elaboration.expressions.ERange;
+import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ERecord;
+import org.simantics.scl.compiler.elaboration.expressions.ERuleset;
+import org.simantics.scl.compiler.elaboration.expressions.ESelect;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLet;
+import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
+import org.simantics.scl.compiler.elaboration.expressions.ETypeAnnotation;
+import org.simantics.scl.compiler.elaboration.expressions.EVar;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
+import org.simantics.scl.compiler.elaboration.expressions.EWhen;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.ExpressionTransformer;
+import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
+import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
+import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
 import org.simantics.scl.compiler.elaboration.expressions.accessor.ExpressionAccessor;
 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
@@ -40,10 +100,12 @@ import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
 
 public class StandardExpressionTransformer implements
 ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor,
-EquationVisitor {
+EquationVisitor, CHRAstQueryVisitor {
 
     @Override
     public Expression transform(EAmbiguous expression) {
+        if(expression.resolvedExpression != null)
+            expression.resolvedExpression = expression.resolvedExpression.accept(this);
         return expression;
     }
 
@@ -125,14 +187,16 @@ EquationVisitor {
         statement.value = statement.value.accept(this);
     }
     
+    public void transform(CHRQuery query) {
+        for(CHRLiteral lit : query.literals)
+            for(int i=0;i<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);
         }
     }
     
@@ -143,6 +207,13 @@ EquationVisitor {
         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);
@@ -520,10 +591,36 @@ EquationVisitor {
 
     @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);
     }
 
 }
@@ -1,13 +1,71 @@
-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;
@@ -23,7 +81,6 @@ import org.simantics.scl.compiler.elaboration.expressions.block.StatementVisitor
 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;
@@ -42,7 +99,7 @@ import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
 
 public class StandardExpressionVisitor implements 
 ExpressionVisitor, QueryVisitor, FieldAccessorVisitor, ListQualifierVisitor,
-EquationVisitor, StatementVisitor {
+EquationVisitor, StatementVisitor, CHRAstQueryVisitor {
 
     @Override
     public void visit(EApply expression) {
@@ -66,6 +123,8 @@ EquationVisitor, StatementVisitor {
         expression.pattern.accept(this);
         expression.value.accept(this);
         expression.in.accept(this);
+        if(expression.monadEvidence != null)
+            visit(expression.monadEvidence);
     }
 
     @Override
@@ -138,6 +197,7 @@ EquationVisitor, StatementVisitor {
     public void visit(ELet expression) {
         for(Assignment assignment : expression.assignments)
             visit(assignment);
+        expression.in.accept(this);
     }
 
     public void visit(Assignment assignment) {
@@ -198,6 +258,12 @@ EquationVisitor, StatementVisitor {
         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) {
@@ -356,15 +422,26 @@ EquationVisitor, StatementVisitor {
             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
@@ -448,9 +525,41 @@ EquationVisitor, StatementVisitor {
     
     @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);
     }
 }
index 334cb4560cc488e2ae2a9101dc245f64c0f10c04..6df643ea38e17f1e51f2689d0288b7f379d02718 100644 (file)
@@ -9,7 +9,6 @@ import org.simantics.scl.compiler.common.precedence.Associativity;
 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;
@@ -53,10 +52,10 @@ import org.simantics.scl.runtime.profiling.BranchPoint;
 
 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;
@@ -178,6 +177,10 @@ public class Builtins extends ConcreteModule {
                 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, 
@@ -363,4 +366,8 @@ public class Builtins extends ConcreteModule {
         return documentation;
     }
 
+       public static void flush() {
+               INSTANCE = new Builtins();
+       }
+
 }
index cf927825e176df8bbe2e4f4c87063e9d17adf5ee..8144a6c8b66a0f1e0b85f65bb37609c30e0d08dc 100644 (file)
@@ -65,5 +65,15 @@ public class CheckRelation extends AbstractRelation {
     public String toString() {
         return "Check";
     }
+
+    @Override
+    public Type getEnforceEffect() {
+        return Types.NO_EFFECTS;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.NO_EFFECTS;
+    }
     
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/DynamicConstructor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/DynamicConstructor.java
new file mode 100644 (file)
index 0000000..078e7f6
--- /dev/null
@@ -0,0 +1,51 @@
+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));
+    }
+}
index 7116ed9f1c757f7f8154f2bda97c1ae93e08872f..316506a5c94058de1e1856079e494f6731c3d026 100644 (file)
@@ -75,5 +75,14 @@ public class EqRelation extends AbstractRelation {
     public String toString() {
         return "=";
     }
-    
+
+    @Override
+    public Type getEnforceEffect() {
+        return Types.NO_EFFECTS;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.NO_EFFECTS;
+    }
 }
index 10f36193e9c27773b7a5cd0d46ddbb9dbaa4f37e..5537f71ab2645487c802c78dab8f5c1ff4e0b67b 100644 (file)
@@ -70,5 +70,14 @@ public class ExecuteRelation extends AbstractRelation {
     public String toString() {
         return "Execute";
     }
-    
+
+    @Override
+    public Type getEnforceEffect() {
+        return Types.NO_EFFECTS;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.NO_EFFECTS;
+    }
 }
index e412a11689f708e3dd27679a82d468173743a9d8..aeec9a35be73a7485597060e07071c874db3d470 100644 (file)
@@ -23,7 +23,7 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 
 public class JavaModule extends ConcreteModule {
 
-    public static final JavaModule INSTANCE = new JavaModule();
+    public static JavaModule INSTANCE = new JavaModule();
     
     public static final String MODULE_NAME = "JavaBuiltin";
 
@@ -147,6 +147,9 @@ public class JavaModule extends ConcreteModule {
             result = new EApplyType(result, var);
         return result;
     }
-    
+
+    public static void flush() {
+       INSTANCE = new JavaModule();
+    }
 }
 
index a022d1b37e7488d58181b4aa0542081cc04ac328..f43b62b075240b78c9c771c270234290a45f5357 100644 (file)
@@ -80,4 +80,14 @@ public class MemberRelation extends AbstractRelation {
     public String toString() {
         return "<-";
     }
+
+    @Override
+    public Type getEnforceEffect() {
+        return Types.NO_EFFECTS;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.NO_EFFECTS;
+    }
 }
index 434f2da6e13ff7b8249d6373aa7595c87eb7aca6..b68657a1cedd6c9a0cda0a883ee5fdf2ca94b417 100644 (file)
@@ -261,6 +261,16 @@ public class MinigraphModule extends ConcreteModule {
             public String toString() {
                 return "Statement";
             }
+            
+            @Override
+            public Type getEnforceEffect() {
+                return GRAPH;
+            }
+            
+            @Override
+            public Type getQueryEffect() {
+                return GRAPH;
+            }
         });
         addEntityType("Resource", new SCLEntityType() {
             @Override
index ef30deb435ca36318350ccfb8c5fdceb06577f60..89568cb57fd5f2201f40484a77a3d1b07d5c27cd 100644 (file)
@@ -80,4 +80,14 @@ public class OptionalRelation extends AbstractRelation {
     public String toString() {
         return "Optional";
     }
+
+    @Override
+    public Type getEnforceEffect() {
+        return Types.NO_EFFECTS;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.NO_EFFECTS;
+    }
 }
index 53eb780fdaf2174393a8235d15a755aa8363d5be..a3ca43d362ba09e28493c6d55326a4755c9b1589 100644 (file)
@@ -7,27 +7,16 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
 import org.simantics.scl.compiler.elaboration.expressions.EVar;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.query.pre.QPreExists;
 import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
 import org.simantics.scl.compiler.errors.Locations;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public abstract class QAbstractCombiner extends Query {
     public Query[] queries;
     
     public QAbstractCombiner(Query[] queries) {
         this.queries = queries;
     }
-
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        for(Query query : queries)
-            query.collectFreeVariables(vars);
-    }
     
     @Override
     public Query resolve(TranslationContext context) {
@@ -75,18 +64,6 @@ public abstract class QAbstractCombiner extends Query {
             query.checkType(context);
     }
     
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -95,10 +72,4 @@ public abstract class QAbstractCombiner extends Query {
                 query.setLocationDeep(loc);
         }
     }
-    
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Query query : queries)
-            query.forVariables(procedure);
-    }
 }
index e04246e40e7d4224837205d7622c404527bae0aa..d580f2bb04c0b5e00fbf5b7444ceaf50194938cf 100644 (file)
@@ -2,24 +2,14 @@ package org.simantics.scl.compiler.elaboration.query;
 
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.errors.Locations;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public abstract class QAbstractModifier extends Query {
     public Query query;
     
     public QAbstractModifier(Query query) {
         this.query = query;
     }
-
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        query.collectFreeVariables(vars);
-    }
     
     @Override
     public Query resolve(TranslationContext context) {
@@ -32,18 +22,6 @@ public abstract class QAbstractModifier extends Query {
         query.checkType(context);
     }
     
-    @Override
-    public void collectRefs(TObjectIntHashMap<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) {
@@ -51,9 +29,4 @@ public abstract class QAbstractModifier extends Query {
             query.setLocationDeep(loc);
         }
     }
-    
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        query.forVariables(procedure);
-    }
 }
index fd7dacb799b625984ccf280c1b4f96380701c950..5f13bfd7b385a7b15a559ee07e41161ad13b464c 100644 (file)
@@ -27,8 +27,6 @@ import org.simantics.scl.compiler.types.Types;
 
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.map.hash.TIntObjectHashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class QAtom extends Query {
@@ -47,12 +45,6 @@ public class QAtom extends Query {
         this.parameters = parameters;
     }
 
-    @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        for(Expression parameter : parameters)
-            parameter.collectFreeVariables(vars);
-    }
-
     @Override
     public void checkType(TypingContext context) {
         // Type parameters
@@ -129,7 +121,7 @@ public class QAtom extends Query {
                     }
                     else {
                         optionalVariableByParameter[i] = -1;
-                        parameter.forVariables(procedure);
+                        parameter.forVariableUses(procedure);
                     }
                 }
             }
@@ -147,34 +139,6 @@ public class QAtom extends Query {
         }
     }
 
-    private static void collectRefs(SCLRelation relation, TObjectIntHashMap<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;
@@ -250,12 +214,6 @@ public class QAtom extends Query {
         visitor.visit(this);
     }
 
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Expression parameter : parameters)
-            parameter.forVariables(procedure);
-    }
-
     @Override
     public void splitToPhases(TIntObjectHashMap<ArrayList<Query>> result) {
         int phase = relation.getPhase();
index 5356eccc2708987042bb174f215a2ab374782084..2f9c0c50705a7e0baf21cd367612a299ed499da9 100644 (file)
@@ -8,7 +8,6 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
 import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException;
 import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
@@ -18,10 +17,9 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
 import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
 
 public class QExists extends QAbstractModifier {
-    Variable[] variables;
+    public Variable[] variables;
     
     public QExists(Variable[] variables, Query query) {
         super(query);
@@ -32,13 +30,6 @@ public class QExists extends QAbstractModifier {
         this(variables.toArray(new Variable[variables.size()]), query);
     }
 
-    @Override
-    public void collectFreeVariables(THashSet<Variable> vars) {
-        super.collectFreeVariables(vars);
-        for(Variable variable : variables)
-            vars.remove(variable);
-    }
-
     @Override
     public void checkType(TypingContext context) {
         for(Variable var : variables)
@@ -92,13 +83,6 @@ public class QExists extends QAbstractModifier {
         visitor.visit(this);
     }
     
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Variable variable : variables)
-            procedure.execute(location, variable);
-        super.forVariables(procedure);
-    }
-    
     @Override
     public Query accept(QueryTransformer transformer) {
         return transformer.transform(this);
index 62ff9583ce97317519fe2074254f818b61cf6027..03bcec3e9b6f322f3b426829f30c7d814095a1d2 100644 (file)
@@ -4,17 +4,11 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
 import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.types.Types;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class QIf extends Query {
     public Expression condition;
     public Query thenQuery;
@@ -25,28 +19,7 @@ public class QIf extends Query {
         this.thenQuery = thenQuery;
         this.elseQuery = elseQuery;
     }
-
-    @Override
-    public void collectFreeVariables(THashSet<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);
@@ -82,13 +55,6 @@ public class QIf extends Query {
     public void accept(QueryVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        condition.forVariables(procedure);
-        elseQuery.forVariables(procedure);
-        thenQuery.forVariables(procedure);
-    }
     
     @Override
     public Query accept(QueryTransformer transformer) {
index ca9378c89f19da98d41b699e95ef88c75f497048..02061b79801d0fceadc61b6fe91176a9757fbc9d 100644 (file)
@@ -5,18 +5,12 @@ import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
-import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
 import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
 import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.types.Type;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 public class QMapping extends Query {
     public final MappingRelation mappingRelation;
     public final Expression[] parameters;
@@ -26,26 +20,6 @@ public class QMapping extends Query {
         this.parameters = parameters;
     }
 
-    @Override
-    public void collectFreeVariables(THashSet<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
@@ -82,12 +56,6 @@ public class QMapping extends Query {
     public void accept(QueryVisitor visitor) {
         visitor.visit(this);
     }
-
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        for(Expression parameter : parameters)
-            parameter.forVariables(procedure);
-    }
     
     @Override
     public Query accept(QueryTransformer transformer) {
index 0ac54e22ec29d72b8468bde640220c4676a4ed39..58f7807540188b6a81422e8be3a4d96fc238791c 100644 (file)
@@ -10,10 +10,13 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.EError;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
-import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionVisitor;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectVarsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor;
 import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
 import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException;
 import org.simantics.scl.compiler.elaboration.query.compilation.DynamicProgrammingOrdering;
@@ -29,15 +32,11 @@ import org.simantics.scl.compiler.internal.parsing.Symbol;
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.map.hash.TIntObjectHashMap;
 import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
 import gnu.trove.set.hash.TIntHashSet;
 
 public abstract class Query extends Symbol {
     public static final Query[] EMPTY_ARRAY = new Query[0];
     
-    public abstract void collectFreeVariables(THashSet<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) {
@@ -135,8 +134,6 @@ public abstract class Query extends Symbol {
         });
     }
     
-    public abstract void forVariables(VariableProcedure procedure);
-    
     public TIntObjectHashMap<ArrayList<Query>> splitToPhases() {
         TIntObjectHashMap<ArrayList<Query>> result = new TIntObjectHashMap<ArrayList<Query>>(2);
         splitToPhases(result);
@@ -156,4 +153,15 @@ public abstract class Query extends Symbol {
     }
     
     public abstract Query accept(QueryTransformer transformer);
+    
+    public void forVariables(VariableProcedure procedure) {
+        accept(new ForVariablesUsesVisitor(procedure));
+    }
+    public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+        accept(new CollectRefsVisitor(allRefs, refs));
+    }
+
+    public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
+        accept(new CollectVarsVisitor(allVars, vars));
+    }
 }
index ee96433d3e11e35c7e98370916de82f6b3c0d7f8..2f4d14baecfda0fa64c36b3646398066fb744aad 100644 (file)
@@ -6,17 +6,12 @@ import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
-import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.elaboration.query.QConjunction;
 import org.simantics.scl.compiler.elaboration.query.QExists;
 import org.simantics.scl.compiler.elaboration.query.Query;
 import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
 import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 /**
  * Query classes that may exist before resolving
  */
@@ -24,11 +19,6 @@ public abstract class PreQuery extends Query {
 
     public ArrayList<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) {
@@ -40,18 +30,6 @@ public abstract class PreQuery extends Query {
         throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support collectConstraints.");
     }
     
-    @Override
-    public void collectRefs(TObjectIntHashMap<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.");
@@ -71,9 +49,4 @@ public abstract class PreQuery extends Query {
             query = new QExists(extraVariables.toArray(new Variable[extraVariables.size()]), query);
         return query;
     }
-    
-    @Override
-    public void forVariables(VariableProcedure procedure) {
-        throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support forVariables.");
-    }
 }
index 96ace3b6433f0b3be367b81dbe194cd39ff0a171..bcdcb4e351a237e7efbd0dcca11deccad63db0ea 100644 (file)
@@ -160,4 +160,14 @@ public class ConcreteRelation extends Symbol implements SCLRelation {
             Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
         throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");
     }
+
+    @Override
+    public Type getEnforceEffect() {
+        return writingEffect;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return sections.get(0).effect; 
+    }
 }
index 3fbeef75525671c41daee45dbd80e8b9213015f2..0e0016df9f3f0a14daa79e5aef5eb1e8d334b1bb 100644 (file)
@@ -109,4 +109,14 @@ public class LocalRelation extends AbstractRelation {
     public String toString() {
         return name;
     }
+    
+    @Override
+    public Type getEnforceEffect() {
+        return Types.PROC;
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return Types.PROC;
+    }
 }
index e93ff6e8fe16a7b5eb1aeb5a45164a86302c0be2..58d69f4d9264a321de0597ec9b5b5c706780708d 100644 (file)
@@ -63,4 +63,6 @@ public interface SCLRelation {
             long location,
             Expression[] parameters,
             Expression[] typeConstraintEvidenceParameters);
+    Type getEnforceEffect();
+    Type getQueryEffect();
 }
index 42eb9530d3717401b427b78f7c951c99620f8675..03e3a7f27667e1fe915f28888e86ea62f531ff0b 100644 (file)
@@ -8,7 +8,6 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.let
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple;
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
 
-import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.common.names.Names;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
@@ -140,4 +139,14 @@ public class TransitiveClosureRelation extends AbstractRelation implements Compo
         return new SCLRelation[] { baseRelation };
     }
 
+    @Override
+    public Type getEnforceEffect() {
+        return baseRelation.getEnforceEffect();
+    }
+
+    @Override
+    public Type getQueryEffect() {
+        return baseRelation.getQueryEffect();
+    }
+
 }
index 3be214d2d6bd69f66aa4ae59347adeba2b5cb572..2ce0ced5bd5e46438a93a54b3c7651fab130cba9 100644 (file)
@@ -241,6 +241,8 @@ public class Environments {
             Namespace childNamespace = namespace.getNamespace(prefix.substring(0, p));
             if(childNamespace != null)
                 findValuesForPrefix(childNamespace, prefix.substring(p+1), proc);
+            else
+                namespace.findValuesForPrefix(prefix, AcceptAllNamespaceFilter.INSTANCE, proc);
         }
         else
             namespace.findValuesForPrefix(prefix, AcceptAllNamespaceFilter.INSTANCE, proc);
index 62d5d8c3de021defc1648d90c15f8ad55998440d..0e61a1644ef961bd99b9ae4a770eda46ffadf87e 100644 (file)
@@ -16,7 +16,7 @@ public class ErrorLog {
     
     public void log(CompilationError error) {
         errors.add(error);
-        if(error.severity == ErrorSeverity.ERROR)
+        if(error.severity != ErrorSeverity.WARNING)
                ++errorCount;
     }
     
index 9f65cb3e8662c739d36db66ba175fe8a6c511f58..101e0f9e5cdb04bbcd26f21aea7f3e9a3e33cb02 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.scl.compiler.errors;
 
 public enum ErrorSeverity {
-       ERROR,
-       WARNING
+    ERROR,
+    IMPORT_ERROR,
+    WARNING
 }
index 9ff56eda4cc45eb27dcf29b00c0f9789816215c8..341ba34a796b18ebdd7dbd0850e7649b1328f60f 100644 (file)
@@ -46,8 +46,8 @@ public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstant
             for(CHRConstraint constraint : ruleset.constraints)
                 if(constraint.nextContainerFieldName != null)
                     storeClassBuilder.addField(Opcodes.ACC_PUBLIC, constraint.nextContainerFieldName, CHRPriorityFactContainer);
-        if(ruleset.extensible)
-            storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE);
+        //if(ruleset.extensible)
+        //    storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE);
         
         // Constructors
 
@@ -106,13 +106,16 @@ public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstant
                     }
                 
                 // update context id
+                mb.loadLocal(importedStore);
                 mb.loadLocal(contextVar);
+                mb.invokeVirtual("org/simantics/scl/runtime/chr/CHRRuntimeRuleset", "register", TypeDesc.VOID, new TypeDesc[] {CHRContext});
+                /*mb.loadLocal(contextVar);
                 mb.loadLocal(contextVar);
                 mb.loadField(CHRContext_name, "currentId", FACT_ID_TYPE);
                 mb.loadLocal(importedStore);
                 mb.loadField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE);
                 mb.invokeStatic("java/lang/Math", "max", FACT_ID_TYPE, new TypeDesc[] {FACT_ID_TYPE, FACT_ID_TYPE});
-                mb.storeField(CHRContext_name, "currentId", FACT_ID_TYPE);
+                mb.storeField(CHRContext_name, "currentId", FACT_ID_TYPE);*/
                 
                 mb.returnVoid();
                 mb.finish();
@@ -137,8 +140,11 @@ public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstant
                 // store context id
                 mb.loadLocal(importedStore);
                 mb.loadLocal(contextVar);
+                mb.invokeVirtual("org/simantics/scl/runtime/chr/CHRRuntimeRuleset", "unregister", TypeDesc.VOID, new TypeDesc[] {CHRContext});
+                /*mb.loadLocal(importedStore);
+                mb.loadLocal(contextVar);
                 mb.loadField(CHRContext_name, "currentId", FACT_ID_TYPE);
-                mb.storeField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE);
+                mb.storeField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE);*/
                 
                 mb.returnVoid();
                 mb.finish();
index d9d79737f5222ab39e475a6385377eef49f8f0ce..210e3ded3243fc20755dd4553dd19bd309f0d0ba 100644 (file)
@@ -356,6 +356,8 @@ public class LetApply extends LetStatement implements ValRefBinder {
                
         SSABlock headBlock = getParent();
         SSAFunction thisFunction = headBlock.getParent();
+        if(thisFunction == function)
+            return;
                
         /*System.out.println("--- INLINING -------------------------------");
         System.out.println(thisFunction);
index 56b5c8e6767141bfae285180962016409a7ed975..52d19cc5474526386485205bc1cce5be35015af9 100644 (file)
@@ -4,6 +4,7 @@ import org.cojen.classfile.TypeDesc;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.constants.LocalVariableConstant;
 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
 import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont;
@@ -231,6 +232,9 @@ public class MethodBuilder extends MethodBuilderBase {
             if(!boundVar.generateOnFly)
                 return getLocalVariable(boundVar);
         }
+        else if(val instanceof LocalVariableConstant) {
+            return ((LocalVariableConstant)val).var;
+        }
         push(val, type);
         LocalVariable temp = createLocalVariable(null, getJavaTypeTranslator().toTypeDesc(type));
         storeLocal(temp);
index 12bf42e5bed980910034d3aa661938341a743247..62b2ec1aaf4bc9894d14d8dabb957c80b234853f 100644 (file)
@@ -17,6 +17,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
+import org.simantics.scl.compiler.elaboration.java.DynamicConstructor;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
 import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
@@ -94,7 +95,7 @@ public class PatternMatchingCompiler {
                 if(constructor_ instanceof EConstant) {
                     SCLValue constructor = ((EConstant)constructor_).getValue();
     
-                    ExpressionMatrix matrix = matrixMap.get(constructor.getName());
+                    ExpressionMatrix matrix = constructor.getValue() == DynamicConstructor.INSTANCE ? null : matrixMap.get(constructor.getName());
                     if(matrix == null) {
                         CodeWriter newW = w.createBlock(Types.getTypes(parameters));
                         branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation()));
index 8ca51b275f900a439d5b7a5025ab3d2e96444588..24a3bfb2edcc2e8208aefa4435974fec8b31af47 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
 import org.simantics.scl.compiler.elaboration.expressions.EViewPattern;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.java.DynamicConstructor;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
 import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
@@ -93,7 +94,7 @@ public class PatternMatchingCompiler2 {
                 if(constructor_ instanceof EConstant) {
                     SCLValue constructor = ((EConstant)constructor_).getValue();
     
-                    ExpressionMatrix matrix = matrixMap.get(constructor.getName());
+                    ExpressionMatrix matrix = constructor.getValue() == DynamicConstructor.INSTANCE ? null : matrixMap.get(constructor.getName());
                     if(matrix == null) {
                         CodeWriter newW = w.createBlock(Types.getTypes(parameters));
                         branches.add(new Branch((Constant)constructor.getValue(), newW.getContinuation()));
index 6f3ff3be93150e8685e05495f1104173dfd865f6..eed6d85552c62cf63f4b2028d84fd5990597b0dc 100644 (file)
@@ -46,7 +46,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EWhen;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpression;
 import org.simantics.scl.compiler.elaboration.expressions.GuardedExpressionGroup;
-import org.simantics.scl.compiler.elaboration.expressions.StandardExpressionTransformer;
 import org.simantics.scl.compiler.elaboration.expressions.block.BindStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
@@ -57,6 +56,7 @@ import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionTransformer;
 import org.simantics.scl.compiler.elaboration.query.QAlternative;
 import org.simantics.scl.compiler.elaboration.query.QAtom;
 import org.simantics.scl.compiler.elaboration.query.QConjunction;
index 6060315c4d3103f34933dc9e6fcee61ab2ea7233..50958221ca9e0ac063895ed5ba65573deb895c7b 100644 (file)
@@ -184,7 +184,7 @@ public class TransformationBuilder {
                 }
             };
             for(QMapping mapping : decomposed.targetMappings)
-                mapping.parameters[0].forVariables(check);
+                mapping.parameters[0].forVariableUses(check);
             sourceVariables = sourceVariableList.toArray(new Variable[sourceVariableList.size()]);
         }
         
@@ -220,7 +220,7 @@ public class TransformationBuilder {
             }
             else {
                 PatternAnalyzer analyzer = new PatternAnalyzer(variableSet, mappedVariableUseCount); 
-                expression.forVariables(analyzer);
+                expression.forVariableUses(analyzer);
 
                 if(analyzer.containsVariables)
                     semiopenMappings.add(mapping);
index 75b083f0c9fbadc3a138e77b0b8a7a65b613bed4..06da2356294d80dd89e3803e940c71bb37953a74 100644 (file)
@@ -186,7 +186,7 @@ public class UnifiableFactory {
         
         // 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) {
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/utils/ExpressionDecorator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/utils/ExpressionDecorator.java
deleted file mode 100644 (file)
index 77e47d1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.simantics.scl.compiler.internal.elaboration.utils;
-
-import org.simantics.scl.compiler.elaboration.expressions.Expression;
-
-public interface ExpressionDecorator {
-
-    Expression decorate(Expression expression);
-    boolean decorateSubstructure(Expression expression);
-    
-}
index f7ea1b263617cee6eae8dbc4e5dda34139e10e45..b7bb1924c680efc17326fc39fedd3b6d04bb17bd 100644 (file)
@@ -138,7 +138,7 @@ lexp
                                                                shift ESCAPED_SYMBOL, shift CHAR, shift LBRACE,
                                                                shift WHEN, shift ATTACHED_HASH,
                                                                shift SELECT, shift SELECT_FIRST, shift SELECT_DISTINCT,
-                                                               shift TRANSFORMATION, shift EQ
+                                                               shift TRANSFORMATION, shift EQ, shift CHR_SELECT
     ; 
 
 faexp
@@ -161,6 +161,8 @@ aexp
     | (DO | MDO) statements                                  # Do
     | (SELECT | SELECT_FIRST | SELECT_DISTINCT) 
       exp WHERE queryBlock                                   # Select
+    | CHR_SELECT 
+      exp WHERE verboseChrQuery                              # CHRSelect
     | ENFORCE queryBlock                                     # Enforce
     //| WHEN queryBlock SEMICOLON exp                          # When
     | var                                                    # Var
@@ -204,12 +206,19 @@ statement
     | INCLUDE ID aexp                                        # LocalInclude
     ;
 
+verboseChrQuery
+    = LBRACE chrQuery (SEMICOLON chrQuery)* RBRACE           # VerboseCHRConjunction
+    ;
+    
+
 chrQuery 
-    = listQualifier (COMMA listQualifier)*                   # CHRQuery
+    = chrQueryPart (COMMA chrQueryPart)*                     # CHRConjunction
     ;
 
-verboseChrQuery
-    = LBRACE listQualifier (SEMICOLON listQualifier)* RBRACE # VerboseCHRQuery
+chrQueryPart
+    = exp                                                    # CHRAtom
+    | exp EQUALS exp                                         # CHREquals
+    | exp BINDS exp                                          # CHRBinds
     ;
 
 listQualifier
index 0f45c2511b297a3e6575c7a953c6cd5e9f752c34..1277ffe7b373ff03b30da9f46c49541f7094aae3 100644 (file)
@@ -100,7 +100,7 @@ char_literal    = "'" ([^'\\\ufffd] | "\\" [^\ufffd]) "'"
   transformation  { return sym(supportCHR() ? SCLTerminals.ID : SCLTerminals.TRANSFORMATION); }
   select{whitespace}first { return sym(SCLTerminals.SELECT_FIRST); }
   select{whitespace}distinct { return sym(SCLTerminals.SELECT_DISTINCT); }
-  select          { return sym(SCLTerminals.SELECT); }
+  select          { return sym(supportCHR() ? SCLTerminals.CHR_SELECT : SCLTerminals.SELECT); }
   enforce         { return sym(SCLTerminals.ENFORCE); }
   do              { return sym(SCLTerminals.DO); }
   eq              { return sym(options.supportEq ? SCLTerminals.EQ : SCLTerminals.ID); }
index 5944d12e1cf288e701348305082a2d101eb07591..e3efc28ddf3bfb5e84bd8dc33eae07b276c16fd5 100644 (file)
@@ -1276,7 +1276,7 @@ public class SCLLexer {
             }
           case 175: break;
           case 81: 
-            { return sym(SCLTerminals.SELECT);
+            { return sym(supportCHR() ? SCLTerminals.CHR_SELECT : SCLTerminals.SELECT);
             }
           case 176: break;
           case 82: 
index 378013be5fbabbeb1085e6d43b3854b269873bf0..3d4d5096294402e60dcbbc6bf75b0fa3a5e7ab78 100644 (file)
Binary files a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat and b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat differ
index fc2242dce632d482d95170a31f9bafe86d8a1eb3..3e857b7f1bc8192ef7dc0fe55c80fcdc78f66ab5 100644 (file)
@@ -13,18 +13,18 @@ public abstract class SCLParser {
     public static final boolean TRACE = false;
 
     private static final int INITIAL_CAPACITY = 16;
-    private static final int STATE_COUNT = 358;
-    private static final int TERMINAL_COUNT = 84;
+    private static final int STATE_COUNT = 362;
+    private static final int TERMINAL_COUNT = 85;
     private static final int NONTERMINAL_COUNT = 52;
-    private static final int PRODUCT_COUNT = 135;
+    private static final int PRODUCT_COUNT = 138;
     
     private static final int[] ACTION_ROW_ID = new int[STATE_COUNT];
     private static final int[] ACTION_COLUMN_ID = new int[TERMINAL_COUNT];
-    private static final short[] ACTION_TABLE = new short[6944];
-    private static final int[] ERROR_TABLE = new int[940];
+    private static final short[] ACTION_TABLE = new short[6832];
+    private static final int[] ERROR_TABLE = new int[962];
     private static final int[] GOTO_ROW_ID = new int[STATE_COUNT];
     private static final int[] GOTO_COLUMN_ID = new int[NONTERMINAL_COUNT];
-    private static final short[] GOTO_TABLE = new short[1708];
+    private static final short[] GOTO_TABLE = new short[1953];
     private static final int[] PRODUCT_LHS = new int[PRODUCT_COUNT];
 
     private static final short STATE_MASK = (short)0x0fff;
@@ -99,6 +99,7 @@ public abstract class SCLParser {
         "SELECT_DISTINCT",
         "TRANSFORMATION",
         "EQ",
+        "CHR_SELECT",
         "ATTACHED_DOT",
         "IN",
         "THEN",
@@ -156,12 +157,12 @@ public abstract class SCLParser {
         "accessor",
         "case",
         "queryBlock",
+        "verboseChrQuery",
         "stringLiteral",
         "symbolWithoutMinus",
         "listQualifier",
         "chrQuery",
-        "verboseChrQuery",
-        "constraintSpec",
+        "chrQueryPart",
         "caseRhs",
         "guardedExpArrow",
         "equation",
@@ -395,19 +396,19 @@ public abstract class SCLParser {
         return parse(0);
     }
     public Object parseCommands() {
-        return parse(342);
+        return parse(346);
     }
     public Object parseImport() {
-        return parse(350);
+        return parse(354);
     }
     public Object parseType() {
-        return parse(352);
+        return parse(356);
     }
     public Object parseExp() {
-        return parse(354);
+        return parse(358);
     }
     public Object parseEquationBlock() {
-        return parse(356);
+        return parse(360);
     }
 
 
@@ -535,142 +536,148 @@ public abstract class SCLParser {
         case 59:
             return reduceSelect();
         case 60:
-            return reduceEnforce();
+            return reduceCHRSelect();
         case 61:
-            return reduceVar();
+            return reduceEnforce();
         case 62:
-            return reduceHashedId();
+            return reduceVar();
         case 63:
-            return reduceBlank();
+            return reduceHashedId();
         case 64:
-            return reduceInteger();
+            return reduceBlank();
         case 65:
-            return reduceFloat();
+            return reduceInteger();
         case 66:
-            return reduceString();
+            return reduceFloat();
         case 67:
-            return reduceChar();
+            return reduceString();
         case 68:
-            return reduceTuple();
+            return reduceChar();
         case 69:
-            return reduceViewPattern();
+            return reduceTuple();
         case 70:
-            return reduceRightSection();
+            return reduceViewPattern();
         case 71:
-            return reduceLeftSection();
+            return reduceRightSection();
         case 72:
-            return reduceListLiteral();
+            return reduceLeftSection();
         case 73:
-            return reduceRange();
+            return reduceListLiteral();
         case 74:
-            return reduceListComprehension();
+            return reduceRange();
         case 75:
-            return reduceAs();
+            return reduceListComprehension();
         case 76:
-            return reduceRecord();
+            return reduceAs();
         case 77:
-            return reduceTransformation();
+            return reduceRecord();
         case 78:
-            return reduceEq();
+            return reduceTransformation();
         case 79:
-            return reduceRuleDeclarations();
+            return reduceEq();
         case 80:
-            return reduceStatements();
+            return reduceRuleDeclarations();
         case 81:
-            return reduceImportShowing();
+            return reduceStatements();
         case 82:
-            return reduceImportHiding();
+            return reduceImportShowing();
         case 83:
-            return reduceImportValueItem();
+            return reduceImportHiding();
         case 84:
-            return reduceFieldDescription();
+            return reduceImportValueItem();
         case 85:
-            return reduceGuardedExpEq();
+            return reduceFieldDescription();
         case 86:
-            return reduceFundep();
+            return reduceGuardedExpEq();
         case 87:
-            return reduceQueryRuleDeclaration();
+            return reduceFundep();
         case 88:
-            return reduceAnnotation();
+            return reduceQueryRuleDeclaration();
         case 89:
-            return reduceGuardQuery();
+            return reduceAnnotation();
         case 90:
-            return reduceEqualsQuery();
+            return reduceGuardQuery();
         case 91:
-            return reduceBindQuery();
+            return reduceEqualsQuery();
         case 92:
-            return reduceCompositeQuery();
+            return reduceBindQuery();
         case 93:
-            return reduceApply();
+            return reduceCompositeQuery();
         case 94:
-            return reduceSymbol();
+            return reduceApply();
         case 95:
-            return reduceEscapedId();
+            return reduceSymbol();
         case 96:
-            return reduceMinus();
+            return reduceEscapedId();
         case 97:
-            return reduceLess();
+            return reduceMinus();
         case 98:
-            return reduceGreater();
+            return reduceLess();
         case 99:
-            return reduceDot();
+            return reduceGreater();
         case 100:
-            return reduceFieldAccess();
+            return reduceDot();
         case 101:
-            return reduceIdAccessor();
+            return reduceFieldAccess();
         case 102:
-            return reduceStringAccessor();
+            return reduceIdAccessor();
         case 103:
-            return reduceExpAccessor();
+            return reduceStringAccessor();
         case 104:
-            return reduceCase();
+            return reduceExpAccessor();
         case 105:
-            return reduceQueryBlock();
+            return reduceCase();
         case 106:
-            return reduceStringLiteral();
+            return reduceQueryBlock();
         case 107:
-            return reduceSymbol();
+            return reduceVerboseCHRConjunction();
         case 108:
-            return reduceEscapedId();
+            return reduceStringLiteral();
         case 109:
-            return reduceLess();
+            return reduceSymbol();
         case 110:
-            return reduceGreater();
+            return reduceEscapedId();
         case 111:
-            return reduceDot();
+            return reduceLess();
         case 112:
-            return reduceGuardQualifier();
+            return reduceGreater();
         case 113:
-            return reduceLetQualifier();
+            return reduceDot();
         case 114:
-            return reduceBindQualifier();
+            return reduceGuardQualifier();
         case 115:
-            return reduceThenQualifier();
+            return reduceLetQualifier();
         case 116:
-            return reduceCHRQuery();
+            return reduceBindQualifier();
         case 117:
-            return reduceVerboseCHRQuery();
+            return reduceThenQualifier();
         case 118:
-            return reduceConstraintSpec();
+            return reduceCHRConjunction();
         case 119:
-            return reduceSimpleCaseRhs();
+            return reduceCHRAtom();
         case 120:
-            return reduceGuardedCaseRhs();
+            return reduceCHREquals();
         case 121:
-            return reduceGuardedExpArrow();
+            return reduceCHRBinds();
         case 122:
-            return reduceGuardEquation();
+            return reduceSimpleCaseRhs();
         case 123:
-            return reduceBasicEquation();
+            return reduceGuardedCaseRhs();
         case 124:
-            return reduceEffect();
+            return reduceGuardedExpArrow();
         case 125:
-            return reduceJustEtype();
+            return reduceGuardEquation();
         case 126:
-            return reduceForAll();
+            return reduceBasicEquation();
         case 127:
-            return reduceApplyType();
+            return reduceEffect();
         case 128:
+            return reduceJustEtype();
+        case 129:
+            return reduceForAll();
+        case 130:
+            return reduceApplyType();
+        case 131:
             return reduceDummy();
 
         default:
@@ -824,7 +831,7 @@ public abstract class SCLParser {
      */
     protected abstract Object reduceVerboseCHRStatement();
     /**
-     * statement ::= CONSTRAINT constructor (WHERE constraintSpec)?
+     * statement ::= CONSTRAINT constructor
      */
     protected abstract Object reduceConstraintStatement();
     /**
@@ -931,6 +938,10 @@ public abstract class SCLParser {
      * aexp ::= (SELECT | SELECT_FIRST | SELECT_DISTINCT) exp WHERE queryBlock
      */
     protected abstract Object reduceSelect();
+    /**
+     * aexp ::= CHR_SELECT exp WHERE verboseChrQuery
+     */
+    protected abstract Object reduceCHRSelect();
     /**
      * aexp ::= ENFORCE queryBlock
      */
@@ -1111,6 +1122,10 @@ public abstract class SCLParser {
      * queryBlock ::= LBRACE (query (SEMICOLON (query SEMICOLON)&#42; query)?)? RBRACE
      */
     protected abstract Object reduceQueryBlock();
+    /**
+     * verboseChrQuery ::= LBRACE chrQuery (SEMICOLON chrQuery)&#42; RBRACE
+     */
+    protected abstract Object reduceVerboseCHRConjunction();
     /**
      * stringLiteral ::= BEGIN_STRING (SUSPEND_STRING exp CONTINUE_STRING)&#42; END_STRING
      */
@@ -1132,17 +1147,21 @@ public abstract class SCLParser {
      */
     protected abstract Object reduceThenQualifier();
     /**
-     * chrQuery ::= (listQualifier COMMA)&#42; listQualifier
+     * chrQuery ::= (chrQueryPart COMMA)&#42; chrQueryPart
+     */
+    protected abstract Object reduceCHRConjunction();
+    /**
+     * chrQueryPart ::= exp
      */
-    protected abstract Object reduceCHRQuery();
+    protected abstract Object reduceCHRAtom();
     /**
-     * verboseChrQuery ::= LBRACE listQualifier (SEMICOLON listQualifier)&#42; RBRACE
+     * chrQueryPart ::= exp EQUALS exp
      */
-    protected abstract Object reduceVerboseCHRQuery();
+    protected abstract Object reduceCHREquals();
     /**
-     * constraintSpec ::= LBRACE exp (SEMICOLON exp)&#42; RBRACE
+     * chrQueryPart ::= exp BINDS exp
      */
-    protected abstract Object reduceConstraintSpec();
+    protected abstract Object reduceCHRBinds();
     /**
      * caseRhs ::= ARROW exp (WHERE statements)?
      */
index 34f8d6a9f0da95e4e6a01a95021d82f893176ca8..bda298bd661afd593eb59fc5766f9a6b72ba46da 100644 (file)
@@ -11,6 +11,11 @@ import org.simantics.scl.compiler.common.precedence.Precedence;
 import org.simantics.scl.compiler.compilation.CompilationContext;
 import org.simantics.scl.compiler.constants.CharacterConstant;
 import org.simantics.scl.compiler.constants.StringConstant;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
 import org.simantics.scl.compiler.elaboration.equation.Equation;
@@ -31,6 +36,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EListComprehension;
 import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
 import org.simantics.scl.compiler.elaboration.expressions.EMatch;
+import org.simantics.scl.compiler.elaboration.expressions.EPreCHRSelect;
 import org.simantics.scl.compiler.elaboration.expressions.ERange;
 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
@@ -1246,25 +1252,12 @@ public class SCLParserImpl extends SCLParser {
         return new EViewPattern((Expression)get(1), (Expression)get(3));
     }
 
-    @Override
-    protected Object reduceCHRStatement() {
-        return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
-    }
-
     @Override
     protected Object reduceConstraintStatement() {
         ConstructorAst constructor = (ConstructorAst)get(1);
         return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
     }
 
-    @Override
-    protected Object reduceCHRQuery() {
-        ListQualifier[] query = new ListQualifier[(length()+1)/2];
-        for(int i=0;i<query.length;++i)
-            query[i] = (ListQualifier)get(i*2);
-        return query;
-    }
-
     /*
     @Override
     protected Object reduceWhen() {
@@ -1272,19 +1265,6 @@ public class SCLParserImpl extends SCLParser {
                 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() {
@@ -1305,12 +1285,58 @@ public class SCLParserImpl extends SCLParser {
         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));
     }
 
 }
index 58a40f61ea64bfce284ace557fd935f5e5cc4356..6aab6c4b6a365ceb9b9fcdefbad6da88162ff362 100644 (file)
@@ -65,24 +65,25 @@ public interface SCLTerminals {
     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;
 }
index e92f4d3b4a62e94d497cab50b188c9afc1dba7f3..77d192f0019ae298a1f11e092a4a12109c887fdc 100644 (file)
@@ -1,5 +1,5 @@
-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;
@@ -62,7 +62,7 @@ public class HtmlDocumentationGeneration {
                 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");
             
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlGenerationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HtmlGenerationContext.java
new file mode 100644 (file)
index 0000000..2de5a70
--- /dev/null
@@ -0,0 +1,12 @@
+package org.simantics.scl.compiler.markdown.html;
+
+public class HtmlGenerationContext {
+    public final boolean generateAnchors;
+    
+    public HtmlGenerationContext(boolean generateAnchors) {
+        this.generateAnchors = generateAnchors;
+    }
+
+    public static final HtmlGenerationContext DEFAULT = new HtmlGenerationContext(true);
+    public static final HtmlGenerationContext TEST_DEFAULT = new HtmlGenerationContext(false);
+}
index eb4626f662ef38bc7face6bf34232d23a177be08..f49e4781cb62888747bf4057cf8369e3912e58f4 100644 (file)
@@ -218,7 +218,7 @@ public class MarkdownParser {
             else if((c == '=' || c == '-') 
                     && container instanceof ParagraphNode
                     && Scanner.isSetextHeaderLine(line, firstNonspace, c)
-                    && container.stringContent.indexOf("\n") == -1
+                    /*&& container.stringContent.indexOf("\n") == -1*/
                     ) {
                 HeaderNode header = new HeaderNode(c == '=' ? 1 : 2, true);
                 header.lineNumber = container.lineNumber;
index 34323b402b875706afe057ceb40c3954607f0767..f7b854007c02a856d5b79d24236d01f750d872c8 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class AutolinkNode extends Node {
@@ -11,7 +12,7 @@ public class AutolinkNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<a href=\"");
         if(email)
             b.append("mailto:");
index 355c945b8e790f1b2f5f578dfc501af74cec0851..eb2bda6a08e44499aee3c7c665176c40d9fe976e 100644 (file)
@@ -1,5 +1,7 @@
 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) {
@@ -7,9 +9,9 @@ public class BlockQuoteNode extends 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");
     }
 }
index 797a21bf03665e416275f15298897d4122cbef0e..fed7a73a84caf2757d2432795394ae8b4a512b5f 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class CodeBlockNode extends Node {
@@ -30,7 +31,7 @@ public class CodeBlockNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         if(infoString == null || infoString.isEmpty())
             b.append("<pre><code>");
         else {
index 673a3e82dcddbb6baf48ef309784692dfa6aeb9a..8a421d2937993ecfda8a77339a14ffce9410cf4d 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class CodeNode extends Node {
@@ -8,7 +9,7 @@ public class CodeNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<code>");
         b.append(HtmlEscape.escape(stringContent));
         b.append("</code>");
index 82d7d2eb4f99b333e5b16a937314bf87b4b2fe93..b438ab4e0a316cb6509964203f6892cd5bd3f370 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class EmphNode extends Node {
     boolean strong;
     
@@ -8,12 +10,12 @@ public class EmphNode extends Node {
     }
 
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         if(strong)
             b.append("<strong>");
         else
             b.append("<em>");
-        super.toHtml(b);
+        super.toHtml(context, b);
         if(strong)
             b.append("</strong>");
         else
index 62d95e1a37f6e6be659aec748e839d5d68e9165d..525a4187c1f05d4dbd61d123b278a9abe776339c 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.ExtensionNodeHandler;
 
 public class ExtensionBlockNode extends Node {
@@ -37,7 +38,7 @@ public class ExtensionBlockNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("::").append(extension).append('[').append(content).append(']');
     }
 }
index 71933f0ebcb3d91e9c43df1567a42f0ce97e9fd8..816d595fba292a75bceaaddaa9c1a186b974dc5b 100644 (file)
@@ -1,8 +1,10 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class HardLineBreakNode extends Node {
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<br />\n");
     }
 }
index 05de801ad0474c2785b5307a592b08d42c38bf17..39a2b47f786d4a352a14cdf6c370f884778b86e2 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 
 public class HeaderNode extends Node {
     public int level;
@@ -16,11 +17,16 @@ public class HeaderNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
-        b.append("<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");
     }
 }
index 5416cb0c309ac5a391fb4f6b0233f0d526c9fb6c..22b393cc2a1c9f6977276add859980da43c095d3 100644 (file)
@@ -1,8 +1,10 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class HorizontalRuleNode extends Node {
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<hr />\n");
     }
 }
index fc0752b64daf923cd65b178680bf0e57704bb68b..897c962d0c41954b7db127077f0eb6fa9b544665 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class HtmlNode extends Node {
     public HtmlNode() {
     }
@@ -12,7 +14,7 @@ public class HtmlNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append(stringContent);
         b.append('\n');
     }
index 25122bc73145609e093be15756e700a855774598..9ef771ab9b8b548a6b2ed5a719471a4d9b90ab20 100644 (file)
@@ -1,11 +1,13 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
+
 public class HtmlTagNode extends Node {
     public HtmlTagNode(StringBuilder stringContent) {
         this.stringContent = stringContent;
     }
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append(stringContent);
     }
 }
index ebe5d56541f8d556bf16c16edbd6e6301fb75303..e238c43510187fe5ac421c7704e952116b6e0a54 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class ImageNode extends Node {
@@ -14,7 +15,7 @@ public class ImageNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<img src=\"").append(HtmlEscape.escapeURL(url))
          .append("\" alt=\"");
         toPlainText(b);
index 8217b7e968727415e47d43259f25b3a0639f354b..4e2737f2e48a004ae7b15c1ca1494d59f75ffadb 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 
 public class ItemNode extends Node {
     public int indentation;
@@ -13,11 +14,11 @@ public class ItemNode extends Node {
         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;
@@ -29,7 +30,7 @@ public class ItemNode extends Node {
             for(Node child = firstChild; child != null; child = child.next) {
                 if(child instanceof ParagraphNode) {
                     for(Node n=child.firstChild;n!=null;n=n.next)
-                        n.toHtml(b);
+                        n.toHtml(context, b);
                     noNewline = true;
                 }
                 else {
@@ -37,14 +38,14 @@ public class ItemNode extends Node {
                         b.append('\n');
                         noNewline = false;
                     }
-                    child.toHtml(b);
+                    child.toHtml(context, b);
                 }
             }
             b.append("</li>\n");
         }
         else {
             b.append("<li>\n");
-            super.toHtml(b);
+            super.toHtml(context, b);
             b.append("</li>\n");
         }
     }
index 829dd4233a0843abdf60834e3afbf59209f3e2ce..bde60f2b73990b3218db47e9f958e1714e0038db 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class LinkNode extends Node {
@@ -14,7 +15,7 @@ public class LinkNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<a href=\"").append(HtmlEscape.escapeURL(url));
         if(title.isEmpty())
             b.append("\">");
@@ -23,7 +24,7 @@ public class LinkNode extends Node {
             b.append(HtmlEscape.escape(title));
             b.append("\">");
         }
-        super.toHtml(b);
+        super.toHtml(context, b);
         b.append("</a>");
     }
 }
index 1bf3397387b3c98fa4f0aa2d32cfb533d34fb706..82e123f263665d0bbe260cbe424736d759f61964 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 
 public class ListNode extends Node {
     public char bulletChar;
@@ -25,11 +26,11 @@ public class ListNode extends Node {
     }
     
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         if(bulletChar == '+' || bulletChar == '-' || bulletChar == '*') {
             b.append("<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 {
@@ -38,7 +39,7 @@ public class ListNode extends Node {
             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");
         }
     }
index 7c91ceaa023e95f7a745f295362d6b77b03193be..9e576beed4883a1a7de57038a2d471662c97708d 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.markdown.nodes;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.ExtensionNodeHandler;
 import org.simantics.scl.compiler.markdown.internal.MarkdownParser;
 
@@ -33,9 +34,9 @@ public abstract class Node {
         return false;
     }
     
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         for(Node child = firstChild; child != null; child = child.next)
-            child.toHtml(b);
+            child.toHtml(context, b);
     }
     
     public List<HeaderNode> extractHeaders() {
@@ -46,9 +47,9 @@ public abstract class Node {
         return result;
     }
     
-    public String toHtml() {
+    public String toHtml(HtmlGenerationContext context) {
         StringBuilder b = new StringBuilder();
-        toHtml(b);
+        toHtml(context, b);
         int len = b.length();
         if(len > 0 && b.charAt(len-1) == '\n')
             b.delete(len-1, len);
index 8e37c1e5c0ce13d5ed0fff239033597d6940759d..3b3611ac78774650fd0d0db95741cc6e4cee53a3 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 
 public class ParagraphNode extends Node {
     @Override
@@ -7,9 +8,9 @@ public class ParagraphNode extends Node {
         return true;
     }
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append("<p>");
-        super.toHtml(b);
+        super.toHtml(context, b);
         b.append("</p>\n");
     }
 }
index 710b3ce51fc8118a4e837c2052276a33517c9fa6..8922a1e5290efe28168e9db5a380f66d674a97eb 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.markdown.nodes;
 
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.HtmlEscape;
 
 public class TextNode extends Node {
@@ -7,7 +8,7 @@ public class TextNode extends Node {
         this.stringContent = text;
     }
     @Override
-    public void toHtml(StringBuilder b) {
+    public void toHtml(HtmlGenerationContext context, StringBuilder b) {
         b.append(HtmlEscape.escape(stringContent));
     }
     @Override
index da837fb60e59947395c9872fddc27b45a4eee3cc..fdb01e58d37ce2f1cf37a49dee5fd82eee3531e2 100644 (file)
@@ -126,7 +126,7 @@ public class ParseTableBuilder {
                     }
                 }
                 stackOpMap.put(a, stackOp);
-                System.out.println(newState + " " + grammar.getName(a) + " " + stackOp);
+                //System.out.println(newState + " " + grammar.getName(a) + " " + stackOp);
                 
                 if(stackOverflow) {
                     System.err.println("Stack overflow when following " + grammar.getName(a) + " at");
@@ -396,7 +396,7 @@ public class ParseTableBuilder {
         
         //builder.visualize();
         
-        builder.printParseTable();
+        //builder.printParseTable();
         return builder.getParseTable();
     }
 
index d8526ca12c45024601b39efef4f10cc4a7938057..ed0968b36800d1dc163aba4620ee7ed88ad6ea3b 100644 (file)
@@ -7,7 +7,7 @@ import java.util.Arrays;
 import java.util.Collections;
 
 public abstract class GrammarParser {    
-    public static final boolean TRACE = true;
+    public static final boolean TRACE = false;
 
     private static final int INITIAL_CAPACITY = 16;
     private static final int STATE_COUNT = 19;
index 939010d40bc9392db981081bfbdb52496344fcf2..61a1d2c958526db87ef442d0155bafe1bbf6a602 100644 (file)
@@ -1,9 +1,11 @@
 package org.simantics.scl.compiler.source.repository;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 import org.simantics.scl.compiler.module.Module;
 import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.module.repository.UpdateListener.Observable;
 import org.simantics.scl.compiler.source.ModuleSource;
 import org.simantics.scl.compiler.source.PrecompiledModuleSource;
 
@@ -21,6 +23,8 @@ public class MapModuleSourceRepository implements ModuleSourceRepository {
     THashMap<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() {
     }
     
@@ -36,6 +40,12 @@ public class MapModuleSourceRepository implements ModuleSourceRepository {
     
     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) {
@@ -49,6 +59,29 @@ public class MapModuleSourceRepository implements ModuleSourceRepository {
     @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);
     }
 
index 67f43838d837ff897d8a0f8c9a3d1e97df13ecee..899ee0418efef4af964fa01d69ddf06edfcb6520 100644 (file)
@@ -42,7 +42,6 @@ import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
 import org.simantics.scl.compiler.internal.codegen.writer.ExternalConstant;
 import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter;
 import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
 import org.simantics.scl.compiler.internal.parsing.parser.SCLBlockParser;
@@ -300,9 +299,9 @@ public class ExpressionEvaluator {
             if(!errorLog.hasNoErrors())
                 throw new SCLExpressionCompilationException(errorLog.getErrors());
             if(decorateExpression && Types.canonical(expectedEffect) != Types.NO_EFFECTS) {
-                ExpressionDecorator decorator =
+                ToplevelEffectDecorator decorator =
                         new ToplevelEffectDecorator(errorLog, environment);
-                expression = expression.decorate(decorator);
+                expression = expression.accept(decorator);
             }
             expression = context.solveConstraints(environment, expression);
             expressionType = expression.getType();
index 5a3c39e60a3fcecd9f56bf68cc6a2a8f32cf85d1..491d88e41b95ef6d3f254ae7472d9e54d9134fda 100644 (file)
@@ -4,7 +4,9 @@ import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.common.names.Names;
+import org.simantics.scl.compiler.elaboration.expressions.Case;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.ECHRRuleset;
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;
 import org.simantics.scl.compiler.elaboration.expressions.EFieldAccess;
@@ -15,16 +17,18 @@ import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
 import org.simantics.scl.compiler.elaboration.expressions.EWhen;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionTransformer;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.errors.Locations;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
-public class ToplevelEffectDecorator implements ExpressionDecorator {
+import gnu.trove.map.hash.THashMap;
+
+public class ToplevelEffectDecorator extends StandardExpressionTransformer {
 
     ErrorLog errorLog;
     Environment environment;
@@ -34,92 +38,101 @@ public class ToplevelEffectDecorator implements ExpressionDecorator {
         this.environment = environment;
     }
 
-    private static Expression decorate(SCLValue transactionFunction, Type effect, Expression expression) {
-        Variable var = new Variable("_");
-        var.setType(Types.UNIT);
-        Expression trans = new EApply(expression.getLocation(), Types.PROC,
-                new EConstant(transactionFunction,
-                        expression.getType()),
-                        new ESimpleLambda(Locations.NO_LOCATION, var, effect, expression)
-                );
-        if(expression instanceof EApply) {
-            EApply apply = (EApply)expression;
-            trans = apply.toANormalForm(trans);
-        }
-        return trans;
+    @Override
+    public Expression transform(EEnforce expression) {
+        return decorateByEffect(expression, expression.getEffect());
+    }
+    
+    @Override
+    public Expression transform(EWhen expression) {
+        return decorateByEffect(expression, expression.getEffect());
+    }
+    
+    @Override
+    public Expression transform(ERuleset expression) {
+        return decorateByEffect(expression, expression.getEffect());
+    }
+    
+    @Override
+    public Expression transform(ECHRRuleset expression) {
+        return decorateByEffect(expression, expression.getEffect());
+    }
+    
+    @Override
+    public Expression transform(EFieldAccess expression) {
+        // Can we encounter EFieldAccess in this transformer?
+        return decorateByEffect(expression, expression.getEffect());
+    }
+    
+    @Override
+    public Expression transform(ESelect expression) {
+        return decorateByEffect(expression, expression.getEffect());
     }
 
-    private static final TCon R = Types.con("R/R", "R");
+    @Override
+    public Expression transform(EApply expression) {
+        return decorateByEffect(super.transform(expression), expression.getLocalEffect());
+    }
 
     @Override
-    public Expression decorate(Expression expression) {
-        if(expression instanceof EApply)
-            return decorateByEffect(expression, ((EApply)expression).getLocalEffect());
-        else if(expression instanceof ESelect 
-                || expression instanceof EEnforce
-                || expression instanceof EWhen
-                || expression instanceof EFieldAccess
-                || expression instanceof ERuleset)
-            return decorateByEffect(expression, expression.getEffect());
+    public Expression transform(ESimpleLambda expression) {
+        // Never has side effects
         return expression;
     }
 
+    @Override
+    public Expression transform(ELambda expression) {
+        // Never has side effects
+        return expression;
+    }
+
+    @Override
+    protected void transformCases(Case[] cases) {
+        for(Case case_ : cases)
+            case_.value = case_.value.accept(this);
+    }
+    
+    private static final THashMap<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;
     }
-
 }
index 52095a10169c88160aac11f4b9d3392cc79806e4..61be3240eb72230529a65c273d113410c311f9e8 100644 (file)
@@ -8,5 +8,6 @@ Require-Bundle: org.simantics.scl.runtime;bundle-version="0.4.0",
  org.simantics.scl.osgi;bundle-version="1.0.4",
  org.jdom2;bundle-version="2.0.6",
  org.junit;bundle-version="4.12.0";resolution:=optional,
- com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2"
+ com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2",
+ com.fasterxml.jackson.core.jackson-databind
 Bundle-ClassPath: .
diff --git a/bundles/org.simantics.scl.data/scl/Data/JsonNode.scl b/bundles/org.simantics.scl.data/scl/Data/JsonNode.scl
new file mode 100644 (file)
index 0000000..f0e49f4
--- /dev/null
@@ -0,0 +1,23 @@
+import "StandardLibrary"
+import "Data/Writer"
+import "JavaBuiltin" as Java
+import "Data/Json"
+
+importJava "com.fasterxml.jackson.databind.JsonNode" where
+    data JsonNode
+
+importJava "org.simantics.scl.data.xml.JsonNodeHelper" where
+    @private
+    @JavaName toJsonString
+    jsonNodeToString :: JsonNode -> String
+    @private
+    @JavaName fromJsonString
+    stringToJsonNode :: String -> JsonNode
+
+jsonNodeToJson :: JsonNode -> Json
+jsonNodeToJson node = fromJsonString (jsonNodeToString node)
+
+jsonToJsonNode :: Json -> JsonNode
+jsonToJsonNode json = stringToJsonNode (toJsonString json)
+
+    
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JsonNodeHelper.java b/bundles/org.simantics.scl.data/src/org/simantics/scl/data/xml/JsonNodeHelper.java
new file mode 100644 (file)
index 0000000..9eda114
--- /dev/null
@@ -0,0 +1,28 @@
+package org.simantics.scl.data.xml;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+public class JsonNodeHelper {
+
+       private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
+
+       static {
+           SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
+       }
+
+       public static String toJsonString(JsonNode node) throws JsonProcessingException {
+           final Object obj = SORTED_MAPPER.treeToValue(node, Object.class);
+           final String json = SORTED_MAPPER.writeValueAsString(obj);
+           return json;
+       }
+
+       public static JsonNode fromJsonString(String s) throws JsonProcessingException, IOException {
+               return SORTED_MAPPER.readTree(s);       
+       }
+       
+}
index df556086ed6ab61d0aa1458f5d6da06e24955172..32019768b2f08e7c6bb930a014fa8d656413ba0b 100644 (file)
@@ -265,6 +265,9 @@ importJava "org.simantics.db.common.utils.ListUtils" where
     
     @JavaName create
     createList :: [Resource] -> <WriteGraph> Resource
+
+    @JavaName create
+    createList :: Resource -> [Resource] -> <WriteGraph> Resource
     
     @javaName insertBack
     insertBack :: Resource -> [Resource] -> <WriteGraph> ()
index a8ffd13db76dedbe5ff5093e5e9ee722a96c7aea..9a6ffde8c17267717a3113d3ecfded655e262942 100644 (file)
@@ -21,6 +21,9 @@ Example:
     """
     variable :: String -> <ReadGraph> Variable
     
+    @JavaName getPossibleVariable
+    possibleVariable :: String -> <ReadGraph> Maybe Variable
+
     @JavaName getVariable
     """
 Function **resourceVariable** converts a resource to a corresponding variable.
diff --git a/bundles/org.simantics.scl.rest/.classpath b/bundles/org.simantics.scl.rest/.classpath
new file mode 100644 (file)
index 0000000..eca7bdb
--- /dev/null
@@ -0,0 +1,7 @@
+<?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>
diff --git a/bundles/org.simantics.scl.rest/.gitignore b/bundles/org.simantics.scl.rest/.gitignore
new file mode 100644 (file)
index 0000000..7fb5d66
--- /dev/null
@@ -0,0 +1 @@
+.settings
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.rest/.project b/bundles/org.simantics.scl.rest/.project
new file mode 100644 (file)
index 0000000..ddf0f2c
--- /dev/null
@@ -0,0 +1,28 @@
+<?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>
diff --git a/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..e92a3cf
--- /dev/null
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics SCL REST-Server
+Bundle-SymbolicName: org.simantics.scl.rest
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.scl.rest.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.glassfish.jersey.core.jersey-server,
+ javax.ws.rs-api,
+ org.simantics.scl.compiler,
+ org.simantics.scl.osgi,
+ org.eclipse.jetty.servlet,
+ org.glassfish.jersey.containers.jersey-container-servlet-core,
+ javax.servlet-api,
+ org.eclipse.jetty.server,
+ org.eclipse.jetty.util,
+ org.eclipse.jetty.io,
+ com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.8",
+ com.fasterxml.jackson.core.jackson-annotations;bundle-version="2.8.0",
+ com.fasterxml.jackson.core.jackson-databind;bundle-version="2.8.8",
+ org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="2.25.1",
+ org.glassfish.jersey.media.jersey-media-multipart;bundle-version="2.25.1",
+ org.slf4j.api,
+ org.jvnet.mimepull;bundle-version="1.9.6"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.simantics.scl.rest/build.properties b/bundles/org.simantics.scl.rest/build.properties
new file mode 100644 (file)
index 0000000..a4fd10d
--- /dev/null
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               scl/
diff --git a/bundles/org.simantics.scl.rest/scl/SCL/REST/Server.scl b/bundles/org.simantics.scl.rest/scl/SCL/REST/Server.scl
new file mode 100644 (file)
index 0000000..8ed1f7e
--- /dev/null
@@ -0,0 +1,3 @@
+importJava "org.simantics.scl.rest.SCLRESTServer" where
+    start :: String -> Integer -> <Proc> ()
+    stop :: <Proc> ()
diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/Activator.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/Activator.java
new file mode 100644 (file)
index 0000000..4f90e69
--- /dev/null
@@ -0,0 +1,35 @@
+package org.simantics.scl.rest;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+    private static BundleContext context;
+
+    static BundleContext getContext() {
+        return context;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext bundleContext) throws Exception {
+        Activator.context = bundleContext;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext bundleContext) throws Exception {
+        SCLRESTServer.stop();
+        Activator.context = null;
+    }
+
+}
diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/AuthorizationFilter.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/AuthorizationFilter.java
new file mode 100644 (file)
index 0000000..f307b66
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 Association for Decentralized 
+ * Information Management in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the THTH Simantics 
+ * Division Member Component License which accompanies this 
+ * distribution, and is available at
+ * http://www.simantics.org/legal/sdmcl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.scl.rest;
+
+import java.io.IOException;
+
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+public class AuthorizationFilter implements ContainerRequestFilter {
+
+    private final String token;
+
+    public AuthorizationFilter(String token) {
+        this.token = token;
+    }
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+        // Get the HTTP Authorization header from the request
+        String authorizationHeader =  requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
+
+        // Check if the HTTP Authorization header is present and formatted correctly 
+        if (authorizationHeader == null || !authorizationHeader.startsWith("SCLRESTServer-Bearer ")) {
+            throw new NotAuthorizedException("Authorization header must be provided");
+        }
+
+        // Extract the token from the HTTP Authorization header
+        String token = authorizationHeader.substring("SCLRESTServer-Bearer".length()).trim();
+        try {
+            // Validate the token
+            validateToken(token);
+        } catch (Exception e) {
+            requestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
+        }
+    }
+
+    private void validateToken(String token) throws Exception {
+        if (!this.token.equals(token)) {
+            throw new Exception("Wrong token!");
+        }
+    }
+
+}
diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLAPI.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLAPI.java
new file mode 100644 (file)
index 0000000..cb86ff8
--- /dev/null
@@ -0,0 +1,62 @@
+package org.simantics.scl.rest;
+
+import java.io.Reader;
+import java.io.Writer;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.simantics.scl.compiler.commands.CommandSessionWithModules;
+import org.simantics.scl.osgi.SCLOsgi;
+
+public class SCLAPI {
+
+    private static SCLAPI INSTANCE;
+    
+    private ConcurrentHashMap<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);
+    }
+}
diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTAPI.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTAPI.java
new file mode 100644 (file)
index 0000000..4ded247
--- /dev/null
@@ -0,0 +1,110 @@
+package org.simantics.scl.rest;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+
+import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
+import org.glassfish.jersey.media.multipart.FormDataParam;
+
+@Path("SCLAPI")
+@Produces(MediaType.APPLICATION_JSON)
+public class SCLRESTAPI {
+
+    private SCLAPI sclAPI;
+
+    public SCLRESTAPI() {
+        sclAPI = SCLAPI.getInstance();
+    }
+    
+    private static Map<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();
+    }
+
+}
diff --git a/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTServer.java b/bundles/org.simantics.scl.rest/src/org/simantics/scl/rest/SCLRESTServer.java
new file mode 100644 (file)
index 0000000..0e64202
--- /dev/null
@@ -0,0 +1,85 @@
+package org.simantics.scl.rest;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.servlet.ServletContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLRESTServer {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLRESTServer.class);
+    
+    private static SCLRESTServer INSTANCE = null;
+    private static Server server;
+    private static ServiceServerThread serverThread;
+
+    private SCLRESTServer(String token, int preferablePort) {
+        ResourceConfig config = new ResourceConfig();
+        // JSON serialization/deserialization
+        config.register(JacksonFeature.class);
+        // File upload
+        config.register(MultiPartFeature.class);
+        // Actual API
+        config.register(SCLRESTAPI.class);
+        // Authorization
+        config.register(new AuthorizationFilter(token));
+        
+        ServletHolder holder = new ServletHolder(new ServletContainer(config));
+        
+        server = new Server();
+        ServerConnector connector = new ServerConnector(server);
+        connector.setPort(preferablePort);
+        connector.setHost("localhost");
+        
+        server.setConnectors(new Connector[] { connector });
+        
+        ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
+        context.addServlet(holder, "/*");
+    }
+    
+    private static class ServiceServerThread extends Thread {
+
+        @Override
+        public void run() {
+            try {
+                server.start();
+                server.join();
+            } catch (Exception e) {
+                LOGGER.error("Could not start server ", e);
+            }
+        }
+    }
+
+    private static synchronized SCLRESTServer getInstance(String token, int port) {
+        try {
+            if (INSTANCE == null) {
+                INSTANCE = new SCLRESTServer(token, port);
+            }
+        } catch (Exception e) {
+            LOGGER.error("Could not initialize SCL REST server", e);
+        }
+        return INSTANCE;
+    }
+
+    public static synchronized void start(String token, int port) throws Exception {
+        // Ensure that an instance is created
+        getInstance(token, port);
+        if (serverThread == null && server != null) {
+            serverThread = new ServiceServerThread();
+            serverThread.start();
+        }
+    }
+    
+    public static synchronized void stop() throws Exception {
+        if (server != null)
+            server.stop();
+        serverThread = null;
+    }
+}
index c81f8308954e8ee241653b686b8d0bcbeffdaa6c..eb1e8cd6ff35bed0186d22d68e7b115626246d04 100644 (file)
@@ -1540,6 +1540,24 @@ joinWithSeparator :: Show a => String -> [a] -> String
 joinWithSeparator separator values = runProc ( 
     StringBuilder.toString $ printWithSeparator StringBuilder.new separator values)
 
+
+intercalate :: String -> [String] -> String
+intercalate separator strings = do
+    l = length strings
+    if l == 0
+    then ""
+    else if l == 1
+    then strings!0
+    else runProc do
+        sb = StringBuilder.new
+        sb << strings!0
+        loop i | i == l = ()
+               | otherwise = do
+            sb << separator << strings!i
+            loop (i+1)
+        loop 1
+        StringBuilder.toString sb
+
 instance (Show a) => Show [a] where
     sb <+ l = do 
         len = length l
diff --git a/bundles/org.simantics.scl.runtime/scl/SetUtils.scl b/bundles/org.simantics.scl.runtime/scl/SetUtils.scl
new file mode 100644 (file)
index 0000000..00fa752
--- /dev/null
@@ -0,0 +1,13 @@
+import "Prelude"
+import "Set" as Set
+import "MSet" as MSet
+import "MList" as MList
+
+fromList :: [a] -> Set.T a
+fromList l = runProc (MSet.freeze $ MSet.fromList l)
+
+toList :: Set.T a -> [a]
+toList s = runProc do
+    result = MList.createC (Set.size s)
+    Set.iter (MList.add result) s
+    MList.freeze result
\ No newline at end of file
index 122fcd02b99dc8e943f72c08776c955890e45454..7234b70be861c80806d752140cb575f5453b153c 100644 (file)
@@ -10,6 +10,7 @@ include "Lazy" as Lazy
 include "File" as File
 include "Serialization" as Serialization
 include "Set" as Set
+include "SetUtils" as Set
 //include "Map" as Map
 include "MMap" as MMap
 include "MSet" as MSet
index 8f6ca3ee9f08ad4c03dde93c895d7070ef621b22..21f3b65ad69f26fdb620f97ed8e77b590ede3fc1 100644 (file)
@@ -1,5 +1,15 @@
 package org.simantics.scl.runtime.chr;
 
 public class CHRRuntimeRuleset {
-
+       int currentId;
+       
+       public void register(CHRContext context) {
+               if(context.currentId < currentId)
+                       context.currentId = currentId;
+       }
+       
+       public void unregister(CHRContext context) {
+               if(context.currentId > currentId)
+                       currentId = context.currentId;
+       }
 }
index 931ae92cdc710f1b675f7eb343a21389103142b8..061dad8522a0f7e7758588ab8fd3192238b4a835 100644 (file)
@@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.ui.editors;bundle-version="3.6.0",
  gnu.trove3;bundle-version="3.0.0",
  org.simantics.scl.osgi;bundle-version="1.0.0",
  org.simantics.scl.compiler;bundle-version="0.6.0",
- org.junit;bundle-version="4.12.0";resolution:=optional
+ org.junit;bundle-version="4.12.0";resolution:=optional,
+ com.ibm.icu
 Export-Package: org.simantics.scl.ui.console,
  org.simantics.scl.ui.editor,
  org.simantics.scl.ui.editor2,
diff --git a/bundles/org.simantics.scl.ui/icons/import_error.png b/bundles/org.simantics.scl.ui/icons/import_error.png
new file mode 100644 (file)
index 0000000..caa1838
Binary files /dev/null and b/bundles/org.simantics.scl.ui/icons/import_error.png differ
index a408e7f30ae3b745fd72ad7f3bd476933cb4ba67..768682fa3ef8a056f0b1fc73e7765a1e1390d034 100644 (file)
@@ -33,6 +33,7 @@ public class Activator extends AbstractUIPlugin {
         reg.put("find", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/find.png") );
         reg.put("disk", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/disk.png") );
         reg.put("error", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/error.png") );
+        reg.put("import_error", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/import_error.png") );
         reg.put("warning", Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/warning.png") );
     }
     
index 4c429e7fdda6ced8d40a94b7f77a9467d42f7aa6..11749a4b2b24eef1c717eec74e9129731da58ce6 100644 (file)
@@ -37,8 +37,15 @@ public class SCLCompletionProposal implements ICompletionProposal, ICompletionPr
     private final SCLCompletionType completionType;
     
     public SCLCompletionProposal(SCLValue value, int replacementOffset, String prefix) {
-        this.name = value.getName().name;
-        this.module = value.getName().module;
+        String tempName = value.getName().name;
+        String tempModule = value.getName().module;
+        int p = tempName.lastIndexOf('.');
+        if(p >= 0) {
+            tempModule = tempModule + "." + tempName.substring(0, p);
+            tempName = tempName.substring(p+1);
+        }
+        this.name = tempName;
+        this.module = tempModule;
         this.documentation = value.getDocumentation();
         this.content = name + " :: " + value.getType() + "  (" + module + ")";
         this.replacementOffset = replacementOffset;
index 4b6818ab7b805587bfe6306a9f1154e48ac0e3ad..378840397759e1fbdbdc3714b2c3c930c01fa32b 100644 (file)
@@ -9,6 +9,7 @@ import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.PlatformUI;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.module.InvalidModulePathException;
 import org.simantics.scl.compiler.module.ModuleUtils;
 import org.simantics.scl.compiler.source.ModuleSource;
@@ -106,6 +107,7 @@ public class OpenDeclaration extends AbstractHandler {
             SCLTextEditorEnvironment editorEnvironment = moduleEditor.getSCLTextEditorEnvironment();
             editorEnvironment.updateEnvironment(moduleEditor.getDocument());
             SCLValue value = editorEnvironment.getValue(identifierAtCaret);
+            System.out.println("identifierAtCaret = " + identifierAtCaret + " [" + Locations.beginOf(value.definitionLocation) + ", " + Locations.endOf(value.definitionLocation) + "]");
             if(value != null)
                 OpenSCLDefinition.openDefinition(value);
         }
index 100f49e252f68fe6cc8e42b795b12acc0c9bf3b3..05015bb0b36dfeba8cee5afa2b44d3e11bd8d527 100644 (file)
@@ -1,17 +1,35 @@
 package org.simantics.scl.ui.editor2;
 
+import java.text.CharacterIterator;
+
+import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.resource.LocalResourceManager;
 import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.link.LinkedModeModel;
+import org.eclipse.jface.text.link.LinkedPosition;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.contexts.IContextService;
 import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.ui.texteditor.TextNavigationAction;
 import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew;
 import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment;
+import org.simantics.scl.ui.editor2.iterator.DocumentCharacterIterator;
+import org.simantics.scl.ui.editor2.iterator.JavaWordIterator;
+
+import com.ibm.icu.text.BreakIterator;
 
 public class SCLModuleEditor2 extends TextEditor {
     private boolean disposed = false;
@@ -43,6 +61,34 @@ public class SCLModuleEditor2 extends TextEditor {
         updatePartName();
     }
 
+    @Override
+    protected void createNavigationActions() {
+        super.createNavigationActions();
+        
+        // Taken from org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.createNavigationActions()
+        final StyledText textWidget= getSourceViewer().getTextWidget();
+        
+        IAction action = new NavigatePreviousSubWordAction();
+        action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS);
+        setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action);
+        textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL);
+
+        action = new NavigateNextSubWordAction();
+        action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT);
+        setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action);
+        textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL);
+
+        action = new SelectPreviousSubWordAction();
+        action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
+        setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action);
+        textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT, SWT.NULL);
+
+        action = new SelectNextSubWordAction();
+        action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
+        setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action);
+        textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT, SWT.NULL);
+    }
+
     protected void updatePartName() {
         setPartName(getEditorInput().getName());
     }
@@ -66,4 +112,423 @@ public class SCLModuleEditor2 extends TextEditor {
     public IDocument getDocument() {
         return getSourceViewer().getDocument();
     }
+    
+    /**
+     * Text navigation action to navigate to the next sub-word.
+     *
+     * @since 3.0
+     */
+    protected abstract class NextSubWordAction extends TextNavigationAction {
+
+        protected JavaWordIterator fIterator= new JavaWordIterator();
+
+        /**
+         * Creates a new next sub-word action.
+         *
+         * @param code Action code for the default operation. Must be an action code from @see org.eclipse.swt.custom.ST.
+         */
+        protected NextSubWordAction(int code) {
+            super(getSourceViewer().getTextWidget(), code);
+        }
+
+        /*
+         * @see org.eclipse.jface.action.IAction#run()
+         */
+        @Override
+        public void run() {
+            final ISourceViewer viewer= getSourceViewer();
+            final IDocument document= viewer.getDocument();
+            try {
+                fIterator.setText((CharacterIterator)new DocumentCharacterIterator(document));
+                int position= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
+                if (position == -1)
+                    return;
+
+                int next= findNextPosition(position);
+                if (isBlockSelectionModeEnabled() && document.getLineOfOffset(next) != document.getLineOfOffset(position)) {
+                    super.run(); // may navigate into virtual white space
+                } else if (next != BreakIterator.DONE) {
+                    setCaretPosition(next);
+                    getTextWidget().showSelection();
+                    fireSelectionChanged();
+                }
+            } catch (BadLocationException x) {
+                // ignore
+            }
+        }
+
+        /**
+         * Finds the next position after the given position.
+         *
+         * @param position the current position
+         * @return the next position
+         */
+        protected int findNextPosition(int position) {
+            ISourceViewer viewer= getSourceViewer();
+            int widget= -1;
+            int next= position;
+            while (next != BreakIterator.DONE && widget == -1) { // XXX: optimize
+                next= fIterator.following(next);
+                if (next != BreakIterator.DONE)
+                    widget= modelOffset2WidgetOffset(viewer, next);
+            }
+
+            IDocument document= viewer.getDocument();
+            LinkedModeModel model= LinkedModeModel.getModel(document, position);
+            if (model != null && next != BreakIterator.DONE) {
+                LinkedPosition linkedPosition= model.findPosition(new LinkedPosition(document, position, 0));
+                if (linkedPosition != null) {
+                    int linkedPositionEnd= linkedPosition.getOffset() + linkedPosition.getLength();
+                    if (position != linkedPositionEnd && linkedPositionEnd < next)
+                        next= linkedPositionEnd;
+                } else {
+                    LinkedPosition nextLinkedPosition= model.findPosition(new LinkedPosition(document, next, 0));
+                    if (nextLinkedPosition != null) {
+                        int nextLinkedPositionOffset= nextLinkedPosition.getOffset();
+                        if (position != nextLinkedPositionOffset && nextLinkedPositionOffset < next)
+                            next= nextLinkedPositionOffset;
+                    }
+                }
+            }
+
+            return next;
+        }
+
+        /**
+         * Sets the caret position to the sub-word boundary given with <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);
+            }
+        }
+    }
+
 }
index 4dfa0507ba3094f34f2a11540786a47cd5c14273..cf6bf9a87c6ade46606a2794453891406d19526e 100644 (file)
@@ -23,32 +23,38 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider {
     private SCLSourceViewerConfigurationNew sourceViewer;
     protected AnnotationModel annotationModel = new AnnotationModel();
     
-    public SCLModuleEditor2DocumentProvider(
-            SCLSourceViewerConfigurationNew sourceViewer) {
+    private Object currentElement;
+    private TextualModuleSource currentSource;
+    
+    public SCLModuleEditor2DocumentProvider(SCLSourceViewerConfigurationNew sourceViewer) {
         this.sourceViewer = sourceViewer;
     }
 
-    private static TextualModuleSource toTextualModuleSource(Object input) {
-        if(!(input instanceof SCLModuleEditorInput))
-            return null;
-        ModuleSource source = ((SCLModuleEditorInput)input).getAdapter(ModuleSource.class);
+    private void updateTextualModuleSource(Object input) {
+        if (currentElement != null && currentElement.equals(input))
+            return;
+        currentElement = input;
+        if(!(currentElement instanceof SCLModuleEditorInput))
+            return;
+        
+        ModuleSource source = ((SCLModuleEditorInput)currentElement).getAdapter(ModuleSource.class);
         if(source == null)
-            return null;
+            return;
         if(!(source instanceof TextualModuleSource))
-            return null;
-        return (TextualModuleSource)source;
+            return;
+        currentSource = (TextualModuleSource)source;
     }
     
     @Override
     protected IDocument createDocument(Object element) throws CoreException {
-        TextualModuleSource source = toTextualModuleSource(element);
-        if(source == null)
+        updateTextualModuleSource(element);
+        if(currentSource == null)
             throw new CoreException(
                     new Status(Status.ERROR, "org.simantics.scl.ui", "Source for the SCL module could not be found.")
                     );
         Document document;
         try {
-            document = new Document(source.getSourceText(null));
+            document = new Document(currentSource.getSourceText(null));
         } catch (IOException e) {
             throw new CoreException(
                     new Status(Status.ERROR, "org.simantics.scl.ui", "Reading SCL module failed.", e)
@@ -57,16 +63,25 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider {
         IDocumentPartitioner partitioner = new FastPartitioner(new SCLPartitionScanner(), SCLPartitionScanner.PARTITION_TYPES);
         partitioner.connect(document);
         document.setDocumentPartitioner(partitioner);
-        sourceViewer.updateCompletionAssistModuleName(source.getModuleName());
+        sourceViewer.updateCompletionAssistModuleName(currentSource.getModuleName());
         return document;
     }
     
+    @Override
+    public void changed(Object element) {
+        updateTextualModuleSource(element);
+    }
+    
+    @Override
+    public void aboutToChange(Object element) {
+        super.aboutToChange(element);
+    }
+    
     @Override
     public boolean isModifiable(Object element) {
-        TextualModuleSource source = toTextualModuleSource(element);
-        if(source == null)
+        if(currentSource == null)
             return false;
-        return source.isUpdateable();
+        return currentSource.isUpdateable();
     }
     
     @Override
@@ -84,10 +99,9 @@ public class SCLModuleEditor2DocumentProvider extends AbstractDocumentProvider {
     @Override
     protected void doSaveDocument(IProgressMonitor monitor, Object element,
             IDocument document, boolean overwrite) throws CoreException {
-        TextualModuleSource source = toTextualModuleSource(element);
-        if(source == null)
+        if(currentSource == null)
             return;
-        source.update(document.get());
+        currentSource.update(document.get());
     }
 
     @Override
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/DocumentCharacterIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/DocumentCharacterIterator.java
new file mode 100644 (file)
index 0000000..de12b15
--- /dev/null
@@ -0,0 +1,220 @@
+package org.simantics.scl.ui.editor2.iterator;
+
+import java.text.CharacterIterator;
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+/**
+ * An <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();
+               }
+       }
+}
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaBreakIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaBreakIterator.java
new file mode 100644 (file)
index 0000000..f020878
--- /dev/null
@@ -0,0 +1,431 @@
+package org.simantics.scl.ui.editor2.iterator;
+
+import java.text.CharacterIterator;
+
+import com.ibm.icu.text.BreakIterator;
+
+import org.eclipse.core.runtime.Assert;
+
+
+
+/**
+ * A java break iterator. It returns all breaks, including before and after
+ * whitespace, and it returns all camel case breaks.
+ * <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$
+               }
+       }
+}
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaWordIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/JavaWordIterator.java
new file mode 100644 (file)
index 0000000..403cc9d
--- /dev/null
@@ -0,0 +1,224 @@
+package org.simantics.scl.ui.editor2.iterator;
+
+import java.text.CharacterIterator;
+
+import com.ibm.icu.text.BreakIterator;
+
+import org.eclipse.core.runtime.Assert;
+
+
+
+/**
+ * Breaks java text into word starts, also stops at line start and end. No
+ * direction dependency.
+ *
+ * @since 3.0
+ */
+public class JavaWordIterator extends BreakIterator {
+
+       /**
+        * The underlying java break iterator. It returns all breaks, including
+        * before and after every whitespace.
+        */
+       private JavaBreakIterator fIterator;
+       /** The current index for the stateful operations. */
+       private int fIndex;
+
+       /**
+        * Creates a new word iterator.
+        */
+       public JavaWordIterator() {
+               fIterator= new JavaBreakIterator();
+               first();
+       }
+
+       /*
+        * @see java.text.BreakIterator#first()
+        */
+       @Override
+       public int first() {
+               fIndex= fIterator.first();
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#last()
+        */
+       @Override
+       public int last() {
+               fIndex= fIterator.last();
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#next(int)
+        */
+       @Override
+       public int next(int n) {
+               int next= 0;
+               while (--n > 0 && next != DONE) {
+                       next= next();
+               }
+               return next;
+       }
+
+       /*
+        * @see java.text.BreakIterator#next()
+        */
+       @Override
+       public int next() {
+               fIndex= following(fIndex);
+               return fIndex;
+       }
+
+       /*
+        * @see java.text.BreakIterator#previous()
+        */
+       @Override
+       public int previous() {
+               fIndex= preceding(fIndex);
+               return fIndex;
+       }
+
+
+       /*
+        * @see java.text.BreakIterator#preceding(int)
+        */
+       @Override
+       public int preceding(int offset) {
+               int first= fIterator.preceding(offset);
+               if (isWhitespace(first, offset)) {
+                       int second= fIterator.preceding(first);
+                       if (second != DONE && !isDelimiter(second, first))
+                               return second;
+               }
+               return first;
+       }
+
+       /*
+        * @see java.text.BreakIterator#following(int)
+        */
+       @Override
+       public int following(int offset) {
+               int first= fIterator.following(offset);
+               if (eatFollowingWhitespace(offset, first)) {
+                       int second= fIterator.following(first);
+                       if (isWhitespace(first, second))
+                               return second;
+               }
+               return first;
+       }
+
+       private boolean eatFollowingWhitespace(int offset, int exclusiveEnd) {
+               if (exclusiveEnd == DONE || offset == DONE)
+                       return false;
+
+               if (isWhitespace(offset, exclusiveEnd))
+                       return false;
+               if (isDelimiter(offset, exclusiveEnd))
+                       return false;
+
+               return true;
+       }
+
+       /**
+        * Returns <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);
+       }
+
+}
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/SequenceCharacterIterator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/iterator/SequenceCharacterIterator.java
new file mode 100644 (file)
index 0000000..96520a3
--- /dev/null
@@ -0,0 +1,158 @@
+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();
+               }
+       }
+}
index b4fd1edd8a1c8fdad594ff86e6a6b610f8b5abcb..3e0cc3120bd8c163c62158b4e5f0661ef8e0d74f 100644 (file)
@@ -90,6 +90,8 @@ public class SCLIssuesView extends ViewPart {
                 SCLIssuesTableEntry entry = (SCLIssuesTableEntry)element;
                 return entry.error.severity == ErrorSeverity.ERROR
                         ? imageRegistry.get("error")
+                        : entry.error.severity == ErrorSeverity.IMPORT_ERROR
+                        ? imageRegistry.get("import_error")
                         : imageRegistry.get("warning");
             }
         });
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleAction.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleAction.java
new file mode 100644 (file)
index 0000000..1d70442
--- /dev/null
@@ -0,0 +1,72 @@
+package org.simantics.scl.ui.modulebrowser;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.simantics.scl.ui.Activator;
+
+import gnu.trove.map.hash.THashMap;
+
+public class CreateModuleAction {
+    public static final String PREFIX = "reference:file:/";
+    
+    public static final void createModule(Bundle bundle, String packageName, String moduleName) throws IOException {
+        String bundleLocation = bundle.getLocation();
+        bundleLocation = bundleLocation.substring(PREFIX.length());
+        
+        Path packagePath = Paths.get(bundleLocation).resolve("scl").resolve(packageName);
+        Files.createDirectories(packagePath);
+        Path modulePath = packagePath.resolve(moduleName + ".scl");
+        if(Files.exists(modulePath))
+            return;
+        Files.createFile(modulePath);
+    }
+    
+    public static THashMap<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;
+    }
+}
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleDialog.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleDialog.java
new file mode 100644 (file)
index 0000000..875c9ac
--- /dev/null
@@ -0,0 +1,186 @@
+package org.simantics.scl.ui.modulebrowser;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.framework.Bundle;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.ui.editor2.OpenSCLModule;
+import org.simantics.scl.ui.modulebrowser.PluginSelectionDialog.Entry;
+
+import gnu.trove.map.hash.THashMap;
+
+public class CreateModuleDialog extends Dialog {
+
+    SCLModuleBrowser parentBrowser;
+    
+    String initialPackageName = "";
+    String initialPluginName = "";
+    
+    Text packageName;
+    Text moduleName;
+    Text pluginName;
+    private THashMap<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();
+    }
+}
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleValidator.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/CreateModuleValidator.java
new file mode 100644 (file)
index 0000000..d3236c0
--- /dev/null
@@ -0,0 +1,28 @@
+package org.simantics.scl.ui.modulebrowser;
+
+public class CreateModuleValidator {
+    public static boolean isValidPackageName(String packageName) {
+        if(packageName.isEmpty())
+            return true;
+        for(String part : packageName.split("/", -1))
+            if(!isValidModuleName(part))
+                return false;
+        return true;
+    }
+
+    public static boolean isValidModuleName(String moduleName) {
+        if(moduleName.isEmpty())
+            return false;
+        {
+            char c = moduleName.charAt(0);
+            if(!Character.isLetter(c))
+                return false;
+        }
+        for(int i=1;i<moduleName.length();++i) {
+            char c = moduleName.charAt(i);
+            if(!Character.isLetter(c) && !Character.isDigit(c) && c != '_')
+                return false;
+        }
+        return true;
+    }
+}
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/PluginSelectionDialog.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/modulebrowser/PluginSelectionDialog.java
new file mode 100644 (file)
index 0000000..30e84f8
--- /dev/null
@@ -0,0 +1,133 @@
+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();
+    }
+
+}
index 5e08a55a407958d12c0b1b542307074e018559c2..b175a3e600c14cc69db9c7e1a8e6ea23de1b6048 100644 (file)
@@ -1,13 +1,17 @@
 package org.simantics.scl.ui.modulebrowser;
 
 import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
 import org.eclipse.ui.part.ViewPart;
 import org.simantics.scl.osgi.SCLOsgi;
 import org.simantics.scl.ui.Activator;
@@ -21,6 +25,8 @@ public class SCLModuleBrowser extends ViewPart {
     public void createPartControl(Composite parent) {
         this.content = new SCLModuleTree(parent, SWT.NONE, SCLOsgi.MODULE_REPOSITORY);
         setPartName("SCL Modules");
+        
+        // Opening modules
         content.addDoubleClickListener(new IDoubleClickListener() {
             @Override
             public void doubleClick(DoubleClickEvent event) {
@@ -33,15 +39,41 @@ public class SCLModuleBrowser extends ViewPart {
             }
         });
         
+        // Toolbar
         IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
         toolBarManager.add(new Action("Refresh modules",
                 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/arrow_refresh.png")) {
             @Override
             public void run() {
-                SCLOsgi.MODULE_REPOSITORY.getSourceRepository().checkUpdates();
-                content.recalculateInput();
+                refresh();
+            }
+        });
+        
+        // Context menu
+        MenuManager menuMgr = new MenuManager();
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener() {
+            public void menuAboutToShow(IMenuManager manager) {
+                ModuleNameTreeEntry entry = (ModuleNameTreeEntry)content.getStructuredSelection().getFirstElement();
+                if(!entry.isModule)
+                    manager.add(new Action("New Module...") {
+                        @Override
+                        public void run() {
+                            CreateModuleDialog dialog = new CreateModuleDialog(content.getControl().getShell(), SCLModuleBrowser.this);
+                            dialog.setPackage(entry.fullName);
+                            dialog.open();
+                        }
+                    });
             }
         });
+        Menu menu = menuMgr.createContextMenu(content.getControl());
+        content.getControl().setMenu(menu);
+        getSite().registerContextMenu(menuMgr, content);
+    }
+    
+    public void refresh() {
+        SCLOsgi.MODULE_REPOSITORY.getSourceRepository().checkUpdates();
+        content.recalculateInput();
     }
 
     @Override
index 41125d0a0ad2f086cb90201c05f15c432d8bebcc..827677451ab3d33d067e466f9db829869a3ad8a1 100644 (file)
@@ -81,6 +81,7 @@ public abstract class Experiment implements IExperiment {
             localStateChange();
             for(IExperimentListener listener : listeners.getListeners())
                 listener.stateChanged(newState);
+            EXPERIMENT_STATE_READ.run();
         }
     }
 
index baf3b83de6873a371a5dddc669c9199f7a0f1194..299c7c7964955e4c47b2aa1beab214342ae35c39 100644 (file)
@@ -36,6 +36,16 @@ public class TreeTableCell extends TableCell implements ITreeTableCell {
                this.data = data;
        }
        
+       @Override
+       public int getRowSpan() {
+               throw new IllegalStateException("Row span is not supported in TreeTableCell");
+       }
+       
+       @Override
+       public int getColumnSpan() {
+               throw new IllegalStateException("Column span is not supported in TreeTableCell");
+       }
+       
        public static TreeTableCell createTreeTableCell(String text, Object data, Object font, int parent, int row, int column, boolean editable) {
                return new TreeTableCell(text, data, extractIFont(font), parent, row, column, editable);
        }
index e4f08db102d0645dbfc2ea1acf64fd62e84797d8..283e1b5ddcadd6f836fef90a811ce8392bac97a7 100644 (file)
@@ -7,6 +7,7 @@ import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.PossibleIndexRoot;
 import org.simantics.db.common.request.ResourceRead2;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext;
@@ -62,8 +63,10 @@ abstract public class AbstractCompileStructuralValueRequest extends AbstractExpr
         Layer0 L0 = Layer0.getInstance(graph);
         String valueType = graph.getPossibleRelatedValue(relation, L0.RequiresValueType, Bindings.STRING);
         if(valueType != null) {
+            Resource relationIndexRoot = graph.syncRequest(new PossibleIndexRoot(relation));
+            RuntimeEnvironment relationRuntimeEnvironment = relationIndexRoot != null ? graph.syncRequest(new RuntimeEnvironmentRequest(relationIndexRoot)) : context.runtimeEnvironment;
             try {
-                return Environments.getType(context.runtimeEnvironment.getEnvironment(), valueType);
+                return Environments.getType(relationRuntimeEnvironment.getEnvironment(), valueType);
             } catch (SCLExpressionCompilationException e) {
                 e.printStackTrace();
             }
index a0e60d0b31e2882935a98a802a8bf7f82776757f..bcae4c4805e8f96a48815bc8bb051f9f677af7bf 100644 (file)
@@ -57,6 +57,8 @@ ACTIONS.NewSTSTest
   @MOD.sclAction "createSTSTestAction"
 ACTIONS.RunSTSTest
   @MOD.sclAction "runSTSTestAction"
+ACTIONS.IgnoreSTSTest
+  @MOD.sclAction "ignoreSTSTestAction"
 ACTIONS.NewSTSVariable
   @MOD.sclAction "createSTSVariableAction"
 
@@ -82,6 +84,13 @@ MAC
         VP.ActionContribution.HasNodeType TESTS.STSSuite
         VP.ActionContribution.HasNodeType TESTS.STSTest
         VP.ActionContribution.HasAction ACTIONS.RunSTSTest
+    VP.BrowseContext.HasActionContribution _ : VP.ActionContribution
+        L0.HasLabel "Ignore"
+        VP.ActionContribution.HasImage SILK.control_play
+        VP.ActionContribution.HasCategory VP.EditActionCategory
+        VP.ActionContribution.HasNodeType TESTS.STSSuite
+        VP.ActionContribution.HasNodeType TESTS.STSTest
+        VP.ActionContribution.HasAction ACTIONS.IgnoreSTSTest
     VP.BrowseContext.HasActionContribution _ : VP.ActionContribution
         L0.HasLabel "STS Variable"
         VP.ActionContribution.HasImage SILK.page_white_edit
index 53218224a089feac163ae5e475d245afe05a25e2..0b99fe784fa2239470ef3f93f80b59f5e2ae6bcf 100644 (file)
@@ -7,6 +7,7 @@ createSTSTestAction res = do
 
 importJava "org.simantics.tests.modelled.ui.TestsUIUtils" where
     runSTSTestAction :: Resource -> <Proc> ()
+    ignoreSTSTestAction :: [Resource] -> <Proc> ()
     
 createSTSSuiteAction :: Resource -> <Proc> ()
 createSTSSuiteAction res = do
index 651ee47df7282751f3e891b11dcce3e5588b2caa..b24f445e23c985e317f652f628e435a0135a3b53 100644 (file)
@@ -1,10 +1,16 @@
 package org.simantics.tests.modelled.ui;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
 import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Write;
+import org.simantics.tests.modelled.ontology.TestsResource;
 import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
 
 public class TestsUIUtils {
@@ -20,4 +26,17 @@ public class TestsUIUtils {
         view.currentTest(test);
         view.execute();
     }
+    
+    public static void ignoreSTSTestAction(List<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);
+                }
+            }
+        });
+    }
 }
index e1eb08baf0321c200af4d79b06034ceb5b4469b3..78964403f95057464a929d8ea81e0622dea54a8b 100644 (file)
@@ -11,9 +11,9 @@ import java.util.Set;
 
 import org.simantics.scl.compiler.commands.CommandSession;
 import org.simantics.scl.compiler.commands.TestScriptExecutor;
+import org.simantics.scl.compiler.elaboration.java.Builtins;
+import org.simantics.scl.compiler.elaboration.java.JavaModule;
 import org.simantics.scl.compiler.module.coverage.CombinedCoverage;
-import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
-import org.simantics.scl.compiler.module.options.ModuleCompilationOptionsAdvisor;
 import org.simantics.scl.compiler.module.repository.ModuleRepository;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
@@ -99,7 +99,8 @@ public class ModelledSTSTest {
     }
     
     public List<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() {
@@ -116,7 +117,7 @@ public class ModelledSTSTest {
 //    //                    }
 //    //                }
 //                    return new ModuleCompilationOptions(coverage);
-//                }
+    //                    }
 //            });
             
             SCLReportingHandler handler = (SCLReportingHandler) SCLContext.getCurrent().get(SCLReportingHandler.REPORTING_HANDLER);
@@ -139,7 +140,9 @@ public class ModelledSTSTest {
             return result;
         } finally {
             // remember to flush this repository
-            repo.flush();
+//            repo.flush();
+            Builtins.flush();
+            JavaModule.flush();
         }
     }
 
index 3c1888a0112c2c2f382e82c05915372ce51d440d..6d7daeb3c6ff191f8e04e444240bf99776f699d3 100644 (file)
@@ -5,6 +5,7 @@ import java.util.Map;
 
 import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
 import org.eclipse.e4.ui.model.application.ui.MUIElement;
 import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
 import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
@@ -14,9 +15,12 @@ import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
 import org.eclipse.e4.ui.workbench.modeling.EModelService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
+import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
 import org.simantics.db.Resource;
 import org.simantics.utils.datastructures.ArrayMap;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
 
 /**
  * @author Tuukka Lehtonen
@@ -166,5 +170,32 @@ public class E4WorkbenchUtils {
             part = partService.createPart(partId);
         return part;
     }
+    
+    public static MCommand getMCommandById(String id) {
+        IEclipseContext context = PlatformUI.getWorkbench().getService(IEclipseContext.class);
+        MApplication application = context.get(MApplication.class);
+        for (MCommand command : application.getCommands()) {
+            if (id.equals(command.getElementId())) {
+                return command;
+            }
+        }
+        return null;
+    }
 
+    @SuppressWarnings("restriction")
+    public static IEditorPart getActiveIEditorPart(MPart mActiveEditorPart) {
+        // TODO: Fix this when we get rid of CompatibilityEditors
+        IEditorPart activeEditor = null;
+        if (mActiveEditorPart != null) {
+            Object editor = mActiveEditorPart.getObject();
+            if (editor instanceof CompatibilityEditor) {
+                CompatibilityEditor compEditor = (CompatibilityEditor) editor;
+                activeEditor = compEditor.getEditor();
+            } else {
+                // TODO: This is not good practice with E4 but an OK fallback for now
+                activeEditor = WorkbenchUtils.getActiveEditor();
+            }
+        }
+        return activeEditor;
+    }
 }
index 1eb13238fad88dc387fa517b4940f066e5ac1ffe..4f297e417e744faf85b3a0f9a590a3fcb8698a6c 100644 (file)
@@ -35,3 +35,9 @@ VP.InstanceOfTest <T VP.Test
 
 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()."
index 5c8f6fd1d9d236980f96d055fb245ae923a56d7c..c0ee33b4ef2f2ad106edabb6d6a0152686bfe504 100644 (file)
@@ -227,4 +227,18 @@ This Agreement is governed by the laws of the State of New York and the intellec
          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>
index 5ba3531700876746a268d18254b592aaa5932a7a..4cf2114432f0d0f3aa35728255e7de5dfb59198e 100644 (file)
@@ -13,7 +13,7 @@
 <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">
index 17c7d28f45016120cb6736611260a8f2e648e55a..aaccfc9152e0da5fdae61f9e56275cee47dac70e 100644 (file)
@@ -332,7 +332,7 @@ img {
 <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
@@ -478,7 +478,7 @@ refs #yyyy
 <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://&lt;user&gt;@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 &quot;Simantics x.y.z[.w] simultaneous release&quot;\r
 git push origin --tags\r
@@ -556,15 +556,15 @@ separate Mediawiki installation.</p>
 </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 &quot;newsletter&quot; 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/&lt;news number&gt;\r
 for the release news.\r
@@ -583,6 +583,9 @@ Insert some general thoughts on the release...
 <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
@@ -590,12 +593,7 @@ Insert some general thoughts on the release...
 </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
index 79359efd215e1346ee9624f7192c4708960ad86a..871b1d0aa3eb0b56069ee1be66033d91bdec3b03 100644 (file)
@@ -36,7 +36,7 @@ Plug-in components that are part of the release train:
 * Simantics R - [simantics/r.git](https://www.simantics.org:8088/r/gitweb?p=simantics/r.git;a=summary)
 * FMIL - [simantics/fmil.git](https://www.simantics.org:8088/r/gitweb?p=simantics/fmil.git;a=summary)
 * FMI Studio - [members/fmi.git](https://www.simantics.org:8088/r/gitweb?p=members/fmi.git;a=summary)
-* Simupedia - [Members SVN](https://www.simantics.org/svn/members/simupedia)
+* Simupedia - [members/simupedia.git](https://www.simantics.org:8088/r/gitweb?p=members/simupedia.git;a=summary)
 
 For simplicity, each of these components are versioned accoring to platform versioning, i.e. for Platform SDK 1.26.0 there will be Simantics Desktop 1.26.0, Sysdyn 1.26.0, and so on.
 
@@ -246,8 +246,8 @@ separate Mediawiki installation.
 
 ## Disseminate information about the release
 
-* [Developer Wiki](http://dev.simantics.org): Update roadmap at http://dev.simantics.org/index.php/Roadmap
-* [Redmine](https://www.simantics.org/redmine/): Post news on the developer/user-visible changes here.
+* [Developer Wiki](http://dev.simantics.org): Update roadmap at [http://dev.simantics.org/index.php/Roadmap](http://dev.simantics.org/index.php/Roadmap)
+* [Redmine](https://www.simantics.org/redmine/): Post news on the developer/user-visible changes here
 * [simantics.org](https://www.simantics.org): Post news on the release and a link to the redmine post
 * [Members Wiki](https://www.simantics.org/members/): Update frame plan to reflect the realized dates and link to Redmine news
 * [mailto:simantics-developers@simantics.org](mailto:simantics-developers@simantics.org) Send "newsletter" to `simantics-developers@simantics.org:
@@ -278,11 +278,11 @@ Insert some general thoughts on the release...
 
 # TODO
 
-* Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release
-  * Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio
+* Start using [https://github.com/mbarbero/fr.obeo.releng.targetplatform](https://github.com/mbarbero/fr.obeo.releng.targetplatform) to generate `.target` files. `.tpd` files allow specifying version ranges instead of specific versions.
 
 
-* Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK
+* Create a parametrized release train pipeline build in Jenkins that creates all artifacts of a simantics release
+  * Desktop, Sysdyn, R, Simupedia, FMIL, FMI Studio
 
-* Start using https://github.com/mbarbero/fr.obeo.releng.targetplatform to generate `.target` files. `.tpd` files allow specifying version ranges instead of specific versions.
 
+* Incorporate tutorial code in the platform repository as a separate folder to allow platform builds to directly ensure that the tutorial code still builds OK
\ No newline at end of file
index 888bb1e27dc312da40f818e470fd99800e1bf1cb..d99e6fd4f7d0042bfe11fda3f96205d5ad2a5a29 100644 (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"/>
index a3cefa4bb364a322ff2d19385fc019d10b51a04d..1fc2f710c93d74c12178e41b8ecabf2315e2a1e2 100644 (file)
@@ -148,6 +148,8 @@ location "http://www.simantics.org/download/private/eclipse-4.7/external-compone
        com.fasterxml.jackson.core.jackson-annotations.source
        com.fasterxml.jackson.core.jackson-core
        com.fasterxml.jackson.core.jackson-core.source
+       com.fasterxml.jackson.core.jackson-databind
+       com.fasterxml.jackson.core.jackson-databind.source
        com.fasterxml.jackson.dataformat.jackson-dataformat-csv
        com.fasterxml.jackson.dataformat.jackson-dataformat-csv.source
        com.fasterxml.jackson.dataformat.jackson-dataformat-xml
index 356d4c2c3631d7f2f32df1da4c59a071aee47921..9290a8b823146ddba33cea736563fa5c9fb6b05c 100644 (file)
@@ -1,4 +1,4 @@
-<?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>
index a72cb5e12af374e2baae37acce5d31dbca24d048..683a1e5801d9e31ca579f8d20abdf1e6bad3bfe7 100644 (file)
@@ -2,7 +2,7 @@
        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>
index d9294497584b063dc98c5e9af77e659dc5e64b42..29d0e553342d0aa69d038cbfb3a3ca3c7ec0767a 100644 (file)
@@ -1,7 +1,7 @@
 # required metadata
 sonar.projectKey=simantics-platform-sdk
 sonar.projectName=Simantics Platform SDK
-sonar.projectVersion=1.25
+sonar.projectVersion=1.30
 
 # path to source directories (required)
 sonar.sources=bundles
@@ -20,4 +20,4 @@ sonar.sources=bundles
 #sonar.language=cobol
 
 # Additional parameters
-#sonar.my.property=value
\ No newline at end of file
+#sonar.my.property=value
similarity index 98%
rename from tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakTest.java
rename to tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/MemoryLeakExperiment.java
index 7ff61a83e8bf597f1319c062749d77922fcfebcd..76cd51e900923c88917cd61d2ac1dde235f72646 100644 (file)
@@ -14,7 +14,7 @@ import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
-public class MemoryLeakTest {
+public class MemoryLeakExperiment {
     ModuleRepository moduleRepository;
 
     EnvironmentSpecification environmentSpecification;
index a5975932b2fdc142ab952229c29f93c9ade7c7bf..cf3aa021b44981dddb463588e46b0bc5cfeb0b46 100644 (file)
@@ -32,6 +32,12 @@ public class ModuleRegressionTests extends TestBase {
     @Test public void CHR8() { test(); }
     @Test public void CHR9() { test(); }
     @Test public void CHR10() { test(); }
+    @Test public void CHR11() { test(); }
+    @Test public void CHR12() { test(); }
+    @Test public void CHR13() { test(); }
+    @Test public void CHRSelect1() { test(); }
+    @Test public void CHRSelect2() { test(); }
+    @Test public void CHRSelect3() { test(); }
     @Test public void ClosureRecursion() { test(); }
     @Test public void Collaz() { test(); }
     @Test public void Compose() { test(); }
@@ -45,7 +51,8 @@ public class ModuleRegressionTests extends TestBase {
     @Test public void DifferentBranchTypes() { test(); }
     @Test public void Div() { test(); }
     @Test public void DoubleConversion() { test(); }
-    @Test public void DoubleEffect() { test(); }    
+    @Test public void DoubleEffect() { test(); }
+    @Test public void Dynamic1() { test(); }
     @Test public void Effects1() { test(); }
     @Test public void Effects2() { test(); }  
     @Test public void Effects3() { test(); }
@@ -201,13 +208,14 @@ public class ModuleRegressionTests extends TestBase {
     @Test public void Record1() { test(); }
     @Test public void Record2() { test(); }
     @Test public void RecordShorthand() { test(); }
+    @Test public void RecursionBug() { test(); }
     @Test public void RecursiveContext() { test(); }
     @Test public void RecursiveValues2() { test(); }
     @Test public void RecursiveValues3() { test(); }
     @Test public void RecursiveValues4() { test(); }
     @Test public void RedBlackTrees() { test(); }
     @Test public void Relations1() { test(); }
-    @Test public void Relations2() { test(); }    
+    @Test public void Relations2() { test(); }
     @Test public void RepeatedVariableInPattern() { test(); }
     @Test public void Scanl() { test(); }
     @Test public void Search() { test(); }
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSessionWithModules.java
new file mode 100644 (file)
index 0000000..9e8c14e
--- /dev/null
@@ -0,0 +1,31 @@
+package org.simantics.scl.compiler.tests;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.simantics.scl.compiler.commands.CommandSessionWithModules;
+import org.simantics.scl.osgi.SCLOsgi;
+
+public class TestCommandSessionWithModules {
+    @Test
+    public void testCommandSessionWithModules() {
+        CommandSessionWithModules session = new CommandSessionWithModules(SCLOsgi.MODULE_REPOSITORY);
+        session.putModule("My/Test/Module", "someValue = 13");
+        
+        {
+            StringWriter writer = new StringWriter();
+            session.runCommands(new StringReader("import \"My/Test/Module\"\nsomeValue"), writer);
+            Assert.assertEquals("13\n", writer.toString());
+        }
+        
+        session.putModule("My/Test/Module", "someValue = 14");
+        
+        {
+            StringWriter writer = new StringWriter();
+            session.runCommands(new StringReader("someValue\nsomeValue+1"), writer);
+            Assert.assertEquals("14\n15\n", writer.toString());
+        }
+    }
+}
index ff0c799ed54fe9515dfee863ae7cdc651d94d0b0..7644afe0594081896be67f2e1a4b14b01485ef9e 100644 (file)
@@ -7,6 +7,7 @@ import java.io.StringReader;
 import java.nio.charset.Charset;
 
 import org.junit.Test;
+import org.simantics.scl.compiler.markdown.html.HtmlGenerationContext;
 import org.simantics.scl.compiler.markdown.internal.MarkdownParser;
 import org.simantics.scl.compiler.markdown.nodes.Node;
 
@@ -77,10 +78,12 @@ public class MarkdownTests {
     }
 
     public static int test(int id, String in, String out) throws IOException {
+        if(in.contains("\u2192"))
+            return SKIPPED;
         MarkdownParser parser = new MarkdownParser();
         Node node = parser.parseDocument(new StringReader(in.replace('\u2192', '\t')));
         
-        String result = node.toHtml().replace('\t', '\u2192');
+        String result = node.toHtml(HtmlGenerationContext.TEST_DEFAULT).replace('\t', '\u2192');
                 
         boolean passed = result.equals(out);
         
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR11.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR11.scl
new file mode 100644 (file)
index 0000000..3ba991e
--- /dev/null
@@ -0,0 +1,26 @@
+module { export = [main], features = [chr] }
+import "Prelude"
+
+ruleset Foo where
+    constraint Foo Integer
+
+main = ()
+  where
+    foo = createFoo
+    include Foo foo
+    
+    when Foo ?x
+    then print ?x
+    
+    when True
+    then Foo 2
+    
+    when Foo ?x
+         ?x < 5
+    then Foo (?x + 1)
+--
+2
+3
+4
+5
+()
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR12.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR12.scl
new file mode 100644 (file)
index 0000000..7c9376d
--- /dev/null
@@ -0,0 +1,15 @@
+module { export = [main], features = [chr] }
+import "Prelude"
+
+main = ()
+  where
+    when Foo ?x ?x
+    then print (?x :: Integer)
+    
+    when True
+    then Foo 1 2
+         Foo 2 1
+         Foo 2 2
+--
+2
+()
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR13.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR13.scl
new file mode 100644 (file)
index 0000000..597c001
--- /dev/null
@@ -0,0 +1,16 @@
+module { export = [main], features = [chr] }
+import "Prelude"
+
+main = ()
+  where
+    when Foo ?x
+    then y = ?x + 1 :: Integer
+         print y
+    
+    when True
+    then Foo 1
+         Foo 2
+--
+3
+2
+()
\ No newline at end of file
index 1d8451439ee92b8b9d6cb680ffd92cbb67fa9ca2..98c3a4338aa639a517366f15532096f3490321d5 100644 (file)
@@ -6,5 +6,4 @@ main = ()
     A ?x, not A (?x+1) => A (?x-1)
     True => A 0
 --
-0
-()
\ No newline at end of file
+6:11-6:23: CHR negation is not yet supported.
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect1.scl
new file mode 100644 (file)
index 0000000..63ea561
--- /dev/null
@@ -0,0 +1,10 @@
+module {
+    features = [chr]
+}
+import "StandardLibrary"
+
+main = select (?a,?b) where
+    ?a <- [1,2,3]
+    ?b <- [2,3,4]
+--
+[(1,2), (1,3), (1,4), (2,2), (2,3), (2,4), (3,2), (3,3), (3,4)]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect2.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect2.scl
new file mode 100644 (file)
index 0000000..e49dd44
--- /dev/null
@@ -0,0 +1,17 @@
+module {
+    features = [chr]
+}
+import "StandardLibrary"
+
+main = 
+    select (?a,?b) where
+        Foo ?a
+        Bar ?b
+  where
+    True => Foo 1
+    True => Foo 2
+    
+    True => Bar 3
+    True => Bar 4
+--
+[(2,4), (2,3), (1,4), (1,3)]
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect3.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHRSelect3.scl
new file mode 100644 (file)
index 0000000..2be9b98
--- /dev/null
@@ -0,0 +1,21 @@
+module {
+    features = [chr]
+}
+import "StandardLibrary"
+
+main = ()
+  where
+    constraint Edge Integer Integer
+  
+    True => Edge 2 3
+    True => Edge 1 2
+    True => Edge 3 4
+    
+    when -Edge ?x ?y
+         [] = select ?z where
+             Edge ?z ?x
+    then print "removed \(?x) \(?y)"
+--
+removed 1 2
+removed 2 3
+()
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Dynamic1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Dynamic1.scl
new file mode 100644 (file)
index 0000000..ca32ea4
--- /dev/null
@@ -0,0 +1,13 @@
+import "Prelude"
+
+myShow :: Dynamic -> String
+myShow (Dynamic v) = show (v :: Integer)
+myShow (Dynamic v) = show (v :: Double)
+myShow (Dynamic v) = show (v :: String)
+myShow (Dynamic v) = show (v :: Boolean)
+myShow (Dynamic v) = "[\(intercalate ", " $ map myShow v)]"
+myShow _ = "Unknown"
+
+main = myShow $ Dynamic [Dynamic False, Dynamic (3 :: Integer), Dynamic (3.1 :: Double), Dynamic "Foo"]
+--
+[False, 3, 3.1, "Foo"]
\ No newline at end of file
index 95d8b03dab09dfae641969b8a7be876a11d35132..3cf6ed74bb4ac610d1419cff486ce21484c987c2 100644 (file)
@@ -1,4 +1,4 @@
 
 main = \ /* no parameters */ -> 3
 --
-2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION.
\ No newline at end of file
+2:30-2:32: Unexpected token '->' (ARROW). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, CHR_SELECT, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION.
\ No newline at end of file
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursionBug.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/RecursionBug.scl
new file mode 100644 (file)
index 0000000..3a6ab24
--- /dev/null
@@ -0,0 +1,16 @@
+module {
+    export = [main]
+}
+
+import "Prelude"
+
+data Path = EmptyPath | ConsPath String Path
+
+showR :: Path -> String
+showR EmptyPath = "@"
+showR (ConsPath h EmptyPath) = h
+showR (ConsPath h t) = "\(h)-\(showR t)"
+
+main = "Hello world!"
+--
+Hello world!
\ No newline at end of file
index 85637b16be7595d0d13159799e3c81da0a518a29..45f6b08535b78369c8827930ed488946ad7c32bd 100644 (file)
@@ -1,4 +1,4 @@
 a = =
 b = 4
 --
-1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION.
\ No newline at end of file
+1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, CHR_SELECT, DO, ENFORCE, EQ, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LAMBDA_MATCH, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION.
\ No newline at end of file