]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
migrated to svn revision 33108
authorHannu Niemistö <hannu.niemisto@iki.fi>
Mon, 15 Aug 2016 09:38:14 +0000 (12:38 +0300)
committerHannu Niemistö <hannu.niemisto@iki.fi>
Mon, 15 Aug 2016 09:38:14 +0000 (12:38 +0300)
310 files changed:
bundles/com.famfamfam.silk/META-INF/MANIFEST.MF
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/genericrelation/DependenciesRelation.java
bundles/org.simantics.db.procore.server.environment/build.properties
bundles/org.simantics.db.procore.server.environment/src/msijni.dll [deleted file]
bundles/org.simantics.db.procore.server.environment/src/msijni64.dll [deleted file]
bundles/org.simantics.db.procore.ui/META-INF/MANIFEST.MF
bundles/org.simantics.db.procore.ui/src/org/simantics/db/procore/ui/ProCoreUserAgent.java
bundles/org.simantics.db.server/build.properties
bundles/org.simantics.diagram.ontology/build.properties
bundles/org.simantics.document.server/build.properties
bundles/org.simantics.layer0/build.properties
bundles/org.simantics.nativemem/.classpath [new file with mode: 0644]
bundles/org.simantics.nativemem/.project [new file with mode: 0644]
bundles/org.simantics.nativemem/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.nativemem/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
bundles/org.simantics.nativemem/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.nativemem/build.properties [new file with mode: 0644]
bundles/org.simantics.nativemem/jna-4.2.1.jar [new file with mode: 0644]
bundles/org.simantics.nativemem/jna-platform-4.2.1.jar [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryCounters.java [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Arch.java [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/OS.java [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi32.java [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi64.java [new file with mode: 0644]
bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Test.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/cojen/classfile/MethodDesc.java
bundles/org.simantics.scl.compiler/src/org/cojen/classfile/TypeDesc.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/ValueToStringConverter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CompilationTimer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/DocumentationGeneration.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/NameExistenceChecks.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/NamespaceOfModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeChecking.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingScheduler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeInferableDefinition.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalBoxedArrayElementConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/LocalVariableConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ClassRef.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.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/contexts/TypeTranslationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TypingContext.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/expressions/ASTExpression.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 [new file with mode: 0644]
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/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/EEntityTypeAnnotation.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/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/ERecord.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/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/GuardedExpressionGroup.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.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/block/GuardStatement.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/java/MinigraphModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/StandardMacroRule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClass.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/TypeClassInstance.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/QConjunction.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QDisjunction.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/QMapping.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/QNegation.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/compilation/ConstraintCollectionContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/DynamicProgrammingOrdering.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/compilation/ExpressionConstraint.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/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/elaboration/rules/TransformationRule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/AbstractLocalEnvironment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/ConcreteEnvironment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/EmptyNamespace.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Environments.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/LocalEnvironment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/Namespace.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceImpl.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/NamespaceSpec.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/environment/filter/NamespaceFilters.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/errors/CompilationErrorFormatter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/LoopAnalysis.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/analysis/StatementBrowser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/optimization/OptimizationMap.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/BoundVar.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw.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/ssa/statements/LetFunctions.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/ClassBuilder.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/CopyContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/PrintingContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SCLContextPreparationStep.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/ModuleWriter.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/deriving/InstanceDerivers.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintEnvironment.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSet.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ConstraintSolver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintSolver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints2/ConstraintStore.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/profiling/BranchPointInjector.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/subsumption/SubSolver.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/transformations/DecomposedRule.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/parsing/declarations/DRuleAst.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/translation/RelationRepository.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeElaborationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/TypeHashCodeContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/HierarchicalDocumentationRef.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/html/SCLDocumentationExtensionNodeHandler.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Entities.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/inlines/Subject.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java
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/internal/Scanner.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/LazyModule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepositories.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/ExpressionClassLoader.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/MutableClassLoader.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeEnvironmentImpl.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/runtime/RuntimeModuleMap.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/ClassModuleSource.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ClassModuleSourceRepository.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/CompositeModuleSourceRepository.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/FileModuleSourceRepository.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/source/repository/ModuleSourceRepository.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/ExpressionInterpretationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLCompilerConfiguration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TApply.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TCon.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TForAll.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TMetaVar.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TPred.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TUnion.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TVar.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Type.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Types.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/kinds/Kinds.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeTree.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ActiveTests.java
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FutureTests.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ModuleRegressionTests.java [moved from bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTestsWithoutPrelude.java with 51% similarity]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTests.java
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTestsWithPrelude.java [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestBase.java
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestClassNaming.java
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestExpressionEvaluator.java
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestTypeDesc.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/UnimplementedTests.java
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable1.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable2.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/InvalidLambda.scl
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Seq.scl [deleted file]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl [new file with mode: 0644]
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/UnexpectedToken.scl
bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/unit/TestNamespaceFilter.java
bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleModuleSource.java
bundles/org.simantics.scl.osgi/src/org/simantics/scl/osgi/internal/BundleTestScriptRunnable.java
bundles/org.simantics.scl.runtime/META-INF/MANIFEST.MF
bundles/org.simantics.scl.runtime/build.properties
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/Lists.java
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/SCLContext.java
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/equations/TestEquationContext.java
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/exceptions/MatchingException.java [new file with mode: 0644]
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/io/SclIO.java
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/minigraph/Minigraph.java
bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/unification/UMapUtils.java
bundles/org.simantics.spreadsheet.ontology/build.properties
bundles/org.simantics.structural.ontology/build.properties
bundles/org.simantics.threadlog/.classpath [new file with mode: 0644]
bundles/org.simantics.threadlog/.project [new file with mode: 0644]
bundles/org.simantics.threadlog/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
bundles/org.simantics.threadlog/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/org.simantics.threadlog/build.properties [new file with mode: 0644]
bundles/org.simantics.threadlog/examples/org/simantics/threadlog/examples/Example1.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/Task.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/ThreadLog.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Interval.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Lane.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogController.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogVisualizer.java [new file with mode: 0644]
bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java [new file with mode: 0644]
bundles/org.simantics.utils.datastructures/build.properties
bundles/pom.xml
bundles/winterwell.markdown/.classpath [new file with mode: 0644]
bundles/winterwell.markdown/.project [new file with mode: 0644]
bundles/winterwell.markdown/META-INF/MANIFEST.MF [new file with mode: 0644]
bundles/winterwell.markdown/build.properties [new file with mode: 0644]
bundles/winterwell.markdown/icons/coffee.png [new file with mode: 0644]
bundles/winterwell.markdown/icons/github-cat_yellow.png [new file with mode: 0644]
bundles/winterwell.markdown/icons/notepad.gif [new file with mode: 0644]
bundles/winterwell.markdown/icons/settings16_yellow.png [new file with mode: 0644]
bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar [new file with mode: 0644]
bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar [new file with mode: 0644]
bundles/winterwell.markdown/lib/winterwell.utils.jar [new file with mode: 0644]
bundles/winterwell.markdown/plugin.xml [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/Activator.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/LogUtil.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/StringMethods.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenGfmView.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenMdView.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/commands/Preferences.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/ActionBarContributor.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/ColorManager.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/ExportHTMLAction.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/FormatAction.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/HeaderRule.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/HeaderWithUnderlineRule.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/LinkRule.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/ListRule.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/MDColorConstants.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/MDConfiguration.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/MDScanner.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/MDTextHover.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownContentOutlinePage.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownEditor.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/PrintAction.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatter.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatterTest.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPage.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPageTest.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/preferences/MarkdownPreferencePage.java [new file with mode: 0644]
bundles/winterwell.markdown/src/winterwell/markdown/views/MarkdownPreview.java [new file with mode: 0644]
features/com.lowagie.text.feature/.gitignore [new file with mode: 0644]
features/com.lowagie.text.feature/.project [new file with mode: 0644]
features/com.lowagie.text.feature/build.properties [new file with mode: 0644]
features/com.lowagie.text.feature/feature.xml [new file with mode: 0644]
features/org.apache.lucene4.feature/.gitignore [new file with mode: 0644]
features/org.apache.lucene4.feature/.project [new file with mode: 0644]
features/org.apache.lucene4.feature/build.properties [new file with mode: 0644]
features/org.apache.lucene4.feature/feature.xml [new file with mode: 0644]
features/org.simantics.eclipsec.launcher.feature/.project [new file with mode: 0644]
features/org.simantics.eclipsec.launcher.feature/build.properties [new file with mode: 0644]
features/org.simantics.eclipsec.launcher.feature/feature.xml [new file with mode: 0644]
features/org.simantics.sdk.feature/feature.xml
features/org.simantics.ui.workbench.feature/feature.xml
features/pom.xml

index ed8297e4c8a67efab07ea87dd58cd0c6ec5a0192..7f1d30dab8aa875ed58fd48c4ba6fd902aee756c 100644 (file)
@@ -2,5 +2,5 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Silk icon set
 Bundle-SymbolicName: com.famfamfam.silk
-Bundle-Version: 1.3
+Bundle-Version: 1.3.0
 Bundle-Vendor: Semantum Oy
index 965ca6ee489131e437448c54f40adce09167e012..d3c44903b3c05235c41e3c40ec357b064fdf1008 100644 (file)
@@ -405,10 +405,10 @@ public class DependenciesRelation extends UnsupportedRelation implements Generic
                                            if (parent != null) {\r
                                                _additions.add(new Object[] { ss.getRandomAccessId(parent), ss.getRandomAccessId(entry.component), name, types, id != null ? id.indexString() : "" });\r
                                            } else {\r
-                                                   System.err.println("resource " + entry.component + ": no parent for entry " + name + " " + types);\r
+                                                   //System.err.println("resource " + entry.component + ": no parent for entry " + name + " " + types);\r
                                            }\r
                                        } else {\r
-                                           System.err.println("resource " + entry.component + ": " + name + " " + types);\r
+                                           //System.err.println("resource " + entry.component + ": " + name + " " + types);\r
                                        }\r
                                    } else if(_entry instanceof ComponentModification) {\r
                                        ComponentModification entry = (ComponentModification)_entry;\r
index 6425a96133e072c749e7f7fccf374b9f52ac6a76..93557d6946ccc24a4e5cf264c860dc50e49c55ca 100644 (file)
@@ -13,8 +13,8 @@ source.. = src/
 output.. = bin/\r
 bin.includes = META-INF/,\\r
                .,\\r
-               bin/msijni.dll,\\r
-               bin/msijni64.dll,\\r
+               msijni.dll,\\r
+               msijni64.dll,\\r
                VC90.2008.SP1.KB2467174.redist.x64.exe,\\r
                VC90.2008.SP1.KB2467174.redist.x86.exe\r
 src.includes = native/\r
diff --git a/bundles/org.simantics.db.procore.server.environment/src/msijni.dll b/bundles/org.simantics.db.procore.server.environment/src/msijni.dll
deleted file mode 100644 (file)
index 8009884..0000000
Binary files a/bundles/org.simantics.db.procore.server.environment/src/msijni.dll and /dev/null differ
diff --git a/bundles/org.simantics.db.procore.server.environment/src/msijni64.dll b/bundles/org.simantics.db.procore.server.environment/src/msijni64.dll
deleted file mode 100644 (file)
index df74979..0000000
Binary files a/bundles/org.simantics.db.procore.server.environment/src/msijni64.dll and /dev/null differ
index 3965148e3a336a15f09587ae679d87530eba9930..f16e9813766a35fcd760545d0aae81211f33a8ad 100644 (file)
@@ -9,14 +9,13 @@ Bundle-Activator: org.simantics.db.procore.ui.internal.Activator
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.simantics.db.procore.ui
 Import-Package: 
- org.osgi.framework;version="1.3.0",
+ org.eclipse.core.runtime,
  org.eclipse.jface.dialogs,
  org.eclipse.jface.operation,
- org.eclipse.core.runtime,
  org.eclipse.swt.widgets,
- org.eclipse.ui,
+ org.osgi.framework;version="1.3.0",
  org.simantics.db,
- org.simantics.db.exception,
  org.simantics.db.common.utils,
+ org.simantics.db.exception,
  org.simantics.db.server;visibility:=reexport
 Require-Bundle: org.simantics.db.procore;bundle-version="1.2.1"
index dc93b2f9d9a45918a546a42383fa396523104422..54b892070e70e4e0c28f534fe3ec98e5e13018eb 100644 (file)
@@ -2,28 +2,21 @@ package org.simantics.db.procore.ui;
 \r
 import org.eclipse.swt.widgets.Display;\r
 import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.ui.IWorkbench;\r
-import org.eclipse.ui.IWorkbenchWindow;\r
 import org.simantics.db.DatabaseUserAgent;\r
 import org.simantics.db.exception.InternalException;\r
 import org.simantics.db.procore.ProCoreDriver;\r
 \r
 public final class ProCoreUserAgent implements DatabaseUserAgent {\r
-    private static Shell getShell(IWorkbench workbench) {\r
-        IWorkbenchWindow wbw = workbench.getActiveWorkbenchWindow();\r
+    private static Shell getShell() {\r
         Shell shell = null;\r
-        if (null != wbw) {\r
-            shell = wbw.getShell();\r
-        } else {\r
-            Display d = getDisplay();\r
-            if (d == null)\r
-                return null;\r
-            shell = d.getActiveShell();\r
-            if (null == shell) {\r
-                Shell[] shells = d.getShells();\r
-                if (null != shells && shells.length > 0)\r
-                    shell = shells[0];\r
-            }\r
+        Display d = getDisplay();\r
+        if (d == null)\r
+            return null;\r
+        shell = d.getActiveShell();\r
+        if (null == shell) {\r
+            Shell[] shells = d.getShells();\r
+            if (null != shells && shells.length > 0)\r
+                shell = shells[0];\r
         }\r
         return shell;\r
     }\r
@@ -33,13 +26,6 @@ public final class ProCoreUserAgent implements DatabaseUserAgent {
             d = Display.getDefault();\r
         return d;\r
     }\r
-    private IWorkbench workbench;\r
-    public ProCoreUserAgent(IWorkbench workbench) {\r
-        this.workbench = workbench;\r
-    }\r
-    private Shell getShell() {\r
-        return getShell(workbench);\r
-    }\r
     @Override\r
     public boolean handleStart(InternalException exception) {\r
         Shell shell = getShell();\r
index af1a5578701904d6f61dabb4f79185dc52db1a9e..657c95170833515c3e397e5920b9dce38429e360 100644 (file)
@@ -15,5 +15,4 @@ bin.includes = META-INF/,\
                .,\\r
                win32.x86/,\\r
                win32.x86_64/,\\r
-               linux.x86/,\\r
                linux.x86_64/\r
index 15454c697905796bfa54049ee6db50eb44c686fc..fb164279d32b25779889cf3b7a5500310f85e3ea 100644 (file)
@@ -2,6 +2,5 @@ source.. = src/
 output.. = bin/\r
 bin.includes = META-INF/,\\r
                .,\\r
-               graphs/*.tg,\\r
                graph.tg\r
 src.includes = graph/\r
index 5959d12ac39f99b5e10f143d1c241dcdc6dd6d0f..34f26f88677e827fb40b842f67bd47b7e2136e1d 100644 (file)
@@ -3,7 +3,6 @@ output.. = bin/
 bin.includes = META-INF/,\\r
                .,\\r
                plugin.xml,\\r
-               document.war,\\r
                webdefault.xml,\\r
                scl/,\\r
 src.includes = scl/\r
index 15454c697905796bfa54049ee6db50eb44c686fc..fb164279d32b25779889cf3b7a5500310f85e3ea 100644 (file)
@@ -2,6 +2,5 @@ source.. = src/
 output.. = bin/\r
 bin.includes = META-INF/,\\r
                .,\\r
-               graphs/*.tg,\\r
                graph.tg\r
 src.includes = graph/\r
diff --git a/bundles/org.simantics.nativemem/.classpath b/bundles/org.simantics.nativemem/.classpath
new file mode 100644 (file)
index 0000000..2854214
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry exported="true" kind="lib" path="jna-4.2.1.jar"/>\r
+       <classpathentry kind="lib" path="jna-platform-4.2.1.jar"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.nativemem/.project b/bundles/org.simantics.nativemem/.project
new file mode 100644 (file)
index 0000000..4d55767
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.nativemem</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.nativemem/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.nativemem/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..11f6e46
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7\r
+org.eclipse.jdt.core.compiler.compliance=1.7\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.7\r
diff --git a/bundles/org.simantics.nativemem/.settings/org.eclipse.pde.core.prefs b/bundles/org.simantics.nativemem/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..b7e72d0
--- /dev/null
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1\r
+pluginProject.extensions=false\r
+resolve.requirebundle=false\r
diff --git a/bundles/org.simantics.nativemem/META-INF/MANIFEST.MF b/bundles/org.simantics.nativemem/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..d1de018
--- /dev/null
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Native Memory Tracking
+Bundle-SymbolicName: org.simantics.nativemem
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: Semantum Oy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ClassPath: .,
+ jna-4.2.1.jar,
+ jna-platform-4.2.1.jar
+Export-Package: org.simantics.nativemem
diff --git a/bundles/org.simantics.nativemem/build.properties b/bundles/org.simantics.nativemem/build.properties
new file mode 100644 (file)
index 0000000..07df1f0
--- /dev/null
@@ -0,0 +1,6 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               jna-4.2.1.jar,\\r
+               jna-platform-4.2.1.jar\r
diff --git a/bundles/org.simantics.nativemem/jna-4.2.1.jar b/bundles/org.simantics.nativemem/jna-4.2.1.jar
new file mode 100644 (file)
index 0000000..c21183e
Binary files /dev/null and b/bundles/org.simantics.nativemem/jna-4.2.1.jar differ
diff --git a/bundles/org.simantics.nativemem/jna-platform-4.2.1.jar b/bundles/org.simantics.nativemem/jna-platform-4.2.1.jar
new file mode 100644 (file)
index 0000000..ca6ea47
Binary files /dev/null and b/bundles/org.simantics.nativemem/jna-platform-4.2.1.jar differ
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java
new file mode 100644 (file)
index 0000000..cfccc21
--- /dev/null
@@ -0,0 +1,56 @@
+package org.simantics.nativemem;\r
+\r
+import org.simantics.nativemem.internal.Arch;\r
+import org.simantics.nativemem.internal.OS;\r
+import org.simantics.nativemem.internal.Psapi32;\r
+import org.simantics.nativemem.internal.Psapi64;\r
+\r
+import com.sun.jna.platform.win32.Kernel32;\r
+import com.sun.jna.platform.win32.WinNT.HANDLE;\r
+\r
+\r
+public class NativeMem {\r
+\r
+    /**\r
+     * @param out\r
+     *            the structure to write the result into or <code>null</code> to\r
+     *            create a new structure\r
+     * @return the result structure\r
+     */\r
+    public static ProcessMemoryCounters getMemoryCounters(ProcessMemoryCounters out) {\r
+        if (out == null)\r
+            out = new ProcessMemoryCounters();\r
+\r
+        OS os = OS.calculate();\r
+        Arch arch = Arch.calculate();\r
+        switch (os) {\r
+        case WINDOWS: {\r
+            HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess();\r
+            switch (arch) {\r
+            case X86: {\r
+                Psapi32.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi32.PROCESS_MEMORY_COUNTERS_EX();\r
+                boolean ok = Psapi32.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());\r
+                if (ok)\r
+                    pmem.writeTo(out);\r
+                return out;\r
+            }\r
+\r
+            case X86_64: {\r
+                Psapi64.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi64.PROCESS_MEMORY_COUNTERS_EX();\r
+                boolean ok = Psapi64.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());\r
+                if (ok)\r
+                    pmem.writeTo(out);\r
+                return out;\r
+            }\r
+\r
+            default:\r
+                throw new UnsupportedOperationException("Architecture " + arch + " not supported on operating system " + os);\r
+            }\r
+        }\r
+\r
+        default:\r
+            throw new UnsupportedOperationException("Operating system " + os + " not supported");\r
+        }\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryCounters.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryCounters.java
new file mode 100644 (file)
index 0000000..d2192d3
--- /dev/null
@@ -0,0 +1,54 @@
+package org.simantics.nativemem;\r
+\r
+/**\r
+ * Architecture-independent version of the Windows PsApi PROCESS_MEMORY_COUNTERS\r
+ * structure.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ProcessMemoryCounters {\r
+    public int PageFaultCount;\r
+    public long PeakWorkingSetSize;\r
+    public long WorkingSetSize;\r
+    public long QuotaPeakPagedPoolUsage;\r
+    public long QuotaPagedPoolUsage;\r
+    public long QuotaPeakNonPagedPoolUsage;\r
+    public long QuotaNonPagedPoolUsage;\r
+    public long PagefileUsage;\r
+    public long PeakPagefileUsage;\r
+    public long PrivateUsage;\r
+\r
+    @Override\r
+    public String toString() {\r
+        return "ProcessMemoryCounters [PageFaultCount="\r
+                + PageFaultCount + ", PeakWorkingSetSize=" + PeakWorkingSetSize\r
+                + ", WorkingSetSize=" + WorkingSetSize\r
+                + ", QuotaPeakPagedPoolUsage=" + QuotaPeakPagedPoolUsage\r
+                + ", QuotaPagedPoolUsage=" + QuotaPagedPoolUsage\r
+                + ", QuotaPeakNonPagedPoolUsage=" + QuotaPeakNonPagedPoolUsage\r
+                + ", QuotaNonPagedPoolUsage=" + QuotaNonPagedPoolUsage\r
+                + ", PagefileUsage=" + PagefileUsage + ", PeakPagefileUsage="\r
+                + PeakPagefileUsage + ", PrivateUsage=" + PrivateUsage + "]";\r
+    }\r
+\r
+    public String toHumanReadableString() {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append("ProcessMemoryCounters [\n\tPageFaultCount             = ").append(PageFaultCount)\r
+        .append(",\n\tPeakWorkingSetSize         = ").append(toMb(PeakWorkingSetSize))\r
+        .append(" MB,\n\tWorkingSetSize             = ").append(toMb(WorkingSetSize))\r
+        .append(" MB,\n\tQuotaPeakPagedPoolUsage    = ").append(toMb(QuotaPeakPagedPoolUsage))\r
+        .append(" MB,\n\tQuotaPagedPoolUsage        = ").append(toMb(QuotaPagedPoolUsage))\r
+        .append(" MB,\n\tQuotaPeakNonPagedPoolUsage = ").append(toMb(QuotaPeakNonPagedPoolUsage))\r
+        .append(" MB,\n\tQuotaNonPagedPoolUsage     = ").append(toMb(QuotaNonPagedPoolUsage))\r
+        .append(" MB,\n\tPagefileUsage              = ").append(toMb(PagefileUsage))\r
+        .append(" MB,\n\tPeakPagefileUsage          = ").append(toMb(PeakPagefileUsage))\r
+        .append(" MB,\n\tPrivateUsage               = ").append(toMb(PrivateUsage))\r
+        .append(" MB]");\r
+        return sb.toString();\r
+    }\r
+\r
+    private double toMb(long bytes) {\r
+        return (double) bytes / 1048576.0;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Arch.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Arch.java
new file mode 100644 (file)
index 0000000..7910f06
--- /dev/null
@@ -0,0 +1,25 @@
+package org.simantics.nativemem.internal;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public enum Arch {\r
+    PPC, PPC_64, SPARC, X86, X86_64, UNKNOWN;\r
+\r
+    public static Arch calculate() {\r
+        String osArch = System.getProperty("os.arch");\r
+        assert osArch != null;\r
+        osArch = osArch.toLowerCase();\r
+        if (osArch.equals("i386") || osArch.equals("i586") || osArch.equals("i686") || osArch.equals("x86"))\r
+            return X86;\r
+        if (osArch.startsWith("amd64") || osArch.startsWith("x86_64"))\r
+            return X86_64;\r
+        if (osArch.equals("ppc"))\r
+            return PPC;\r
+        if (osArch.startsWith("ppc"))\r
+            return PPC_64;\r
+        if (osArch.startsWith("sparc"))\r
+            return SPARC;\r
+        return UNKNOWN;\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/OS.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/OS.java
new file mode 100644 (file)
index 0000000..a1d0a48
--- /dev/null
@@ -0,0 +1,20 @@
+package org.simantics.nativemem.internal;\r
+\r
+public enum OS {\r
+    APPLE, LINUX, SUN, WINDOWS, UNKNOWN;\r
+\r
+    public static OS calculate() {\r
+        String osName = System.getProperty("os.name");\r
+        assert osName != null;\r
+        osName = osName.toLowerCase();\r
+        if (osName.startsWith("mac os x"))\r
+            return APPLE;\r
+        if (osName.startsWith("windows"))\r
+            return WINDOWS;\r
+        if (osName.startsWith("linux"))\r
+            return LINUX;\r
+        if (osName.startsWith("sun"))\r
+            return SUN;\r
+        return UNKNOWN;\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi32.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi32.java
new file mode 100644 (file)
index 0000000..ba302c9
--- /dev/null
@@ -0,0 +1,67 @@
+package org.simantics.nativemem.internal;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.simantics.nativemem.ProcessMemoryCounters;\r
+\r
+import com.sun.jna.Native;\r
+import com.sun.jna.Structure;\r
+import com.sun.jna.platform.win32.WinNT.HANDLE;\r
+import com.sun.jna.win32.StdCallLibrary;\r
+\r
+public interface Psapi32 extends StdCallLibrary {\r
+\r
+    Psapi32 INSTANCE = (Psapi32) Native.loadLibrary("Psapi", Psapi32.class);\r
+\r
+    /*\r
+     * https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874%28v=vs.85%29.aspx\r
+     */\r
+    public static class PROCESS_MEMORY_COUNTERS_EX extends Structure {\r
+        public int cb;\r
+        public int PageFaultCount;\r
+        public int PeakWorkingSetSize;\r
+        public int WorkingSetSize;\r
+        public int QuotaPeakPagedPoolUsage;\r
+        public int QuotaPagedPoolUsage;\r
+        public int QuotaPeakNonPagedPoolUsage;\r
+        public int QuotaNonPagedPoolUsage;\r
+        public int PagefileUsage;\r
+        public int PeakPagefileUsage;\r
+        public int PrivateUsage;\r
+\r
+        @SuppressWarnings("rawtypes")\r
+        @Override\r
+        protected List getFieldOrder() {\r
+            return PROCESS_MEMORY_COUNTERS_EX_FIELDS;\r
+        }\r
+\r
+        static final List<String> PROCESS_MEMORY_COUNTERS_EX_FIELDS = Arrays.asList(new String[] { \r
+                "cb", "PageFaultCount",\r
+                "PeakWorkingSetSize", "WorkingSetSize",\r
+                "QuotaPeakPagedPoolUsage", "QuotaPagedPoolUsage",\r
+                "QuotaPeakNonPagedPoolUsage", "QuotaNonPagedPoolUsage",\r
+                "PagefileUsage", "PeakPagefileUsage", "PrivateUsage"\r
+        });\r
+\r
+        public void writeTo(ProcessMemoryCounters to) {\r
+            to.PageFaultCount = PageFaultCount;\r
+            to.PeakWorkingSetSize = PeakWorkingSetSize;\r
+            to.WorkingSetSize = WorkingSetSize;\r
+            to.QuotaPeakPagedPoolUsage = QuotaPeakPagedPoolUsage;\r
+            to.QuotaPagedPoolUsage = QuotaPagedPoolUsage;\r
+            to.QuotaPeakNonPagedPoolUsage = QuotaPeakNonPagedPoolUsage;\r
+            to.QuotaNonPagedPoolUsage = QuotaNonPagedPoolUsage;\r
+            to.PagefileUsage = PagefileUsage;\r
+            to.PeakPagefileUsage = PeakPagefileUsage;\r
+            to.PrivateUsage = PrivateUsage;\r
+        }\r
+    }\r
+\r
+    /*\r
+     * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219%28v=vs.85%29.aspx\r
+     */\r
+    boolean GetProcessMemoryInfo(HANDLE Process, PROCESS_MEMORY_COUNTERS_EX ppsmemCounters, int cb);\r
+\r
+\r
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi64.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Psapi64.java
new file mode 100644 (file)
index 0000000..ba58251
--- /dev/null
@@ -0,0 +1,66 @@
+package org.simantics.nativemem.internal;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.simantics.nativemem.ProcessMemoryCounters;\r
+\r
+import com.sun.jna.Native;\r
+import com.sun.jna.Structure;\r
+import com.sun.jna.platform.win32.WinNT.HANDLE;\r
+import com.sun.jna.win32.StdCallLibrary;\r
+\r
+public interface Psapi64 extends StdCallLibrary {\r
+\r
+    Psapi64 INSTANCE = (Psapi64) Native.loadLibrary("Psapi", Psapi64.class);\r
+\r
+    /*\r
+     * https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874%28v=vs.85%29.aspx\r
+     */\r
+    public static class PROCESS_MEMORY_COUNTERS_EX extends Structure {\r
+        public int cb;\r
+        public int PageFaultCount;\r
+        public long PeakWorkingSetSize;\r
+        public long WorkingSetSize;\r
+        public long QuotaPeakPagedPoolUsage;\r
+        public long QuotaPagedPoolUsage;\r
+        public long QuotaPeakNonPagedPoolUsage;\r
+        public long QuotaNonPagedPoolUsage;\r
+        public long PagefileUsage;\r
+        public long PeakPagefileUsage;\r
+        public long PrivateUsage;\r
+\r
+        @SuppressWarnings("rawtypes")\r
+        @Override\r
+        protected List getFieldOrder() {\r
+            return PROCESS_MEMORY_COUNTERS_EX_FIELDS;\r
+        }\r
+\r
+        private static final List<String> PROCESS_MEMORY_COUNTERS_EX_FIELDS = Arrays.asList(new String[] { \r
+                "cb", "PageFaultCount",\r
+                "PeakWorkingSetSize", "WorkingSetSize",\r
+                "QuotaPeakPagedPoolUsage", "QuotaPagedPoolUsage",\r
+                "QuotaPeakNonPagedPoolUsage", "QuotaNonPagedPoolUsage",\r
+                "PagefileUsage", "PeakPagefileUsage", "PrivateUsage"\r
+        });\r
+\r
+        public void writeTo(ProcessMemoryCounters to) {\r
+            to.PageFaultCount = PageFaultCount;\r
+            to.PeakWorkingSetSize = PeakWorkingSetSize;\r
+            to.WorkingSetSize = WorkingSetSize;\r
+            to.QuotaPeakPagedPoolUsage = QuotaPeakPagedPoolUsage;\r
+            to.QuotaPagedPoolUsage = QuotaPagedPoolUsage;\r
+            to.QuotaPeakNonPagedPoolUsage = QuotaPeakNonPagedPoolUsage;\r
+            to.QuotaNonPagedPoolUsage = QuotaNonPagedPoolUsage;\r
+            to.PagefileUsage = PagefileUsage;\r
+            to.PeakPagefileUsage = PeakPagefileUsage;\r
+            to.PrivateUsage = PrivateUsage;\r
+        }\r
+    }\r
+\r
+    /*\r
+     * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219%28v=vs.85%29.aspx\r
+     */\r
+    boolean GetProcessMemoryInfo(HANDLE Process, PROCESS_MEMORY_COUNTERS_EX ppsmemCounters, int cb);\r
+\r
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Test.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Test.java
new file mode 100644 (file)
index 0000000..d00db0c
--- /dev/null
@@ -0,0 +1,13 @@
+package org.simantics.nativemem.internal;\r
+\r
+import org.simantics.nativemem.NativeMem;\r
+import org.simantics.nativemem.ProcessMemoryCounters;\r
+\r
+public class Test {\r
+\r
+    public static void main(String[] args) {\r
+        ProcessMemoryCounters mem = NativeMem.getMemoryCounters(null);\r
+        System.out.println(mem.toHumanReadableString());\r
+    }\r
+\r
+}\r
index e9547699238991920ac5406956cad1e020b85e35..6a751c5b5a1ac1cffbe04c0550989dd1e1de71c1 100644 (file)
 
 package org.cojen.classfile;
 
-import java.io.Serializable;
 import java.io.Externalizable;
-import java.io.ObjectOutput;
-import java.io.ObjectInput;
 import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.io.ObjectStreamException;
+import java.io.Serializable;
 import java.lang.reflect.Method;
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.cojen.util.WeakCanonicalSet;
 
index 084eb3dc85445cef536d561c0eec6cf6d1c2e002..cfc5a1deb0fcf7a303651c39782af93fc6e8742b 100644 (file)
 package org.cojen.classfile;
 
 import java.io.Serializable;
-import java.io.Externalizable;
-import java.io.ObjectOutput;
-import java.io.ObjectInput;
-import java.io.IOException;
-import java.io.ObjectStreamException;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Array;
 import java.util.Collections;
@@ -510,10 +505,6 @@ public abstract class TypeDesc extends Descriptor implements Serializable {
         return false;
     }
 
-    Object writeReplace() throws ObjectStreamException {
-        return new External(mDescriptor);
-    }
-
     private static class PrimitiveType extends TypeDesc {
         private transient final int mCode;
         private transient TypeDesc mArrayType;
@@ -895,27 +886,4 @@ public abstract class TypeDesc extends Descriptor implements Serializable {
             }
         }
     }
-
-    private static class External implements Externalizable {
-        private String mDescriptor;
-
-        public External() {
-        }
-
-        public External(String desc) {
-            mDescriptor = desc;
-        }
-
-        public void writeExternal(ObjectOutput out) throws IOException {
-            out.writeUTF(mDescriptor);
-        }
-
-        public void readExternal(ObjectInput in) throws IOException {
-            mDescriptor = in.readUTF();
-        }
-
-        public Object readResolve() throws ObjectStreamException {
-            return forDescriptor(mDescriptor);
-        }
-    }
 }
index 8ad47b0a093d9b6ebeecc121e603cf4e0ffaa6f7..e463a4e6a4ca420c8308e405c4dc0017dd321d8c 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.commands;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -62,6 +58,10 @@ import org.simantics.scl.runtime.reporting.SCLReporting;
 import org.simantics.scl.runtime.reporting.SCLReportingHandler;
 import org.simantics.scl.runtime.tuple.Tuple0;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
 
 public class CommandSession {
 
index 07ca39015fb4f363f1d1f8484ece89ebbb5fb12f..51d5c456fcaf3e8690a5e9499cf08487fdfad762 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.commands;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
 import org.simantics.scl.compiler.top.ExpressionEvaluator;
 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
@@ -9,6 +7,8 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.runtime.function.Function1;
 
+import gnu.trove.map.hash.THashMap;
+
 public class ValueToStringConverter {
     final RuntimeEnvironment environment;
     final THashMap<Type, Function1> showInstances = new THashMap<Type, Function1>(); 
index 91215886255e02c05d25f7b43835afa2cdb4c29f..0ad3627d89f5337ace03301b0d9e470eddcb4169 100644 (file)
@@ -1,9 +1,9 @@
 package org.simantics.scl.compiler.compilation;\r
 \r
-import gnu.trove.map.hash.TObjectLongHashMap;\r
-\r
 import java.util.ArrayList;\r
 \r
+import gnu.trove.map.hash.TObjectLongHashMap;\r
+\r
 public class CompilationTimer {\r
     private long initialTime, previousTime;\r
     private ArrayList<TimerEntry> entries = new ArrayList<TimerEntry>();\r
index e4124d9b79559a9c862386133d55bff50af14d55..b242431806efc334f6fd463f9dbcaa8eba48a8df 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.compilation;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
@@ -13,6 +10,9 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DDocumentationAs
 import org.simantics.scl.compiler.module.ConcreteModule;
 import org.simantics.scl.compiler.types.TCon;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class DocumentationGeneration {
     THashMap<String, DDocumentationAst> valueDocumentation;
     THashMap<String, DDocumentationAst> typeDocumentation;
index dc3bdc9e852c901acb0b0a360de15aedb15f8cd8..d331283fd76f3ddfd624f65a4fc7c03e288379a5 100644 (file)
@@ -1,7 +1,6 @@
 package org.simantics.scl.compiler.compilation;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
index 8204b5f604bea380e30625f97d8d77af70ebf47a..1f45c5f41a9d88c8345686e70fcd8b4834dd37ff 100644 (file)
@@ -5,22 +5,27 @@ import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
 import org.simantics.scl.compiler.environment.AmbiguousNameException;\r
 import org.simantics.scl.compiler.environment.Environment;\r
 import org.simantics.scl.compiler.errors.ErrorLog;\r
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
 \r
 public class NameExistenceChecks {\r
     public static void checkIfValueExists(ErrorLog errorLog, long location,\r
             Environment environment, String name) {\r
-        try {\r
-            SCLValue value = environment.getLocalNamespace().getValue(name);\r
-            if(value != null)\r
+        if(SCLCompilerConfiguration.ALLOW_OVERLOADING)\r
+            return;\r
+        else {\r
+            try {\r
+                SCLValue value = environment.getLocalNamespace().getValue(name);\r
+                if(value != null)\r
+                    errorLog.log(location,\r
+                            "Value " + name + " is already defined in the module " + \r
+                                    value.getName().module + \r
+                            " that is imported to the default namespace.");\r
+            } catch(AmbiguousNameException e) {\r
                 errorLog.log(location,\r
-                        "Value " + name + " is already defined in the module " + \r
-                                value.getName().module + \r
-                        " that is imported to the default namespace.");\r
-        } catch(AmbiguousNameException e) {\r
-            errorLog.log(location,\r
-                    "Value " + name + " is already defined in the modules " + \r
-                            e.conflictingModules[0] + " and  " + e.conflictingModules[1] +  \r
-                    " that are imported to the default namespace.");\r
+                        "Value " + name + " is already defined in the modules " + \r
+                                e.conflictingModules[0] + " and  " + e.conflictingModules[1] +  \r
+                        " that are imported to the default namespace.");\r
+            }\r
         }\r
     }\r
     \r
index 7b2ee618f5dcf87d2becb248eb49c4e9b8ac6dda..8ade1602e23e730ba4e37227eb5ef09dd861eb7c 100644 (file)
@@ -1,7 +1,6 @@
 package org.simantics.scl.compiler.compilation;
 
-import gnu.trove.procedure.TObjectProcedure;
-
+import java.util.Arrays;
 import java.util.function.Consumer;
 
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
@@ -18,8 +17,11 @@ import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
 import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
 import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.types.TCon;
 
+import gnu.trove.procedure.TObjectProcedure;
+
 public class NamespaceOfModule implements Namespace {
     private final Namespace base;
     private final Module module;
@@ -37,9 +39,30 @@ public class NamespaceOfModule implements Namespace {
     @Override
     public SCLValue getValue(String name) throws AmbiguousNameException {
         SCLValue value = module.getValue(name);
+        if(SCLCompilerConfiguration.ALLOW_OVERLOADING) {
+            SCLValue value2;
+            try {
+                value2 = base.getValue(name);
+            } catch(AmbiguousNameException e) {
+                if(value != null) {
+                    String[] conflictingModules = Arrays.copyOf(e.conflictingModules, e.conflictingModules.length+1);
+                    conflictingModules[e.conflictingModules.length] = module.getName();
+                    throw new AmbiguousNameException(Arrays.asList(conflictingModules), e.name);
+                }
+                else
+                    throw e;
+            }
+            if(value == null)
+                return value2;
+            if(value2 == null)
+                return value;
+            throw new AmbiguousNameException(Arrays.asList(value.getName().module, value2.getName().module), value.getName().name);
+        }
+        else {
         if(value != null)
             return value;
         return base.getValue(name);
+        }
     }
 
     @Override
index 97266d6e9781e16d2c5d77ba4d0107b80f8ee251..554a360811b69b2312151b9c4f8fe503d131c790 100644 (file)
@@ -5,16 +5,13 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.app
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda;
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
 import org.simantics.scl.compiler.elaboration.expressions.ETransformation;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
@@ -42,6 +39,11 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 
+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 TypeChecking {
     final ErrorLog errorLog;
     final Environment environment;
@@ -97,6 +99,8 @@ public class TypeChecking {
                             context.pushEffectUpperBound(expression.location, Types.PROC);
                             expression = expression.checkType(context, value.getType());
                             context.popEffectUpperBound();
+                            for(EAmbiguous overloaded : context.overloadedExpressions)
+                                overloaded.assertResolved(errorLog);
                             value.setExpression(expression);
                             
                             ArrayList<EVariable> constraintDemand = context.getConstraintDemand();
@@ -199,6 +203,7 @@ public class TypeChecking {
                         @Override
                         public void run() {
                             Type type = value.getType();
+
                             Expression expression = value.getExpression();
 
                             try {
@@ -211,6 +216,8 @@ public class TypeChecking {
                                 context.pushEffectUpperBound(expression.location, Types.PROC);
                                 expression = expression.checkType(context, type);
                                 context.popEffectUpperBound();
+                                for(EAmbiguous overloaded : context.overloadedExpressions)
+                                    overloaded.assertResolved(errorLog);
                                 expression.getType().addPolarity(Polarity.POSITIVE);
                                 context.solveSubsumptions(expression.getLocation());
                                 ArrayList<EVariable> demands = context.getConstraintDemand();
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/TypeCheckingOld.java
deleted file mode 100644 (file)
index c5ef573..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-package org.simantics.scl.compiler.compilation;
-
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply;
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.applyTypes;
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.lambda;
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
-import java.util.ArrayList;
-
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
-import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;
-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.modules.SCLValue;
-import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
-import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
-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.constraints.Constraint;
-import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintEnvironment;
-import org.simantics.scl.compiler.internal.elaboration.constraints.ConstraintSolver;
-import org.simantics.scl.compiler.internal.elaboration.constraints.ExpressionAugmentation;
-import org.simantics.scl.compiler.internal.elaboration.constraints.ReducedConstraints;
-import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
-import org.simantics.scl.compiler.module.ConcreteModule;
-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 org.simantics.scl.compiler.types.kinds.Kinds;
-import org.simantics.scl.compiler.types.util.Polarity;
-
-public class TypeCheckingOld {
-    public static final boolean PRINT_VALUES = false;
-    
-    ErrorLog errorLog;
-    Environment environment;
-    ConcreteModule module;
-    
-    ConstraintEnvironment ce;
-    ArrayList<SCLValue[]> valuesWithoutTypeAnnotation = new ArrayList<SCLValue[]>(); 
-    ArrayList<SCLValue> valuesWithTypeAnnotation = new ArrayList<SCLValue>();
-    
-    public TypeCheckingOld(ErrorLog errorLog, Environment environment,
-            ConcreteModule module) {
-        this.errorLog = errorLog;
-        this.environment = environment;
-        this.module = module;
-    }
-    
-    public void typeCheck() {
-        ce = new ConstraintEnvironment(environment);
-        groupValueDefinitionsByDependency();
-        typeCheckValuesWithoutTypeAnnotations();
-        typeCheckValuesWithTypeAnnotations();
-        typeCheckRules();
-    }
-
-    private void groupValueDefinitionsByDependency() {
-        // Collect all untyped names
-        final ArrayList<SCLValue> values = new ArrayList<SCLValue>();
-        for(SCLValue value : module.getValues()) {
-            if(value.getExpression() != null) {
-                if(value.getType() == null)
-                    values.add(value);
-                else
-                    valuesWithTypeAnnotation.add(value);   
-            }            
-        }
-        
-        // Create inverse
-        final TObjectIntHashMap<Object> allRefs = 
-                new TObjectIntHashMap<Object>(values.size()*2, 0.5f, -1);
-        for(int i=0;i<values.size();++i)
-            allRefs.put(values.get(i), i);
-        
-        // Create groups       
-        new StronglyConnectedComponents(values.size()) {
-            
-            TIntHashSet set = new TIntHashSet();
-            
-            @Override
-            protected void reportComponent(int[] component) {
-                SCLValue[] valueComponent = new SCLValue[component.length];
-                for(int i=0;i<component.length;++i)
-                    valueComponent[i] = values.get(component[i]);
-                valuesWithoutTypeAnnotation.add(valueComponent);
-            }
-            
-            @Override
-            protected int[] findDependencies(int u) {
-                Expression expression = values.get(u).getExpression();
-                expression.collectRefs(allRefs, set);
-                
-                int[] result = set.toArray();
-                set.clear();
-                
-                return result;
-            }
-            
-        }.findComponents();
-    }
-    
-    private void typeCheckValuesWithoutTypeAnnotations() {
-        for(SCLValue[] group : valuesWithoutTypeAnnotation) {
-            if(PRINT_VALUES) {
-                System.out.println("---------------------------------------------");
-                System.out.print("---");
-                for(SCLValue value : group)
-                    System.out.print(" " + value.getName());
-                System.out.println();
-            }
-            
-            for(int i=0;i<group.length;++i)
-                group[i].setType(Types.metaVar(Kinds.STAR));
-            
-            TypingContext context = new TypingContext(errorLog, environment);
-            context.recursiveValues = new THashSet<SCLValue>();
-            for(SCLValue value : group)
-                context.recursiveValues.add(value);
-                    
-            @SuppressWarnings("unchecked")
-            ArrayList<EVariable>[] constraintDemands = new ArrayList[group.length];
-            
-            @SuppressWarnings("unchecked")
-            ArrayList<EPlaceholder>[] recursiveReferences = new ArrayList[group.length];
-            for(int i=0;i<group.length;++i) {
-                context.recursiveReferences = new ArrayList<EPlaceholder>();
-                
-                SCLValue value = group[i];
-                Expression expression = value.getExpression();
-                expression = expression.checkType(context, value.getType());
-                value.setExpression(expression);
-                
-                ArrayList<EVariable> constraintDemand = context.getConstraintDemand();
-                if(!constraintDemand.isEmpty()) {
-                    constraintDemands[i] = constraintDemand;
-                    context.resetConstraintDemand();
-                }
-                
-                recursiveReferences[i] = context.recursiveReferences;
-            }
-
-            for(Type type : Types.getTypes(group))
-                type.addPolarity(Polarity.POSITIVE);
-            context.solveSubsumptions(group[0].getExpression().getLocation());
-            ArrayList<Constraint> allUnsolvedConstraints = new ArrayList<Constraint>(); 
-            
-            @SuppressWarnings("unchecked")
-            ArrayList<Variable>[] freeEvidence = new ArrayList[group.length];  
-            for(int i=0;i<group.length;++i) {
-                if(constraintDemands[i] != null) {
-                    SCLValue value = group[i];
-                    Expression expression = value.getExpression();
-                    
-                    ReducedConstraints red = ConstraintSolver.solve(
-                            ce, new ArrayList<TPred>(0), constraintDemands[i],
-                            true /*!Types.isFunction(expression.getType())*/);                                        
-                    
-                    expression = ExpressionAugmentation.augmentSolved(
-                            red.solvedConstraints, 
-                            expression);
-                    value.setExpression(expression);
-                    value.setType(expression.getType());
-                    
-                    for(Constraint c : red.unsolvedConstraints)
-                        if(c.constraint.isGround()) {
-                            errorLog.log(c.getDemandLocation(), "There is no instance for <"+c.constraint+">.");
-                        }          
-                    
-                    ArrayList<Variable> fe = new ArrayList<Variable>(red.unsolvedConstraints.size());
-                    for(Constraint c : red.unsolvedConstraints) {
-                        allUnsolvedConstraints.add(c);
-                        fe.add(c.evidence);
-                    }
-                    freeEvidence[i] = fe;
-                }
-                else {
-                    group[i].setExpression(group[i].getExpression().decomposeMatching());
-                    freeEvidence[i] = new ArrayList<Variable>(0);
-                }
-            }
-
-            THashSet<TVar> varSet = new THashSet<TVar>(); 
-            for(int i=0;i<group.length;++i) {
-                SCLValue value = group[i];
-                Type type = value.getType();
-                type = type.convertMetaVarsToVars();
-                value.setType(type);
-                varSet.addAll(Types.freeVars(type));
-            }
-            
-            TVar[] vars = varSet.toArray(new TVar[varSet.size()]);
-            
-            // Collect all constraints needed in the group
-            THashSet<TPred> constraintSet = new THashSet<TPred>();
-            for(int i=0;i<group.length;++i) {
-                for(Variable evidence : freeEvidence[i]) {
-                    constraintSet.add((TPred)evidence.getType());
-                }
-            }
-            TPred[] constraints = constraintSet.toArray(new TPred[constraintSet.size()]);
-            for(TPred constraint : constraints)
-                if(constraint.containsMetaVars()) {
-                    for(Constraint c : allUnsolvedConstraints) {
-                        if(Types.equals(c.constraint, constraint)) {
-                            errorLog.log(c.getDemandLocation(), 
-                                    "Constrain " + constraint + 
-                                    " contains free variables not mentioned in the type of the value.");
-                            break;
-                        }
-                    }
-                }
-
-
-            // TODO copy to TypeChecking2 from this onwards
-            for(int i=0;i<group.length;++i) {                
-                // Create evidence array of every value in the group that has the variables
-                // in the same array as in the shared array
-                ArrayList<Variable> fe = freeEvidence[i];
-                THashMap<TPred, Variable> indexedEvidence = new THashMap<TPred, Variable>(fe.size());
-                for(Variable v : fe)
-                    indexedEvidence.put((TPred)v.getType(), v);
-                fe.clear();
-                for(TPred c : constraints) {
-                    Variable var = indexedEvidence.get(c);
-                    if(var == null) {
-                        // These are variables that are not directly needed in 
-                        // this definition but in the definitions that are
-                        // recursively called
-                        var = new Variable("evX");
-                        var.setType(c);
-                        fe.add(var);
-                    }
-                    fe.add(var);
-                }
-                
-                // Add evidence parameters to the functions
-                SCLValue value = group[i];
-                value.setExpression(lambda(Types.NO_EFFECTS, fe, value.getExpression())
-                        .closure(vars));
-                value.setType(Types.forAll(vars, 
-                        Types.constrained(constraints, value.getType())));
-                
-                // Add evidence parameters to recursive calls
-                for(EPlaceholder ref : recursiveReferences[i]) {
-                    ref.expression = loc(ref.expression.location, apply(
-                            Types.NO_EFFECTS,
-                            applyTypes(ref.expression, vars),
-                            vars(fe)));
-                }
-            }
-        }
-    }
-    
-    private void typeCheckValuesWithTypeAnnotations() {
-        ArrayList<TPred> givenConstraints = new ArrayList<TPred>();
-        for(SCLValue value : valuesWithTypeAnnotation) {            
-            Type type = value.getType();
-            if(type != null) {
-                if(PRINT_VALUES) {
-                    System.out.println("---------------------------------------------");
-                    System.out.println("--- " + value.getName() + " :: " + type);
-                }
-                Expression expression = value.getExpression();
-                ArrayList<TVar> vars = new ArrayList<TVar>();
-                type = Types.removeForAll(type, vars);                
-                type = Types.removePred(type, givenConstraints);
-                
-                /*System.out.println("---------------------------------------------");
-                TypeUnparsingContext tuc = new TypeUnparsingContext();
-                System.out.println("--- " + value.getName() + " :: " + type.toString(tuc));
-                for(TPred t : givenConstraints)
-                    System.out.println(">>> " + t.toString(tuc));
-                */
-                TypingContext context = new TypingContext(errorLog, environment);
-                //System.out.println(expression);
-                expression = expression.checkType(context, type);
-                //System.out.println(expression);
-                expression.getType().addPolarity(Polarity.POSITIVE);
-                context.solveSubsumptions(expression.getLocation());
-                ArrayList<EVariable> demands = context.getConstraintDemand();
-                if(!demands.isEmpty() || !givenConstraints.isEmpty()) {
-                    ReducedConstraints red = 
-                            ConstraintSolver.solve(ce, givenConstraints, demands, true);    
-                    givenConstraints.clear();
-                    for(Constraint c :  red.unsolvedConstraints) {
-                        errorLog.log(c.getDemandLocation(), 
-                                "Constraint <"+c.constraint+"> is not given and cannot be derived.");
-                    }
-                    if(errorLog.isEmpty()) { // To prevent exceptions
-                        expression = ExpressionAugmentation.augmentSolved(
-                                red.solvedConstraints,
-                                expression);
-                        expression = ExpressionAugmentation.augmentUnsolved(
-                                red.givenConstraints, 
-                                expression); 
-                    }
-                }
-                else {
-                    if(errorLog.isEmpty()) // To prevent exceptions
-                        expression = expression.decomposeMatching();
-                }
-                expression = expression.closure(vars.toArray(new TVar[vars.size()]));
-                value.setExpression(expression);
-            }
-        }
-    }
-
-    public void typeCheckRules() {
-        TypingContext context = new TypingContext(errorLog, environment);
-        for(TransformationRule rule : module.getRules()) {
-            context.pushEffectUpperBound(rule.location, Types.metaVar(Kinds.EFFECT));
-            rule.checkType(context);
-            rule.setEffect(Types.canonical(context.popEffectUpperBound()));
-        }
-        context.solveSubsumptions(Locations.NO_LOCATION);
-        
-        ArrayList<EVariable> demands = context.getConstraintDemand();
-        if(!demands.isEmpty()) {
-            ReducedConstraints red = 
-                    ConstraintSolver.solve(ce, new ArrayList<TPred>(), demands, true);
-            for(Constraint c :  red.unsolvedConstraints) {
-                errorLog.log(c.getDemandLocation(), 
-                        "Constraint <"+c.constraint+"> is not given and cannot be derived.");
-            }
-        }
-        
-        for(MappingRelation mappingRelation : module.getMappingRelations())
-            for(Type parameterType : mappingRelation.parameterTypes)
-                if(!parameterType.isGround()) {
-                    errorLog.log(mappingRelation.location, "Parameter types of the mapping relation are not completely determined.");
-                    break;
-                }
-        
-        /*for(Rule rule : module.getRules()) {
-            System.out.println(rule.name);
-            for(Variable variable : rule.variables)
-                System.out.println("    " + variable.getName() + " :: " + variable.getType());
-        }*/
-    }
-}
index c3fb2dda7076d74f0e9924e8eed00197e950f557..cb6752527605e5dc9c1d659515c2272234cd3aa9 100644 (file)
@@ -1,11 +1,5 @@
 package org.simantics.scl.compiler.compilation;
 
-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;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
@@ -18,6 +12,12 @@ import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedCo
 import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.TVar;
 
+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;
+
 /**
  * Schedules the order of type checking.
  * 
index 34c6c1b85189fca05dff5536f094f4439370bf2c..17b165d7f2312ebf64aba4ffde902426b15b8d22 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.compilation;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint;
 import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.TVar;
 
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
 public interface TypeInferableDefinition {
     long getLocation();
     Collection<Object> getDefinedObjects();
index a26ee9d750dbc3493f3345e6ab1433f5e14c9cc8..b7114a441e57a674de875efa81a529c6aaa5178b 100644 (file)
@@ -1,7 +1,7 @@
 package org.simantics.scl.compiler.constants;
 
-import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
 import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 import org.simantics.scl.compiler.types.Type;
index 782f34e390d475eae7a2c442ffc21f1166ac21f6..7de438d151e57844f05c9c065435870ed6f129c7 100644 (file)
@@ -1,7 +1,7 @@
 package org.simantics.scl.compiler.constants;
 
-import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
 import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 import org.simantics.scl.compiler.types.Type;
index 5686d63400b231afd9de38cc1b647edc962124fc..2ff26cf2dc5d5132259de6b317153af7382f4983 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.constants.generic;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -20,6 +18,8 @@ import org.simantics.scl.compiler.constants.generic.MethodRef.StaticFieldRef;
 import org.simantics.scl.compiler.constants.generic.MethodRef.StaticMethodRef;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
 
+import gnu.trove.map.hash.THashMap;
+
 /**
  * This class is a reference to a Java class that contains a map of MethodRef for each
  * method declared by the referenced class.
index e983e1277e0a93f27ab0964e3083ecf588583531..90e93f3d00a014b6de9d1dc13e5f0bffe05f4ecd 100755 (executable)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.elaboration.contexts;
 
-import gnu.trove.list.array.TLongArrayList;
-import gnu.trove.map.hash.THashMap;
-
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.constants.Constant;
@@ -30,6 +27,9 @@ 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.list.array.TLongArrayList;
+import gnu.trove.map.hash.THashMap;
+
 public class SimplificationContext implements EnvironmentalContext {
     Environment environment;
     ErrorLog errorLog;
index 961fa902b9db552469b998f2e30e8255f806dcc1..b5f9f93e942cb17bcf21c411d7e37702244bd415 100644 (file)
@@ -1,10 +1,5 @@
 package org.simantics.scl.compiler.elaboration.contexts;
 
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -12,6 +7,7 @@ import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.common.precedence.Associativity;
 import org.simantics.scl.compiler.common.precedence.Precedence;
 import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
 import org.simantics.scl.compiler.elaboration.expressions.EEntityTypeAnnotation;
 import org.simantics.scl.compiler.elaboration.expressions.EError;
@@ -36,6 +32,13 @@ import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
 import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.simantics.scl.compiler.types.Type;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
 
 public class TranslationContext extends TypeTranslationContext implements EnvironmentalContext {
 
@@ -147,7 +150,45 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
     }
     
     private Expression resolveIn(long location, Namespace namespace, String name) {
-        SCLValue value = resolveValueIn(location, namespace, name);
+        SCLValue value;
+        try {
+            value = resolveValueIn(location, namespace, name);
+        } catch (AmbiguousNameException e) {
+            if(SCLCompilerConfiguration.ALLOW_OVERLOADING) {
+                EAmbiguous.Alternative[] alternatives = new EAmbiguous.Alternative[e.conflictingModules.length];
+                //System.out.println("Overloading:");
+                for(int i=0;i<e.conflictingModules.length;++i) {
+                    Name altName = Name.create(e.conflictingModules[i], e.name);
+                    //System.out.println("    " + altName);
+                    SCLValue altValue = environment.getValue(altName);
+                    alternatives[i] = new EAmbiguous.Alternative() {
+                        @Override
+                        public Type getType() {
+                            return altValue.getType();
+                        }
+    
+                        @Override
+                        public Expression realize() {
+                            EConstant expression = new EConstant(altValue);
+                            expression.location = location;
+                            return expression;
+                        }
+                        
+                        @Override
+                        public String toString() {
+                            return altValue.getName().toString().replace('/', '.');
+                        }
+                    };
+                }
+                EAmbiguous expression = new EAmbiguous(alternatives);
+                expression.location = location;
+                return expression;
+            }
+            else {
+                errorLog.log(location, e.getMessage());
+                value = null;
+            }
+        }
         if(value == null)
             return new EError(location);
         return new EConstant(location, value);
@@ -340,8 +381,7 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
             return prec;
     }
 
-    private SCLValue resolveValueIn(long location, Namespace namespace, final String name) {
-        try {
+    private SCLValue resolveValueIn(long location, Namespace namespace, final String name) throws AmbiguousNameException {
             SCLValue value = namespace.getValue(name);
             if(value == null) {
                 StringBuilder message = new StringBuilder();
@@ -391,10 +431,6 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
                 return null;
             }
             return value;
-        } catch (AmbiguousNameException e) {
-            errorLog.log(location, e.getMessage());
-            return null;
-        }
     }
     
     public Case translateCase(Expression lhs, Expression rhs) {        
index 29b9028e6d721e6a21d1f5e5d9d998c41762e35b..b9dbb4be823b1e3d7c1bb769073c91f7bbe654c3 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.elaboration.contexts;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.errors.ErrorLog;
 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
@@ -15,6 +13,8 @@ import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
 import org.simantics.scl.compiler.types.kinds.Kind;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 
+import gnu.trove.map.hash.THashMap;
+
 public class TypeTranslationContext {
     
     Environment environment;
index de58a05cdb6c7838d02f4a108a77ac4127b98444..850f077db32d3ec9c8b81a2ebe5b4f6b32b30aa6 100644 (file)
@@ -1,13 +1,11 @@
 package org.simantics.scl.compiler.elaboration.contexts;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.constants.NoRepConstant;
+import org.simantics.scl.compiler.elaboration.expressions.EAmbiguous;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;
 import org.simantics.scl.compiler.elaboration.expressions.EError;
@@ -41,6 +39,9 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class TypingContext implements EnvironmentalContext {
 
     private ErrorLog errorLog;
@@ -64,6 +65,9 @@ public class TypingContext implements EnvironmentalContext {
     public THashSet<SCLValue> recursiveValues;
     public ArrayList<EPlaceholder> recursiveReferences;
     
+    // Overloading
+    public ArrayList<EAmbiguous> overloadedExpressions = new ArrayList<EAmbiguous>(); 
+    
     //TypeUnparsingContext tuc = new TypeUnparsingContext();   
     
     Environment environment;
@@ -258,7 +262,7 @@ public class TypingContext implements EnvironmentalContext {
      * Instantiates type abstractions and constraints from the value.
      */
     public Expression instantiate(Expression expr) {
-        Type type = Types.weakCanonical(expr.getType());
+        Type type = Types.canonical(expr.getType());
         while(type instanceof TForAll) {
             TForAll forAll = (TForAll)type;
             TVar var = forAll.var;
@@ -297,7 +301,7 @@ public class TypingContext implements EnvironmentalContext {
      * type applications, lambdas and effect subsumptions.
      */
     public Expression subsume(Expression expr, Type b) {
-        b = Types.weakCanonical(b);
+        b = Types.canonical(b);
         /*if(b instanceof TForAll) {
             TForAll forAll = (TForAll)b;
             TVar var = forAll.var;
index c753924e64eb7fc5e99576e2e6fa2e4c13200475..8b24943478792887543d9a6cc363ff63fe1281b7 100644 (file)
@@ -56,7 +56,7 @@ public class EqGuard extends Equation {
 \r
     @Override\r
     public void checkType(TypingContext context) {\r
-        guard = guard.inferType(context);\r
+        guard = guard.checkIgnoredType(context);\r
     }\r
 \r
     @Override\r
index aeeb1ec1ea8c4ce80b4ff052d695e5c50d8d0bba..af0a43d0896c495f31b0c1d9280ff46dc4dce483 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -11,6 +7,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public abstract class ASTExpression extends SimplifiableExpression {\r
     public ASTExpression() {\r
     }\r
index 219cce461a10adb586c484a3713a546152e7772c..50eda1c130d6840475875276a71f011760ce53ce 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator
 import org.simantics.scl.compiler.internal.parsing.Symbol;\r
 import org.simantics.scl.compiler.types.Type;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class Case extends Symbol {\r
     public Expression[] patterns;\r
     public Expression value;\r
@@ -99,6 +99,17 @@ public class Case extends Symbol {
             patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);\r
         value = value.checkType(context, requiredType);\r
     }\r
+    \r
+    public void checkIgnoredType(TypingContext context, Type[] parameterTypes) {\r
+        if(patterns.length != parameterTypes.length) {\r
+            context.getErrorLog().log(location, "This case has different arity ("+patterns.length+\r
+                    ") than than the first case (+"+parameterTypes.length+"+).");\r
+            return;\r
+        }\r
+        for(int i=0;i<patterns.length;++i)\r
+            patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);\r
+        value = value.checkIgnoredType(context);\r
+    }\r
         \r
     public void decorate(ExpressionDecorator decorator) {\r
         for(int i=0;i<patterns.length;++i)\r
index 224bd17b96979e6d64b0e761fb0b42b90f2715f8..95b18efd62abd266e90af0b7a6237172899302d2 100644 (file)
@@ -128,4 +128,10 @@ public abstract class DecoratingExpression extends SimplifiableExpression {
         expression = expression.checkBasicType(context, requiredType);
         return this;
     }
+    
+    @Override
+    public Expression checkIgnoredType(TypingContext context) {
+        expression = expression.checkIgnoredType(context);
+        return this;
+    }
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EAmbiguous.java
new file mode 100644 (file)
index 0000000..6121a57
--- /dev/null
@@ -0,0 +1,227 @@
+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.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;
+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.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;
+    
+    Alternative[] alternatives;
+    boolean[] active;
+    int activeCount;
+    transient TypingContext context;
+    Expression resolvedExpression;
+    
+    public abstract static class Alternative {
+        public abstract Type getType();
+        public abstract Expression realize();
+    }
+    
+    public EAmbiguous(Alternative[] alternatives) {
+        this.alternatives = alternatives;
+        this.active = new boolean[alternatives.length];
+        for(int i=0;i<alternatives.length;++i)
+            this.active[i] = true;
+        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();
+    }
+    
+    private Type getCommonSkeleton() {
+        Type[] types = new Type[activeCount];
+        for(int i=0,j=0;i<alternatives.length;++i)
+            if(active[i])
+                types[j++] = Types.instantiateAndStrip(alternatives[i].getType());
+        return Skeletons.commonSkeleton(context.getEnvironment(), types);
+    }
+
+    private void filterActive() {
+        THashMap<TMetaVar,Type> unifications = new THashMap<TMetaVar,Type>(); 
+        Type requiredType = getType();
+        if(DEBUG)
+            System.out.println("EAmbigious.filterActive with " + requiredType);
+        for(int i=0;i<alternatives.length;++i)
+            if(active[i]) {
+                unifications.clear();
+                Type alternativeType = Types.instantiateAndStrip(alternatives[i].getType());
+                if(DEBUG)
+                    System.out.println("    " + alternativeType);
+                if(!Skeletons.areSkeletonsCompatible(unifications, alternativeType, requiredType)) {
+                    active[i] = false;
+                    --activeCount;
+                }
+            }
+        if(DEBUG)
+            System.out.println("    activeCount = " + activeCount);
+    }
+
+    private String getNoMatchDescription(Type requiredType) {
+        StringBuilder b = new StringBuilder();
+        b.append("Expected <");
+        requiredType.toString(new TypeUnparsingContext(), b);
+        b.append(">, but no alteratives match the type: ");
+        for(int i=0;i<alternatives.length;++i) {
+            b.append("\n    ");
+            b.append(alternatives[i]);
+            b.append(" :: ");
+            alternatives[i].getType().toString(new TypeUnparsingContext(), b);
+        }
+        b.append('.');
+        return b.toString();
+    }
+    
+    private String getAmbiguousDescription(Type requiredType) {
+        StringBuilder b = new StringBuilder();
+        b.append("Expected <");
+        requiredType.toString(new TypeUnparsingContext(), b);
+        b.append(">, but multiple values match the type: ");
+        for(int i=0;i<alternatives.length;++i) {
+            b.append("\n    ");
+            b.append(alternatives[i]);
+            b.append(" :: ");
+            alternatives[i].getType().toString(new TypeUnparsingContext(), b);
+        }
+        b.append('.');
+        return b.toString();
+    }
+
+
+    private void resolveTo(int i) {
+        if(DEBUG)
+            System.out.println("EAmbigious.resolve to " + alternatives[i]);
+        resolvedExpression = context.instantiate(alternatives[i].realize());
+        Type requiredType = getType();
+        try {
+            Types.unify(resolvedExpression.getType(), requiredType);
+        } catch (UnificationException e) {
+            context.getErrorLog().log(location, getNoMatchDescription(requiredType));
+        }
+    }
+    
+    private void listenType() {
+        if(DEBUG)
+            System.out.println("EAmbigious.listenType " + getType());
+        new TypeListener() {
+            @Override
+            public void notifyAboutChange() {
+                if(DEBUG)
+                    System.out.println("EAmbigious.notifyAboutChange " + getType());
+                Type requiredType = getType();
+                filterActive();
+                if(activeCount == 0) {
+                    context.getErrorLog().log(location, getNoMatchDescription(requiredType));
+                    return;
+                }   
+                else if(activeCount == 1) {
+                    for(int i=0;i<alternatives.length;++i)
+                        if(active[i]) {
+                            resolveTo(i);
+                            return;
+                        }
+                }
+                Type commonType = getCommonSkeleton();
+                try {
+                    Skeletons.unifySkeletons(requiredType, commonType);
+                    listenType();
+                } catch (UnificationException e) {
+                    context.getErrorLog().log(location, getNoMatchDescription(requiredType));
+                }
+            }
+        }.listenSkeleton(getType());
+    }
+    
+    @Override
+    public Expression inferType(TypingContext context) {
+        this.context = context;
+        context.overloadedExpressions.add(this);
+        setType(getCommonSkeleton());
+        listenType();
+        return this;
+    }
+    
+    @Override
+    public void collectFreeVariables(THashSet<Variable> vars) {
+    }
+
+    @Override
+    public Expression resolve(TranslationContext context) {
+        throw new InternalCompilerError("EAmbiguousConstant should not exist in resolve phase.");
+    }
+
+    @Override
+    public void setLocationDeep(long loc) {
+        if(location == Locations.NO_LOCATION)
+            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
+    }
+    
+    @Override
+    public Expression simplify(SimplificationContext context) {
+        if(resolvedExpression != null)
+            return resolvedExpression;
+        else {
+            context.getErrorLog().log(location, getAmbiguousDescription(getType()));
+            return this;
+        }
+    }
+    
+    public void assertResolved(ErrorLog errorLog) {
+        if(resolvedExpression == null)
+            errorLog.log(location, getAmbiguousDescription(getType()));
+    }
+    
+    @Override
+    public Expression accept(ExpressionTransformer transformer) {
+        return transformer.transform(this);
+    }
+
+}
index fb27b9198afbf00ef9b6ae9b08eac1585eabbe97..8df327362560bc8574eefc96542d9e6f4da4de4a 100755 (executable)
@@ -1,12 +1,9 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.names.Name;\r
+import org.simantics.scl.compiler.constants.NoRepConstant;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -26,6 +23,8 @@ import org.simantics.scl.compiler.internal.interpreted.IApply;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
 import org.simantics.scl.compiler.internal.interpreted.IListLiteral;\r
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
+import org.simantics.scl.compiler.types.Skeletons;\r
+import org.simantics.scl.compiler.types.TFun;\r
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
@@ -33,6 +32,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 import org.simantics.scl.compiler.types.util.MultiFunction;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EApply extends Expression {\r
     Expression function;\r
     Expression[] parameters;\r
@@ -248,8 +251,7 @@ public class EApply extends Expression {
         return new IApply(function.toIExpression(target), parametersI);\r
     }\r
     \r
-    @Override\r
-    public Expression inferType(TypingContext context) {\r
+    private void inferType(TypingContext context, boolean ignoreResult) {\r
         function = function.inferType(context);\r
         function = context.instantiate(function);\r
         MultiFunction mfun;\r
@@ -265,7 +267,12 @@ public class EApply extends Expression {
             setType(Types.metaVar(Kinds.STAR));\r
             for(int i=0;i<parameters.length;++i)\r
                 parameters[i] = parameters[i].inferType(context);\r
-            return this;\r
+            return;\r
+        }\r
+        if((ignoreResult && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun &&\r
+                Types.canonical(mfun.effect) == Types.NO_EFFECTS) ||\r
+                (context.isInPattern() && Skeletons.canonicalSkeleton(mfun.returnType) instanceof TFun)) {\r
+            context.getErrorLog().log(location, "The function is applied with too few parameters.");\r
         }\r
         \r
         // Check parameter types\r
@@ -276,7 +283,19 @@ public class EApply extends Expression {
         \r
         context.declareEffect(location, mfun.effect);\r
         setType(mfun.returnType);\r
-\r
+    }\r
+    \r
+    @Override\r
+    public Expression inferType(TypingContext context) {\r
+        inferType(context, false);\r
+        return this;\r
+    }\r
+    \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        inferType(context, true);\r
+        if(Types.canonical(getType()) != Types.UNIT)\r
+            return new ESimpleLet(location, null, this, new ELiteral(NoRepConstant.PUNIT));\r
         return this;\r
     }\r
 \r
index 3cdbabf7816ae25b60911b5b9ef23742f0c05371..98c9aaedbfde9aa5b317ef533b4cc1b10c365538 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
@@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EApplyType extends Expression {    \r
     Expression expression;\r
     Type parameter;\r
index 0a11d9b99b169e4787bc4526babd8384cbc01a6a..8f6892a42f4f8cfb1e5a78e91386aef908c11c5e 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
@@ -17,6 +13,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EAsPattern extends Expression {\r
 \r
     Variable var;\r
index c7b0b80ef3518554c6714f67fbcfed7b65f2221c..fc6eda2eedb898ca531f8de148f6f77c632399e2 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EBind extends SimplifiableExpression {\r
     public Expression pattern;\r
     public Expression value;\r
index 45fb72d6340e1e95bc1cd41f5bfd179b76c14472..590cbbd96bf75ab80fd0d7d674b7c47d9164e6d6 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.names.Name;\r
@@ -35,6 +31,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.MultiFunction;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EConstant extends Expression {\r
     SCLValue value;\r
     Type[] typeParameters;\r
@@ -232,7 +232,7 @@ public class EConstant extends Expression {
             return this;\r
         }\r
         else\r
-            return this;\r
+            return applyPUnit(context);\r
     }\r
 \r
     @Override\r
index 11bc4b63357f3f459a61d6505b629d63a9a029d7..92608b7177707d8bffc0142ea7571f1b4eaac42a 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
@@ -18,6 +14,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EEnforce extends SimplifiableExpression {\r
     \r
     Query query;\r
index 108b4b707557ce188a44761f693b56c5588c0951..67fe2db7c37937b29975f75b4c29e98cd19375ea 100644 (file)
@@ -1,7 +1,6 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*;\r
-import gnu.trove.map.hash.THashMap;\r
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;\r
 \r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.java.EqRelation;\r
@@ -15,6 +14,8 @@ import org.simantics.scl.compiler.environment.Environments;
 import org.simantics.scl.compiler.errors.Locations;\r
 import org.simantics.scl.compiler.internal.parsing.Token;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class EEntityTypeAnnotation extends ASTExpression {\r
     \r
     Expression expression;\r
index 41cea63ffb212e0aaad8f3eb56feb2d674ddcfb5..cf3774f2168628edba17b2fef342b761bbbe88ee 100644 (file)
@@ -107,6 +107,11 @@ public class EEquations extends SimplifiableExpression {
         return this;\r
     }\r
     \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        return inferType(context);\r
+    }\r
+\r
     @Override\r
     public Expression simplify(SimplificationContext context) {\r
         context.getErrorLog().log(location, "Equations should be transformed into other expressions before simplification phase.");\r
index d9a24618103c301defc751a8f6150b8a3f6d326b..d3f37281dfef771c4c69ab226f9b681ad5255b24 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -18,6 +14,10 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EError extends Expression {\r
 \r
     public EError(long loc, Type type) {\r
index afbe9d64f16c5bd5f98d322406e079d6cf96a3fb..56ea79a2a458bbe0d01e1065fd428dde31480ad2 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
@@ -24,6 +20,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EExternalConstant extends Expression {\r
     Object value;\r
     \r
index bcb7bf37b867d300306aa17ed8e4727c0e94212b..b49999c06e72c35b021f99bacba81c02b54dd2b9 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.names.Name;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -15,6 +11,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EFieldAccess extends SimplifiableExpression {\r
 \r
     private static final Type VARIABLE = Types.con("Simantics/Variables", "Variable");\r
index ef5412c7bb093f8e275adb984f8ee8c7faba7e5f..55fd9b4939991348bd65e8d81abbe35f1bfca776 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -13,6 +9,10 @@ import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EGetConstraint extends SimplifiableExpression {\r
     TPred constraint;\r
     EVariable evidence;\r
index 420875999216f685b99da760e4b861ad219351d8..e1ccd53ddc3bc2a7bdf99d30fe12eb7ac19e6044 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EIf extends Expression {\r
     public Expression condition;\r
     public Expression then_;\r
@@ -117,6 +117,14 @@ public class EIf extends Expression {
         return this;\r
     }\r
     \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        condition = condition.checkType(context, Types.BOOLEAN);\r
+        then_ = then_.checkIgnoredType(context);\r
+        else_ = else_.checkIgnoredType(context);\r
+        return this;\r
+    }\r
+    \r
     @Override\r
     public Expression decorate(ExpressionDecorator decorator) {\r
         condition = condition.decorate(decorator);\r
index 7ccd66d0a3b8240fd25d70b37bb56bca94e07cf5..101e00b840fc67c1e37c3d7f7f32d82d5092d158 100755 (executable)
@@ -1,10 +1,6 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.constants.DoubleConstant;\r
 import org.simantics.scl.compiler.constants.FloatConstant;\r
@@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EIntegerLiteral extends SimplifiableExpression {\r
     public String value;\r
     EVariable constraint;\r
index 1d46b80c6b98d6760a048399a0f85109a81eabe4..abf4c89da4f282a79425f3a08eba5d03357e9d21 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -17,6 +13,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 import org.simantics.scl.compiler.types.util.MultiFunction;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ELambda extends SimplifiableExpression {\r
     public Case[] cases;\r
     Type effect = Types.NO_EFFECTS;\r
index a1505e0dd8f34d97bfc8eb4768083f6a84215464..8e9a74cd5146ea0fbb1212b660726a8fa1353366 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
@@ -21,6 +17,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ELambdaType extends Expression {\r
     public TVar[] parameters;\r
     public Expression value;\r
index a128e50634f49d88240ebe915d07463b937f5bc1..bbbc25c4de4ed7e7841172fb44f96834c5a15b85 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
@@ -25,6 +21,10 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ELet extends Expression {\r
     public Assignment[] assignments;\r
     public Expression in;\r
@@ -202,6 +202,13 @@ public class ELet extends Expression {
         in = in.checkType(context, requiredType);\r
         return this;\r
     }\r
+    \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        checkAssignments(context);\r
+        in = in.checkIgnoredType(context);\r
+        return this;\r
+    }\r
 \r
     @Override\r
     public Expression decorate(ExpressionDecorator decorator) {\r
index a7e36247ef7b70f5a4c0e769ab655cc832b57b87..abfeb2bc70c84431e30b5aa9409e87b08785f1ae 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -15,6 +11,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EListComprehension extends SimplifiableExpression {\r
 \r
     public Expression head;\r
index 4cdcc6f847f237038bccf8732d3688ffce700a53..b7165e975364cee2524239b2a01455a328d7b5d7 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EListLiteral extends SimplifiableExpression {\r
 \r
     Expression[] components;\r
index 383e212f6b8f6fcfcfcba57897a76bccb9dbe351..15201e7f0f19e935f825ffff57f974c5c1ae957e 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.constants.Constant;\r
@@ -23,6 +19,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ELiteral extends Expression {\r
     Constant value;\r
     \r
index a218b95c38bf04913f983ba5c0978cb169b16e34..11877a60e086e9d0e6ba16f7eac4aaaccedd8cac 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
@@ -13,6 +9,7 @@ import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.environment.Environment;\r
 import org.simantics.scl.compiler.errors.Locations;\r
 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;\r
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
 import org.simantics.scl.compiler.internal.elaboration.matching.PatternMatchingCompiler;\r
 import org.simantics.scl.compiler.internal.elaboration.matching.Row;\r
@@ -21,6 +18,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EMatch extends Expression {\r
 \r
     public Expression[] scrutinee;\r
@@ -75,7 +76,7 @@ public class EMatch extends Expression {
            CodeWriter joinPoint = w.createBlock(getType());\r
            CodeWriter failurePoint = w.createBlock(); // TODO generate only one failurePoint per function\r
            PatternMatchingCompiler.split(w, env, scrutineeVals, joinPoint.getContinuation(), failurePoint.getContinuation(), rows);\r
-           failurePoint.throw_(location, "Matching failure at: " + toString());\r
+           failurePoint.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());\r
            w.continueAs(joinPoint);\r
            return w.getParameters()[0];\r
     }\r
@@ -149,6 +150,19 @@ public class EMatch extends Expression {
         setType(requiredType);\r
         return this;\r
     }\r
+    \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        Type[] scrutineeTypes = new Type[scrutinee.length];\r
+        for(int i=0;i<scrutinee.length;++i) {\r
+            scrutinee[i] = scrutinee[i].checkType(context, Types.metaVar(Kinds.STAR));\r
+            scrutineeTypes[i] = scrutinee[i].getType();\r
+        }\r
+        for(Case case_ : cases)\r
+            case_.checkIgnoredType(context, scrutineeTypes);\r
+        setType(Types.UNIT);\r
+        return this;\r
+    }\r
 \r
     @Override\r
     public Expression decorate(ExpressionDecorator decorator) {\r
index 64d5cc3c64126675f950fddb467fa7abefdeb0ec..8d8883eae66f5e0fe2f20832f922aa7ca37ffe7e 100755 (executable)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 \r
@@ -13,6 +10,9 @@ import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefini
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;\r
 import org.simantics.scl.compiler.errors.Locations;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectObjectProcedure;\r
+\r
 public class EPreLet extends ASTExpression {\r
 \r
     List<LetStatement> assignments;\r
index ff27eb03a4ef066b0fa3f13d81080eede5a31e73..74f24ebb82496048e0d1c5c599c20350c642f646 100644 (file)
@@ -1,13 +1,13 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.expressions.ERuleset.DatalogRule;\r
 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;\r
 import org.simantics.scl.compiler.elaboration.relations.LocalRelation;\r
 import org.simantics.scl.compiler.errors.Locations;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class EPreRuleset extends ASTExpression {\r
 \r
     RuleStatement[] statements;\r
index 644e31ab6968cdfd984f69ed852704b4673fc2b4..f2e17aa00cf6b78f418d993e6615149acb171ff3 100755 (executable)
@@ -1,10 +1,6 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.constants.DoubleConstant;\r
 import org.simantics.scl.compiler.constants.FloatConstant;\r
@@ -19,6 +15,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ERealLiteral extends SimplifiableExpression {\r
     public String value;\r
     EVariable constraint;\r
index cbb69a34be75153b04d99a9d78ccb234676a9194..32999dcb48877a689c980d7e7c1bc73973b46345 100644 (file)
@@ -52,8 +52,29 @@ public class ERecord extends ASTExpression {
             return new EError(constructor.location);
         }
         THashMap<String,FieldAssignment> recordMap = new THashMap<String,FieldAssignment>(fields.length);
-        for(FieldAssignment field : fields)
-            recordMap.put(field.name, field);
+        for(FieldAssignment field : fields) {
+            if(field.value == null) {
+                String bestMatch = null;
+                int bestMatchLength = 0;
+                for(int i=0;i<fieldNames.length;++i) {
+                    String fieldName = fieldNames[i];
+                    if(field.name.startsWith(fieldName) && fieldName.length() > bestMatchLength) {
+                        bestMatch = fieldName;
+                        bestMatchLength = fieldName.length();
+                    }
+                }
+                if(bestMatch == null) {
+                    context.getErrorLog().log(field.location, "Invalid shorthand field " + field.name + " is defined twice.");
+                    return new EError(location);
+                }
+                field.value = new EVar(field.location, field.name);
+                field.name = bestMatch;
+            }
+            if(recordMap.put(field.name, field) != null) {
+                context.getErrorLog().log(field.location, "Field " + field.name + " is defined more than once.");
+                return new EError(location);
+            }
+        }
         Expression[] parameters = new Expression[fieldNames.length];
         boolean error = false;
         for(int i=0;i<fieldNames.length;++i) {
@@ -91,7 +112,8 @@ public class ERecord extends ASTExpression {
         if(location == Locations.NO_LOCATION) {
             location = loc;
             for(FieldAssignment field : fields)
-                field.value.setLocationDeep(loc);
+                if(field.value != null)
+                    field.value.setLocationDeep(loc);
         }
     }
     
index e512460298d5bb40e0316d5b4020d0c21f8184a3..02b8c9ddc0c4922765cbbf5ff321726e4d05ff86 100644 (file)
@@ -131,6 +131,13 @@ public class ERuleset extends SimplifiableExpression {
         return compile(context);\r
     }\r
     \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        checkRuleTypes(context);\r
+        in = in.checkIgnoredType(context);\r
+        return compile(context);\r
+    }\r
+    \r
     @Override\r
     public void collectFreeVariables(THashSet<Variable> vars) {\r
         for(DatalogRule rule : rules) {\r
index 9a0bb040d6acb15ff0aa9edba0f894aa1c28434b..1e92952330fba5b4626eac399021349c31b84688 100644 (file)
@@ -8,9 +8,6 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.new
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.seq;\r
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple;\r
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.common.names.Name;\r
@@ -30,6 +27,10 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ESelect extends SimplifiableExpression {\r
 \r
     private final Type ARRAY_LIST = Types.con("ArrayList", "T"); \r
index 071588ab9d5a33745ebb6c38b22d8f6cbde9fa78..e1efb30457b25973dd60ee3110930dede5b6bc38 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
@@ -27,6 +23,10 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 import org.simantics.scl.compiler.types.util.MultiFunction;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ESimpleLambda extends Expression {\r
     public Variable parameter;\r
     public Expression value;\r
index 53984840d65ca851ecceec5a82c63a5e7f633772..8e73b2392fd3add380c8e656df2eae19777c2211 100755 (executable)
@@ -141,7 +141,7 @@ public class ESimpleLet extends Expression {
 \r
     private void checkBinding(TypingContext context) {\r
         if(variable == null)\r
-            value = value.inferType(context);\r
+            value = value.checkIgnoredType(context);\r
         else if(variable.getType() == null) {\r
             value = value.inferType(context);\r
             variable.setType(value.getType());\r
@@ -168,6 +168,13 @@ public class ESimpleLet extends Expression {
         in = in.checkType(context, requiredType);\r
         return this;\r
     }\r
+    \r
+    @Override\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        checkBinding(context);\r
+        in = in.checkIgnoredType(context);\r
+        return this;\r
+    }\r
 \r
     @Override\r
     public Expression decorate(ExpressionDecorator decorator) {\r
index 63fee96ca7e8096e4454749a074052dac67c9188..24584fe65cee8a0a457925bcba857ce2aa4c2927 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.Comparator;\r
@@ -20,6 +16,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ETransformation extends SimplifiableExpression {\r
     public static final Object TRANSFORMATION_RULES_TYPECHECKED = new Object();\r
     \r
index 48969e77b77b770ea4c2366db7ffbb2b7b3204c0..cfeab99f4e0b783c171ecf8ac61a874d09f99a43 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ETypeAnnotation extends SimplifiableExpression {\r
     Expression value;\r
     Type type;\r
index 553677626cdfc8ba7c283a500d87ce451b8d362a..ca87d72c4e8d878ac3cb30c445758578b43a9295 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
@@ -25,6 +21,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EVariable extends Expression {\r
     public static final EVariable[] EMPTY_ARRAY = new EVariable[0];\r
     \r
@@ -144,9 +144,12 @@ public class EVariable extends Expression {
     \r
     @Override\r
     public Expression inferType(TypingContext context) {\r
-        if(context.isInPattern())\r
+        if(context.isInPattern()) {\r
             variable.setType(Types.metaVar(Kinds.STAR));\r
-        return this;\r
+            return this;\r
+        }\r
+        else\r
+            return applyPUnit(context);\r
     }\r
     \r
     @Override\r
index e7907f3578e62599536bfd89687bebc78e55ab4c..8021c407bee5687f055212c54db0ae157ef2c18a 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
@@ -22,6 +18,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class EWhen extends SimplifiableExpression {\r
 \r
     public Query query;\r
@@ -79,7 +79,7 @@ public class EWhen extends SimplifiableExpression {
         for(Variable variable : variables)\r
             variable.setType(Types.metaVar(Kinds.STAR));\r
         query.checkType(context);\r
-        action.checkType(context, Types.UNIT);\r
+        action.checkIgnoredType(context);\r
         \r
         // Compile query\r
         return compile(context);\r
index 83d7ec4e7bb5290a407df6dc3d79dff8b7fed328..edf93841b5c9ba1adf7420238ee7c24451ed81c6 100755 (executable)
@@ -1,13 +1,11 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.common.precedence.Precedence;\r
+import org.simantics.scl.compiler.constants.NoRepConstant;\r
+import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -36,6 +34,10 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 import org.simantics.scl.compiler.types.util.Typed;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public abstract class Expression extends Symbol implements Typed {\r
     public static final Expression[] EMPTY_ARRAY = new Expression[0];\r
     \r
@@ -77,10 +79,30 @@ public abstract class Expression extends Symbol implements Typed {
     public Expression inferType(TypingContext context) {\r
         return checkBasicType(context, Types.metaVar(Kinds.STAR));\r
     }\r
-       \r
-       public Expression checkBasicType(TypingContext context, Type requiredType) {\r
-           return context.subsume(inferType(context), requiredType);\r
-       }\r
+\r
+    public Expression checkBasicType(TypingContext context, Type requiredType) {\r
+        return context.subsume(inferType(context), requiredType);\r
+    }\r
+    \r
+    protected Expression applyPUnit(EnvironmentalContext context) {\r
+        Type type = Types.canonical(getType());\r
+        if(type instanceof TFun) {\r
+            TFun fun = (TFun)type;\r
+            if(fun.getCanonicalDomain() == Types.PUNIT) {\r
+                EApply result = new EApply(location, this, new ELiteral(NoRepConstant.PUNIT));\r
+                result.effect = fun.getCanonicalEffect();\r
+                return result;\r
+            }\r
+        }\r
+        return this;\r
+    }\r
+\r
+    public Expression checkIgnoredType(TypingContext context) {\r
+        Expression expression = inferType(context);\r
+        if(Types.canonical(expression.getType()) != Types.UNIT)\r
+            expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT));\r
+        return expression;\r
+    }\r
        \r
        /**\r
         * Checks the type of the expression against the given type. Adds type\r
@@ -89,7 +111,7 @@ public abstract class Expression extends Symbol implements Typed {
        public final Expression checkType(TypingContext context, Type requiredType) {\r
            //System.out.println("checkType: " + this + " :: " + requiredType);\r
            if(!context.isInPattern()) {\r
-               requiredType = Types.weakCanonical(requiredType);\r
+               requiredType = Types.canonical(requiredType);\r
            if(requiredType instanceof TForAll) {\r
                 TForAll forAll = (TForAll)requiredType;\r
                 TVar var = forAll.var;\r
index 1bd50bb6a32124834519204e10055ac360309cce..baeedd0f00a51df1e8308dfb737dd77886cb81af 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.scl.compiler.elaboration.expressions;
 
 public interface ExpressionTransformer {
     
+    Expression transform(EAmbiguous expression);
     Expression transform(EApply expression);
     Expression transform(EApplyType expression);
     Expression transform(EAsPattern expression);
index 9bec115127b2a0d5a8a32c5edc0f552743eb463a..48f72eeac0b1a3f743fb0a042eb5c78b32e54619 100755 (executable)
@@ -1,10 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
@@ -13,12 +8,17 @@ import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.errors.Locations;\r
 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;\r
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class GuardedExpressionGroup extends Expression {\r
     public GuardedExpression[] expressions;\r
 \r
@@ -58,7 +58,7 @@ public class GuardedExpressionGroup extends Expression {
         CodeWriter failure = w.createBlock();\r
         compile(env, w, success.getContinuation(), failure.getContinuation());\r
         w.continueAs(success);\r
-        failure.throw_(location, "Matching failure at: " + toString());\r
+        failure.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());\r
         return result;\r
         //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");\r
     }\r
index 17f13889d9471098c9a14e48a60cc14adc654055..1a2f451eeab205b8aff61a0ae5d655a2750660f4 100644 (file)
@@ -38,6 +38,11 @@ public class StandardExpressionTransformer implements
 ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor,
 EquationVisitor {
 
+    @Override
+    public Expression transform(EAmbiguous expression) {
+        return expression;
+    }
+
     @Override
     public Expression transform(EApply expression) {
         expression.function = expression.function.accept(this);
index 0d8da56d45fd194aad28ff83c2104b833ead823e..db1da2bd8fee8e976dfdb557980d8c82c1eca11d 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.accessor;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -14,6 +10,10 @@ import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
 import org.simantics.scl.compiler.types.Types;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ExpressionAccessor extends FieldAccessor {\r
     public Expression fieldName;\r
 \r
index 349623178ecbbe96648d769b4d67db949ab36087..a6eeb3f55d0db6573011a10d8000185af8427710 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.accessor;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -13,6 +9,10 @@ import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
 import org.simantics.scl.compiler.internal.parsing.Symbol;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public abstract class FieldAccessor extends Symbol {\r
     public char accessSeparator;\r
 \r
index 23733e9c179f412c6f57960beaf2c42526cdc2db..59aa3ebe2b2e777e2ba614477712de1b695d4e75 100755 (executable)
@@ -19,11 +19,12 @@ public class GuardStatement extends Statement {
 \r
     @Override\r
     public Expression toExpression(EnvironmentalContext context, boolean monadic, Expression in) {\r
-        Variable var = new Variable("_");\r
-        if(monadic)\r
+        if(monadic) {\r
+            Variable var = new Variable("_");\r
             return new EBind(location, new EVariable(location, var), value, in);\r
+        }\r
         else\r
-            return new ESimpleLet(location, var, value, in);\r
+            return new ESimpleLet(location, null, value, in);\r
     }\r
     \r
     @Override\r
index 5c82a5aea887e9acbd5ca169ddc5870d72bacb36..5f042ff93d77c61a5873b5139826045afa50ba0f 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -16,6 +12,10 @@ import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
 import org.simantics.scl.compiler.types.Type;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ListAssignment extends ListQualifier {\r
     public Expression pattern;\r
     public Expression value;\r
index 7b4cae6bdf25ea2af7fceb6f6b3686fb3282de33..622b53842e212699a3e16704821b6c9c4d04067b 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -19,6 +15,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ListGenerator extends ListQualifier {\r
     public Expression pattern;\r
     public Expression value;\r
index d591652a26e3f78de26e8330ecda2d66267a66fc..0a47f04b1713ddf62b6e97160b4d9e4bcd3210b8 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -15,6 +11,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.Types;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ListGuard extends ListQualifier {\r
     public Expression condition;\r
 \r
index e05501e1e311907508e4437b35a78f1dd935f1a2..270c3ffc767491ab4848f1da681b60c30a84adbc 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -13,6 +9,10 @@ import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator
 import org.simantics.scl.compiler.internal.parsing.Symbol;\r
 import org.simantics.scl.compiler.types.Type;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public abstract class ListQualifier extends Symbol {\r
 \r
     public abstract void checkType(TypingContext context);\r
index c5affbf96fbdf97fb699ca9ae42aa35479598727..84fa63e9ce848284cdd656ab182bf552e31ea2a4 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -14,6 +10,10 @@ import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
 import org.simantics.scl.compiler.types.Type;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ListSeq extends ListQualifier {\r
     public ListQualifier a;\r
     public ListQualifier b;\r
index 5867a5cfe6fb8b3a67b3c236808893577ad2719f..c79714c4e406a8f118f2280cf5526a3507ae5712 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.expressions.list;\r
 \r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
@@ -18,6 +14,10 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ListThen extends ListQualifier {\r
     public ListQualifier left;\r
     public Expression transformer;\r
index c5f8f3621187b02caf6e19b4437071bddbd4105c..6cbdb6f6b19aedef68bf8f69321650fca39123dd 100644 (file)
@@ -9,6 +9,7 @@ import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
 import org.simantics.scl.compiler.elaboration.expressions.EAsPattern;\r
 import org.simantics.scl.compiler.elaboration.expressions.EBind;\r
 import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
+import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;\r
 import org.simantics.scl.compiler.elaboration.expressions.EEnforce;\r
 import org.simantics.scl.compiler.elaboration.expressions.EEquations;\r
 import org.simantics.scl.compiler.elaboration.expressions.EError;\r
@@ -25,7 +26,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EListLiteral;
 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;\r
 import org.simantics.scl.compiler.elaboration.expressions.EMatch;\r
 import org.simantics.scl.compiler.elaboration.expressions.EPlaceholder;\r
-import org.simantics.scl.compiler.elaboration.expressions.ECoveringBranchPoint;\r
 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;\r
 import org.simantics.scl.compiler.elaboration.expressions.ERuleset;\r
 import org.simantics.scl.compiler.elaboration.expressions.ESelect;\r
@@ -331,7 +331,7 @@ public class ExpressionToStringVisitor implements ExpressionVisitor, QueryVisito
             ESimpleLet let = (ESimpleLet)expression;\r
             Variable variable = let.getVariable();\r
             Expression value = let.getValue();\r
-            if("_".equals(variable.getName()))\r
+            if(variable == null || "_".equals(variable.getName()))\r
                 printAsDo(value);\r
             else {\r
                 newLine();\r
index b9534f76b98147a6d6d4f73a229067a3ffe0abe4..6bdaaea7bfda2b0d26a89944b09e6f6be0a1d289 100644 (file)
@@ -1,7 +1,10 @@
 package org.simantics.scl.compiler.elaboration.java;
 
 
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.constant;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.string;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
 
 import org.cojen.classfile.TypeDesc;
 import org.simantics.scl.compiler.constants.generic.CallJava;
index 6319e58b25d07dbc749059cfbd42a793b29a3627..a154dff2304f55200f9f3ea45221349279f13076 100755 (executable)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.elaboration.macros;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
@@ -13,6 +11,8 @@ import org.simantics.scl.compiler.elaboration.expressions.Variable;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 
+import gnu.trove.map.hash.THashMap;
+
 /**
  * This is a macro rule that replaces an application with
  * the definition of the function.
index ef73ea6af1ec0745071c22c452bee333e1535866..49301b151d93e3fd7d54acc5adc7f1990d0a5beb 100755 (executable)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.elaboration.modules;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.cojen.classfile.TypeDesc;\r
@@ -16,6 +14,8 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.kinds.Kinds;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class TypeClass extends TypeConstructor {\r
     public final TPred[] context;\r
     public final TCon name;\r
index c9bfa6fdefe6be4a41237baf28b580ae47a2413d..681c66972a415bcb6c955ff514cd21439c470fb3 100755 (executable)
@@ -1,12 +1,12 @@
 package org.simantics.scl.compiler.elaboration.modules;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import org.simantics.scl.compiler.constants.Constant;\r
 import org.simantics.scl.compiler.elaboration.errors.ElabNode;\r
 import org.simantics.scl.compiler.types.TPred;\r
 import org.simantics.scl.compiler.types.TVar;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class TypeClassInstance extends ElabNode {\r
     public final TypeClass typeClass;\r
     public final TPred[] context;    \r
index 0fc36b6d7a5ce7ca3a497e27625ec4b861ab998c..53eb780fdaf2174393a8235d15a755aa8363d5be 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.Arrays;
 
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
@@ -16,7 +12,10 @@ 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 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 QAbstractCombiner extends Query {
     public Query[] queries;
index 1f05e4734d3b3d15ca58cc17e6e4cb9c38c981c3..e04246e40e7d4224837205d7622c404527bae0aa 100644 (file)
@@ -1,15 +1,14 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 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 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 QAbstractModifier extends Query {
     public Query query;
index 95760513b5383e80136b8005ff9ed50ce4a8b82a..fd7dacb799b625984ccf280c1b4f96380701c950 100644 (file)
@@ -1,11 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-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;
-
 import java.util.ArrayList;
 import java.util.Set;
 
@@ -31,16 +25,22 @@ 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;
+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 {
     public SCLRelation relation;
     public Type[] typeParameters;
     public Expression[] parameters;
-    
+
     public QAtom(SCLRelation relation, Expression ... parameters) {
         this.relation = relation;
         this.parameters = parameters;
     }
-    
+
     public QAtom(SCLRelation relation, Type[] typeParameters, Expression ... parameters) {
         this.relation = relation;
         this.typeParameters = typeParameters;
@@ -52,7 +52,7 @@ public class QAtom extends Query {
         for(Expression parameter : parameters)
             parameter.collectFreeVariables(vars);
     }
-    
+
     @Override
     public void checkType(TypingContext context) {
         // Type parameters
@@ -60,7 +60,7 @@ public class QAtom extends Query {
         typeParameters = new Type[typeVariables.length];
         for(int i=0;i<typeVariables.length;++i)
             typeParameters[i] = Types.metaVar(typeVariables[i].getKind());
-        
+
         // Check parameter types
         Type[] parameterTypes = relation.getParameterTypes();
         if(parameterTypes.length != parameters.length)
@@ -70,7 +70,7 @@ public class QAtom extends Query {
                 parameters[i] = parameters[i]
                         .checkType(context, parameterTypes[i].replace(typeVariables, typeParameters));
     }
-    
+
     public Expression generateEnforce(EnforcingContext context) {
         Variable[] variables = new Variable[parameters.length];
         for(int i=0;i<variables.length;++i)
@@ -92,7 +92,7 @@ public class QAtom extends Query {
     private static class VariableMaskProcedure implements VariableProcedure {
         ConstraintCollectionContext context;
         long requiredVariablesMask = 0L;
-        
+
         public VariableMaskProcedure(ConstraintCollectionContext context) {
             this.context = context;
         }
@@ -104,7 +104,7 @@ public class QAtom extends Query {
                 requiredVariablesMask |= 1L << id;
         }
     }
-    
+
     @Override
     public void collectConstraints(ConstraintCollectionContext context) {
         try {
@@ -133,20 +133,20 @@ public class QAtom extends Query {
                     }
                 }
             }
-                   
+
             // Combine required and optional variables
             TIntHashSet allVariablesSet = new TIntHashSet();
             for(int v : optionalVariableByParameter)
                 if(v >= 0)
                     allVariablesSet.add(v);
-            
+
             context.addConstraint(new RelationConstraint(allVariablesSet.toArray(), varParameters, this,
                     optionalVariableByParameter, procedure.requiredVariablesMask));
         } catch(Exception e) {
             context.getQueryCompilationContext().getTypingContext().getErrorLog().log(location, e);
         }
     }
-    
+
     private static void collectRefs(SCLRelation relation, TObjectIntHashMap<Object> allRefs,
             TIntHashSet refs) {
         if(relation instanceof CompositeRelation) {
@@ -167,7 +167,7 @@ public class QAtom extends Query {
         for(Expression parameter : parameters)
             parameter.collectRefs(allRefs, refs);
     }
-    
+
     @Override
     public void collectVars(TObjectIntHashMap<Variable> allVars,
             TIntHashSet vars) {
@@ -215,7 +215,7 @@ public class QAtom extends Query {
             return new Diff[] { new Diff(diffable.id, new QConjunction(eqs)) };
         }
     }
-    
+
     private static boolean containsReferenceTo(
             CompositeRelation relation,
             THashMap<SCLRelation, Diffable> diffables) {
@@ -235,7 +235,7 @@ public class QAtom extends Query {
         else
             return this;
     }
-    
+
     @Override
     public void setLocationDeep(long loc) {
         if(location == Locations.NO_LOCATION) {
@@ -244,7 +244,7 @@ public class QAtom extends Query {
                 parameter.setLocationDeep(loc);
         }
     }
-    
+
     @Override
     public void accept(QueryVisitor visitor) {
         visitor.visit(this);
@@ -266,7 +266,7 @@ public class QAtom extends Query {
         }
         list.add(this);
     }
-    
+
     @Override
     public Query accept(QueryTransformer transformer) {
         return transformer.transform(this);
index 95bb7b454145638403eb824fe2d59505467947b1..07a1f4556a37d32a68246c8d2ad04fb2acb2871c 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TIntObjectHashMap;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Set;
@@ -22,6 +19,9 @@ import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+
 
 public class QConjunction extends QAbstractCombiner {
 
index f27926414da581dd3e5b35f326bcd00aefe4941f..fc1c769ff67b98a91e4904523e2b8ab145b66332 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TLongObjectHashMap;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.ArrayList;
 import java.util.Set;
 
@@ -25,6 +21,10 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.set.hash.TIntHashSet;
+
 
 public class QDisjunction extends QAbstractCombiner {
 
index cdb0a5726da1e5a02a989fde2bcebb0fd3d84f02..5356eccc2708987042bb174f215a2ab374782084 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.Collection;
 import java.util.Set;
 
@@ -20,6 +17,9 @@ import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 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;
     
index fa0794fb4b037b0a727eeb8bba56f80af42ede61..ca9378c89f19da98d41b699e95ef88c75f497048 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
@@ -17,6 +13,10 @@ 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;
index 20147c7dfd21288b43637019ebd196857d1beb2a..373efa413ddbb09a6e5d7ec302f8e823f866c858 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.TIntHashSet;
-
 import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
@@ -15,6 +12,9 @@ import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryE
 import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
 import org.simantics.scl.compiler.types.Type;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.TIntHashSet;
+
 
 public class QNegation extends QAbstractModifier {
 
index 5154495f5472dcdcb1b2e326673c6e9e3d9f3958..0ac54e22ec29d72b8468bde640220c4676a4ed39 100644 (file)
@@ -1,11 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query;
 
-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;
-
 import java.util.ArrayList;
 import java.util.Set;
 
@@ -32,6 +26,12 @@ import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 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];
     
index 7b2bfc60909cd984029fc53f546ab55d0f343222..e77e52c8a2b7d2292d005ec67814b1e4cfe883ea 100644 (file)
@@ -1,12 +1,12 @@
 package org.simantics.scl.compiler.elaboration.query.compilation;
 
-import gnu.trove.impl.Constants;
-import gnu.trove.map.hash.TObjectIntHashMap;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
 
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
 public class ConstraintCollectionContext {
     QueryCompilationContext context;
     ArrayList<Variable> variables = new ArrayList<Variable>();
index 0506f410c9e971e83dedd8ba05a04daf0d71a23f..d53e4d1f27e383e18d397f2438114f3dedd80fee 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.elaboration.query.compilation;
 
-import gnu.trove.map.hash.TLongObjectHashMap;
-import gnu.trove.procedure.TLongObjectProcedure;
-
 import java.util.ArrayList;
 import java.util.Collections;
 
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.procedure.TLongObjectProcedure;
+
 public class DynamicProgrammingOrdering {
     final ConstraintCollectionContext collectionContext;
     int variableCount;
index 0c7c21e3d0b8929e141bb702ce81c7ddd97efab8..c80d59f37f1f0f8191f230b343dc1644c3197fed 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query.compilation;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
@@ -15,6 +11,10 @@ import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.types.TVar;\r
 import org.simantics.scl.compiler.types.Type;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectObjectProcedure;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
 public class ExpressionConstraint extends QueryConstraint {\r
     Variable variable;\r
     Expression expression;\r
index 049625f6b44917eca6ea66f854e9b06613c14885..ee96433d3e11e35c7e98370916de82f6b3c0d7f8 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.elaboration.query.pre;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
@@ -16,7 +12,10 @@ 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 org.simantics.scl.compiler.types.Type;
+
+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
index 900c9627bc1fbbd2b98acedff7d44c45364de4c3..0a193d6c1e89806b0daff39a8b2ffc7c87ea2622 100644 (file)
@@ -1,6 +1,10 @@
 package org.simantics.scl.compiler.elaboration.relations;
 
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.newVar;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tuple;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.vars;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.common.names.Name;
index a14ddaf062b7435d96dcea3c7b974d3fa6c9e858..7b2f2a19e840e6f8dbde246e8631f99925ae3353 100644 (file)
@@ -4,7 +4,6 @@ import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
-import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 
index fb59470b37151cf6d2ee8031b05fed638190f65d..26111e0b43bf781e3e922debfb61ca1eb61e09b8 100644 (file)
@@ -9,14 +9,11 @@ import static org.simantics.scl.compiler.elaboration.expressions.Expressions.tup
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
 
 import org.simantics.scl.compiler.common.names.Name;
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.expressions.EApply;
 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.query.compilation.QueryCompilationContext;
-import org.simantics.scl.compiler.errors.Locations;
-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;
index d70bf785e250622fbb2d7987fc65550cf97b804c..6bf0f781bd04ac8edeca2772a4a8f655df458c56 100644 (file)
@@ -1,10 +1,5 @@
 package org.simantics.scl.compiler.elaboration.rules;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectObjectProcedure;
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import org.simantics.scl.compiler.common.names.Name;
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
@@ -15,6 +10,11 @@ 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.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
 public class TransformationRule extends Symbol {
     public static final TransformationRule[] EMPTY_ARRAY = new TransformationRule[0];
     
index 9b9647ee19bedfd7343fe3bfb79a6ad35bc46123..98e2467fa6d637fd1ffae602569d85723c2d0142 100644 (file)
@@ -1,14 +1,13 @@
 package org.simantics.scl.compiler.environment;\r
 \r
-import gnu.trove.procedure.TObjectProcedure;\r
-\r
 import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;\r
 import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
 import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
 import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.util.ProcedureType;\r
 \r
+import gnu.trove.procedure.TObjectProcedure;\r
+\r
 public abstract class AbstractLocalEnvironment implements LocalEnvironment {\r
 \r
     @Override\r
index 2fb5e41d769c1d02da6548407cd30347da92771d..e3280daf6e731494e40f2e968093dea2e0aae9ea 100644 (file)
@@ -1,12 +1,12 @@
 package org.simantics.scl.compiler.environment;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Collection;
 
 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
 import org.simantics.scl.compiler.module.Module;
 
+import gnu.trove.map.hash.THashMap;
+
 public class ConcreteEnvironment extends AbstractEnvironment {
 
     private final THashMap<String, Module> moduleMap;
index 9bffef06b5d93d3bfb4644e3dcf74640c287a49d..ed08b7b690864191f88cec3baf47cfd5d84c2ef9 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.environment;
 
-import gnu.trove.procedure.TObjectProcedure;
-
 import java.util.function.Consumer;
 
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
@@ -16,6 +14,8 @@ import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
 import org.simantics.scl.compiler.types.TCon;
 
+import gnu.trove.procedure.TObjectProcedure;
+
 public enum EmptyNamespace implements Namespace {
     INSTANCE;
 
index 11bc2577dfcaf41d92186bcbfa584387f440d16a..5a55a6ca130f81132d59a9ccf5dbe51884c9e346 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.environment;
 
-import gnu.trove.procedure.TObjectProcedure;
-
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
@@ -27,6 +25,8 @@ import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.Type;
 
+import gnu.trove.procedure.TObjectProcedure;
+
 public class Environments {
     /**
      * Get the SCLValue object representing an SCL value defined in a given environment.
index 4ea77a0e23e779942584cfbe3177c7a1e7f5bb2d..b40bd9cdbd16f7b2aea1d685c03220bb5a7688e6 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.environment;\r
 \r
-import gnu.trove.procedure.TObjectProcedure;\r
-\r
 import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.util.ProcedureType;\r
 \r
+import gnu.trove.procedure.TObjectProcedure;\r
+\r
 /**\r
  * Provides local variable names for expressions\r
  * that do not need to defined in any module.\r
index dc388a72c2ebfe2392cd58d8172113f7c9137baa..921b9029d2d2e7e028e8a1a746908f5305ef6324 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.environment;
 
-import gnu.trove.procedure.TObjectProcedure;
-
 import java.util.function.Consumer;
 
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
@@ -16,6 +14,8 @@ import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
 import org.simantics.scl.compiler.types.TCon;
 
+import gnu.trove.procedure.TObjectProcedure;
+
 public interface Namespace {
        /**
         * Find a sub-namespace with a given name
index 9fd58989d1f3b0e4953a8952990caa542b428311..bb98f1aa529b019274cf1252069126595a8db0df 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.environment;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-
 import java.util.ArrayList;
 import java.util.function.Consumer;
 
@@ -20,6 +17,9 @@ import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
 import org.simantics.scl.compiler.module.Module;
 import org.simantics.scl.compiler.types.TCon;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
 public class NamespaceImpl implements Namespace {
 
     private final THashMap<String, Namespace> namespaceMap;
index 3739edb528a76e475da7707751b8aee6f2544e80..8d97123f2e960e18392a2ee18e7bec8458cd0f9b 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.environment;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import java.util.Map;\r
 \r
 import org.simantics.scl.compiler.environment.NamespaceImpl.ModuleImport;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class NamespaceSpec {\r
     public final THashMap<String, NamespaceSpec> namespaceMap = new THashMap<String, NamespaceSpec>();\r
     public final THashMap<String, ModuleImport> moduleMap = new THashMap<String, ModuleImport>();\r
index 57159b861d7d42254266dda514db36410137157f..2749ae3050b271c92a6398ede78058d8e3b8002d 100644 (file)
@@ -1,10 +1,10 @@
 package org.simantics.scl.compiler.environment.filter;\r
 \r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import org.simantics.scl.compiler.elaboration.expressions.EVar;\r
 import org.simantics.scl.compiler.module.ImportDeclaration.ImportSpec;\r
 \r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class NamespaceFilters {\r
     public static NamespaceFilter createFromSpec(ImportSpec spec) {\r
         if(spec.hiding) {\r
index bd29b328b6328df57e063268485852dd6dc3e377..d754170124477850d66050d20e98c70685672d4d 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.errors;
 
-import gnu.trove.list.array.TIntArrayList;
-
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
 
+import gnu.trove.list.array.TIntArrayList;
+
 public class CompilationErrorFormatter {
 
     public static int[] rows(Reader reader) throws IOException {
index 9d6a5645ac1b52cd8bff29da183ea7b9bdb30d35..853f316eef342c12223faf57626c00d610b2d3b4 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.analysis;\r
 \r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import org.simantics.scl.compiler.common.names.Name;\r
 import org.simantics.scl.compiler.constants.SCLConstant;\r
 import org.simantics.scl.compiler.internal.codegen.references.Val;\r
@@ -11,6 +9,8 @@ import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
 import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;\r
 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
 \r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class LoopAnalysis {\r
 \r
     /**\r
index 5760890127cb89ef5a0d255f12fea785995db3f3..e580c7c790ffb41e6a77bf6d6921c86228298668 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.analysis;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.common.names.Name;\r
 import org.simantics.scl.compiler.constants.SCLConstant;\r
@@ -16,6 +13,9 @@ import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;
 import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;\r
 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public abstract class StatementBrowser {\r
 \r
     THashSet<SSABlock> visited;\r
index 0867b4b3f24d5a1207e578006f5c5dc7e7c29dbc..75429d9aee4a8b7691790231397d1156ecdf7d34 100644 (file)
@@ -1,9 +1,9 @@
 package org.simantics.scl.compiler.internal.codegen.optimization;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import org.simantics.scl.compiler.common.names.Name;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class OptimizationMap {\r
 \r
     public static final THashMap<Name, Optimization> OPTIMIZATIONS = new THashMap<Name, Optimization>();\r
index 803397ce6ea458018401925520e9404e2c825964..1c88ba0aa01637a42e9786597352be608c72e2ca 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.references;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.cojen.classfile.TypeDesc;
 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
 import org.simantics.scl.compiler.internal.codegen.ssa.binders.BoundVarBinder;
@@ -11,6 +9,8 @@ import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 
+import gnu.trove.map.hash.THashMap;
+
 public final class BoundVar extends Val {
     public BoundVarBinder parent;
     Type type;
index 392dfb2feb14234b4fc541fd6fd3e729638eeceb..9837fdb77a30ddd2f8cfee1372b3aa90f336453b 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.references;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.internal.codegen.types.BTypes;\r
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
@@ -11,6 +9,8 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 \r
 public abstract class Val implements IVal {\r
     \r
index 3af6a00731cf9ba8d9be957846df60a5c0df919b..730463ab25d1ca6016be54533714fe6112bfe65c 100644 (file)
@@ -10,21 +10,27 @@ import org.simantics.scl.compiler.internal.codegen.references.ValRef;
 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
 import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit;
 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
 import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
 import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
 import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
 import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.runtime.exceptions.MatchingException;
 
 public class Throw extends SSAExit {
 
-    private static final TypeDesc RuntimeException = 
+    public static final TypeDesc RuntimeException = 
             TypeDesc.forClass(RuntimeException.class);
+    public static final TypeDesc MatchingException = 
+            TypeDesc.forClass(MatchingException.class);
     
+    TypeDesc exceptionClass;
     String description;
     
-    public Throw(String description) {
+    public Throw(TypeDesc exceptionClass, String description) {
+        this.exceptionClass = exceptionClass;
         this.description = description;
     }
 
@@ -38,10 +44,14 @@ public class Throw extends SSAExit {
     public void generateCode(MethodBuilder mb) {
         //mb.push(exception.getBinding());
         //cb.mapLineNumber(location);
-        mb.newObject(RuntimeException);
+        mb.newObject(exceptionClass);
         mb.dup();
-        mb.loadConstant(description);
-        mb.invokeConstructor(RuntimeException, new TypeDesc[] {TypeDesc.STRING});
+        if(description == null)
+            mb.invokeConstructor(exceptionClass, Constants.EMPTY_TYPEDESC_ARRAY);
+        else {
+            mb.loadConstant(description);
+            mb.invokeConstructor(exceptionClass, new TypeDesc[] {TypeDesc.STRING});
+        }
         mb.throwObject();
     }
 
@@ -56,7 +66,7 @@ public class Throw extends SSAExit {
 
     @Override
     public SSAExit copy(CopyContext context) {
-        return new Throw(description);
+        return new Throw(exceptionClass, description);
     }
     
     @Override
index 8d5d24e3c421ea37a77406153286fafc1f8cdbfb..83b1e0cb67a81afe13249ace83f230097b2ed892 100644 (file)
@@ -28,7 +28,6 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
 import org.simantics.scl.compiler.types.util.MultiFunction;\r
-import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
 public class LetApply extends LetStatement implements ValRefBinder {\r
     private ValRef function;\r
index 7b1db339faed0fe8b39d43726130c0c2dc31d298..25d9c2544bffd4ab6bb8470ead45408e0900d683 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.ssa.statements;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
@@ -21,6 +18,9 @@ import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
 import org.simantics.scl.compiler.types.TVar;\r
 import org.simantics.scl.compiler.types.Type;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class LetFunctions extends SSAStatement implements FunctionBinder {\r
     long recursiveGroupLocation;\r
     SSAFunction firstFunction;\r
index c3db313ba282a11fc0b70af210b7f9c69220ce9a..42df431810b630cdaf35d7b1d2cebfb75b280aa9 100644 (file)
@@ -49,7 +49,7 @@ public class ClassBuilder {
         return new MethodBuilder(this, moduleBuilder, (access&Opcodes.ACC_STATIC) != 0, methodVisitor, params);
     }
     
-    private MethodVisitor augmentMethodVisitor(String methodName, MethodVisitor methodVisitor) {
+    private MethodVisitor augmentMethodVisitor(final String methodName, MethodVisitor methodVisitor) {
         if(SCLCompilerConfiguration.TRACE_MAX_METHOD_SIZE && moduleBuilder != null) {
             methodVisitor = new CodeSizeEvaluator(methodVisitor) {
                 @Override
index 2383c2051c2ab420187598c7c5d46f58ceecc014..e5fb40a8a709807d43d702e94b04cb70bbad92ad 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.utils;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;\r
 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;\r
@@ -13,6 +11,8 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.Types;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class CopyContext {\r
 \r
     THashMap<Val, Val> valMap = new THashMap<Val, Val>();\r
index 4a8969f14a835345bff004bf7eb899cd4549939d..88556fdb77ba639d2b737e71c0cc7ff395f813df 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.utils;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import java.util.ArrayDeque;\r
 import java.util.ArrayList;\r
 \r
@@ -18,6 +15,9 @@ import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
 import org.simantics.scl.compiler.types.Type;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class PrintingContext {\r
 \r
     THashMap<Object, String> names = new THashMap<Object, String>(); \r
index bf2143c9c903cf24ca463dd3dfb8b42c47e3d092..8dd7a2875b488aa8c9453a673bb1f3a345b7027e 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.utils;
 
-import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
 import org.cojen.classfile.TypeDesc;
 import org.simantics.scl.runtime.SCLContext;
 
index d58d2dd7aab1f2b46701c5cdd9cc30952c67230a..923acdba26115c6cd18d2a95d3bc15267a9a5536 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.utils;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.procedure.TObjectIntProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.constants.Constant;
 import org.simantics.scl.compiler.constants.SCLConstant;
@@ -17,6 +13,10 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.procedure.TObjectIntProcedure;
+import gnu.trove.set.hash.THashSet;
+
 public class SSAValidationContext {
 
     public THashSet<BoundVar> validBoundVariables = new THashSet<BoundVar>();
index f11babe06bd3ef8e110fc00d4a719cf72b424293..6bed9f0661fc854b86afa24738bc3eb6dc032f91 100644 (file)
-package org.simantics.scl.compiler.internal.codegen.writer;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.Branch;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;\r
-import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
-import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.If;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;\r
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.util.MultiFunction;\r
-\r
-public class CodeWriter {\r
-\r
-    ModuleWriter moduleWriter;\r
-    SSABlock block;\r
-    \r
-    CodeWriter(ModuleWriter moduleWriter, SSABlock block) {\r
-        this.moduleWriter = moduleWriter;\r
-        this.block = block;\r
-    }\r
-\r
-    public IVal apply(int lineNumber, IVal function, IVal ... parameters) {\r
-        try {\r
-            MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);\r
-            return applyWithEffect(lineNumber,\r
-                    mfun.effect,\r
-                    mfun.returnType,\r
-                    function, parameters);\r
-        } catch (MatchException e) {\r
-            throw new InternalCompilerError(e);\r
-        }\r
-    }\r
-    \r
-    public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {\r
-        try {\r
-            MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);\r
-            if(!Types.equals(effect, mfun.effect))\r
-                throw new InternalCompilerError();\r
-            if(!Types.equals(returnType, mfun.returnType))\r
-                throw new InternalCompilerError();\r
-        } catch (MatchException e) {\r
-            throw new InternalCompilerError(e);\r
-        }            \r
-        return applyWithEffect(lineNumber, effect, returnType, function, parameters);\r
-    }\r
-    \r
-    public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) {\r
-        BoundVar var = new BoundVar(returnType);\r
-        LetApply apply = new LetApply(var,\r
-                effect,\r
-                function.createOccurrence(), \r
-                ValRef.createOccurrences(parameters));\r
-        apply.location = location;\r
-        block.addStatement(apply);\r
-        return var;\r
-    }\r
-    \r
-    public CodeWriter createBlock(Type ... parameterTypes) {\r
-        SSABlock newBlock = new SSABlock(parameterTypes);\r
-        block.getParent().addBlock(newBlock);\r
-        return new CodeWriter(moduleWriter, newBlock);\r
-    }\r
-    \r
-    public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {\r
-        if(SCLCompilerConfiguration.DEBUG)\r
-            if(effect == null)\r
-                throw new InternalCompilerError();\r
-        SSAFunction function = new SSAFunction(typeParameters, effect, returnType);\r
-        SSABlock block = new SSABlock(parameterTypes);\r
-        function.addBlock(block);\r
-        BoundVar target = new BoundVar(function.getType());\r
-        function.setTarget(target);\r
-        \r
-        this.block.addStatement(new LetFunctions(function));\r
-        return new CodeWriter(moduleWriter, block);\r
-    }\r
-    \r
-    public RecursiveDefinitionWriter createRecursiveDefinition() {\r
-        LetFunctions let = new LetFunctions();\r
-        block.addStatement(let);\r
-        return new RecursiveDefinitionWriter(moduleWriter, let);\r
-    }\r
-    \r
-    public void continueAs(CodeWriter codeWriter) {\r
-        this.block = codeWriter.block;\r
-        codeWriter.block = null;\r
-    }\r
-    \r
-    public IVal[] getParameters() {\r
-        return block.getParameters();\r
-    }\r
-    \r
-    public ICont getContinuation() {\r
-        return block;\r
-    }\r
-    \r
-    public void jump(ICont cont, IVal ... parameters) {\r
-        block.setExit(new Jump(cont.createOccurrence(), \r
-                ValRef.createOccurrences(parameters)));\r
-        block = null;\r
-    }\r
-    \r
-    public void if_(IVal condition, ICont thenTarget, ICont elseTarget) {\r
-        block.setExit(new If(condition.createOccurrence(), \r
-                thenTarget.createOccurrence(), \r
-                elseTarget.createOccurrence()));\r
-        block = null;\r
-    }\r
-\r
-    public void return_(IVal val) {\r
-        jump(block.getParent().getReturnCont(), val);\r
-    }\r
-\r
-    public void switch_(IVal val, Branch[] branches) {\r
-        block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches)));\r
-        block = null;\r
-    }\r
-\r
-    public void throw_(long location, String description) {\r
-        Throw exit = new Throw(description);\r
-        exit.location = location;\r
-        block.setExit(exit);\r
-        block = null;\r
-    }\r
-    \r
-    public ModuleWriter getModuleWriter() {\r
-               return moduleWriter;\r
-       }\r
-\r
-    public SSAFunction getFunction() {\r
-        return block.getParent();\r
-    }        \r
-}\r
+package org.simantics.scl.compiler.internal.codegen.writer;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.codegen.continuations.Branch;
+import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;
+import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.If;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+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 org.simantics.scl.compiler.types.util.MultiFunction;
+
+public class CodeWriter {
+
+    ModuleWriter moduleWriter;
+    SSABlock block;
+    
+    CodeWriter(ModuleWriter moduleWriter, SSABlock block) {
+        this.moduleWriter = moduleWriter;
+        this.block = block;
+    }
+
+    public IVal apply(int lineNumber, IVal function, IVal ... parameters) {
+        try {
+            MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
+            return applyWithEffect(lineNumber,
+                    mfun.effect,
+                    mfun.returnType,
+                    function, parameters);
+        } catch (MatchException e) {
+            throw new InternalCompilerError(e);
+        }
+    }
+    
+    public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) {
+        try {
+            MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length);
+            if(!Types.equals(effect, mfun.effect))
+                throw new InternalCompilerError();
+            if(!Types.equals(returnType, mfun.returnType))
+                throw new InternalCompilerError();
+        } catch (MatchException e) {
+            throw new InternalCompilerError(e);
+        }            
+        return applyWithEffect(lineNumber, effect, returnType, function, parameters);
+    }
+    
+    public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) {
+        BoundVar var = new BoundVar(returnType);
+        LetApply apply = new LetApply(var,
+                effect,
+                function.createOccurrence(), 
+                ValRef.createOccurrences(parameters));
+        apply.location = location;
+        block.addStatement(apply);
+        return var;
+    }
+    
+    public CodeWriter createBlock(Type ... parameterTypes) {
+        SSABlock newBlock = new SSABlock(parameterTypes);
+        block.getParent().addBlock(newBlock);
+        return new CodeWriter(moduleWriter, newBlock);
+    }
+    
+    public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) {
+        if(SCLCompilerConfiguration.DEBUG)
+            if(effect == null)
+                throw new InternalCompilerError();
+        SSAFunction function = new SSAFunction(typeParameters, effect, returnType);
+        SSABlock block = new SSABlock(parameterTypes);
+        function.addBlock(block);
+        BoundVar target = new BoundVar(function.getType());
+        function.setTarget(target);
+        
+        this.block.addStatement(new LetFunctions(function));
+        return new CodeWriter(moduleWriter, block);
+    }
+    
+    public RecursiveDefinitionWriter createRecursiveDefinition() {
+        LetFunctions let = new LetFunctions();
+        block.addStatement(let);
+        return new RecursiveDefinitionWriter(moduleWriter, let);
+    }
+    
+    public void continueAs(CodeWriter codeWriter) {
+        this.block = codeWriter.block;
+        codeWriter.block = null;
+    }
+    
+    public IVal[] getParameters() {
+        return block.getParameters();
+    }
+    
+    public ICont getContinuation() {
+        return block;
+    }
+    
+    public void jump(ICont cont, IVal ... parameters) {
+        block.setExit(new Jump(cont.createOccurrence(), 
+                ValRef.createOccurrences(parameters)));
+        block = null;
+    }
+    
+    public void if_(IVal condition, ICont thenTarget, ICont elseTarget) {
+        block.setExit(new If(condition.createOccurrence(), 
+                thenTarget.createOccurrence(), 
+                elseTarget.createOccurrence()));
+        block = null;
+    }
+
+    public void return_(IVal val) {
+        jump(block.getParent().getReturnCont(), val);
+    }
+
+    public void switch_(IVal val, Branch[] branches) {
+        block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches)));
+        block = null;
+    }
+
+    public void throw_(long location, TypeDesc exceptionClass, String description) {
+        Throw exit = new Throw(exceptionClass, description);
+        exit.location = location;
+        block.setExit(exit);
+        block = null;
+    }
+    
+    public ModuleWriter getModuleWriter() {
+               return moduleWriter;
+       }
+
+    public SSAFunction getFunction() {
+        return block.getParent();
+    }        
+}
index 714f66b952fdba86910f0e270a8c2d64756f41dd..a0484176556009b895484aae50c526598d3a625d 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.codegen.writer;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Map;
 
 import org.simantics.scl.compiler.common.names.Name;
@@ -15,6 +13,8 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.runtime.tuple.Tuple2;
 
+import gnu.trove.map.hash.THashMap;
+
 public class ModuleWriter {
     
     SSAModule module;
index b2489466094cf7a301291d3ba3f3d7ce2437ebbd..0267692548c25aba1121f32d17cb88f5cc16d7b1 100644 (file)
@@ -1,10 +1,10 @@
 package org.simantics.scl.compiler.internal.deriving;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import org.simantics.scl.compiler.types.TCon;\r
 import org.simantics.scl.compiler.types.Types;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class InstanceDerivers {\r
     private static final THashMap<TCon, InstanceDeriver> MAP = \r
             new THashMap<TCon, InstanceDeriver>();\r
index d19dfeec10f7243e43211d32b8c43c39beaa49d7..82df9000799336691ccd77ad4287c8384cc64959 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.constraints;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.cojen.classfile.TypeDesc;
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.constants.ClassConstant;
@@ -26,6 +24,8 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.map.hash.THashMap;
+
 public class ConstraintEnvironment {
     Environment environment;
     
index 1473ab9c465335738f584242e47b6e7f5d137a30..4b516a734d74b49a9c4c235d7eb84039ac1f8bec 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.constraints;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
@@ -13,6 +10,9 @@ import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 class ConstraintSet {
     
     private static int id = 0;
index dfff76475135ab9ec1fc5b694421c25de5e32122..dd91efb70feff2aba4eea80f9264f6a5365f2429 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.constraints;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
 import java.util.Collections;\r
@@ -20,6 +17,9 @@ import org.simantics.scl.compiler.types.exceptions.UnificationException;
 import org.simantics.scl.compiler.types.util.TConComparator;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class ConstraintSolver {\r
 \r
     public static THashSet<TCon> DEFAULTS_IGNORE = new THashSet<TCon>(); \r
index 3b0447394503f142c8c054b339a0480163d2047d..871fc012517df58faae3027ea43ed47ecd4ccac3 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.constraints;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-\r
 import java.util.ArrayList;\r
 \r
 import org.simantics.scl.compiler.types.TApply;\r
@@ -11,6 +8,9 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;\r
 import org.simantics.scl.compiler.types.util.MultiApply;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectObjectProcedure;\r
+\r
 public class InstanceTree<T> {\r
 \r
     Node<T> root;\r
index 652bc00b4809d8083652b3068afbf78f88bdc677..4bd7532b4ebe01543272b21b0da6ab03658d80ed 100644 (file)
@@ -1,13 +1,13 @@
 package org.simantics.scl.compiler.internal.elaboration.constraints2;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectObjectProcedure;
-
 import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.TPred;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+
 public class ConstraintSolver {
     final Environment environment;
     private final THashMap<TCon, ConstraintStore> constraintStores = 
index b4f2dcfa330a698e9ab58a2bcd880ccc407611ef..34973ab4551970c2801c9ea2e3080893e4827987 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.constraints2;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
@@ -14,6 +11,9 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
 class ConstraintStore {
 
     private final ConstraintSolver solver;
index 1ca1e7c3071707e09061cda747da59a6211ccbbe..7f200a11c40167e48875f48ddc97d614ffeb33af 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.matching;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -27,6 +25,8 @@ import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 
+import gnu.trove.map.hash.THashMap;
+
 public class PatternMatchingCompiler {
 
     private static class ExpressionMatrix {
index 930dfe14b547208cb2dba5e228379aa700491b6e..dff4622215473df74bced2f8bcebca7da746dc9a 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.internal.elaboration.profiling;
 import java.util.ArrayList;
 
 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;
@@ -159,6 +160,12 @@ public class BranchPointInjector extends StandardExpressionTransformer {
         return expression;
     }
     
+    @Override
+    public Expression transform(EAmbiguous expression) {
+        ++codeCounter;
+        return super.transform(expression);
+    }
+    
     @Override
     public Expression transform(EApply expression) {
         ++codeCounter;
index 34b34eccef4fc24e137634b2d433ce67e887c167..70adf524b501592229f21d1f8ed201149f9f7e72 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.subsumption;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import java.util.ArrayDeque;\r
 import java.util.ArrayList;\r
 \r
@@ -16,6 +13,9 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.util.Polarity;\r
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class SubSolver {\r
 \r
     public static final boolean DEBUG = false;\r
index bfffd2c6e74a6a1e40a902f7645a528256a6d14b..28ea97dfb4a754b6984fe13d2d92f8f8a2b63741 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.transformations;
 
-import gnu.trove.procedure.TObjectObjectProcedure;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
@@ -11,6 +9,8 @@ import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
 import org.simantics.scl.compiler.elaboration.rules.SectionName;
 import org.simantics.scl.compiler.elaboration.rules.TransformationRule;
 
+import gnu.trove.procedure.TObjectObjectProcedure;
+
 public class DecomposedRule {
     final TransformationRule rule;
     final ArrayList<Query> sourceQueries = new ArrayList<Query>();
index 0beb90f83126543a305f48085c2c1c7cf397095c..dcb212488972f04954a6e9e13b05e734894040ea 100644 (file)
@@ -1,10 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.transformations;
 
-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 java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -38,11 +33,15 @@ import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.elaboration.utils.ForcedClosure;
 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
-import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.Type;
 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;
+
 public class TransformationBuilder {
     private static final TCon UMap = Types.con("Unification", "UMap");
     private static final Name createUMap = Name.create("Unification", "createUMap");
index 0daeb02aea051953e3ab53b4de5b6f0f486bdb7f..7b3face61c962d3b89dbe54c4c0361914762d311 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.internal.elaboration.transformations;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
@@ -25,7 +22,7 @@ import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
 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.types.TypeHashCodeContext;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
@@ -33,6 +30,9 @@ import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.MultiApply;
 import org.simantics.scl.compiler.types.util.MultiFunction;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class UnifiableFactory {
     private static final TCon Unifiable = Types.con("Unification", "Unifiable");
     private static final Name uVar = Name.create("Unification", "uVar");
@@ -245,11 +245,11 @@ public class UnifiableFactory {
         @Override
         public int hashCode() {
             if(hashCode == 0) {
-                TypeHashCodeContext hcContext = new TypeHashCodeContext();
-                hcContext.append(function.hashCode());
+                int hash = HashCodeUtils.SEED;
+                hash = HashCodeUtils.update(hash, function.hashCode());
                 for(Type typeParameter : typeParameters)
-                    typeParameter.updateHashCode(hcContext);
-                hashCode = hcContext.getResult();
+                    hash = typeParameter.hashCode(hash);
+                hashCode = hash;
             }
             return hashCode;
         }
index e44a18879df0a6368c7060dfaa817efe9c5e02bf..5d7e9172c737e845c1608f65b93e9f40b2d6da84 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.internal.parsing.declarations;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.elaboration.query.Query;
 
+import gnu.trove.map.hash.THashMap;
+
 public class DRuleAst extends DeclarationAst {
     public final boolean isAbstract;
     public final String name;
index d94d6c12345510e39c4f8c438c38836415c0ebac..a0ac1cc4fab8bb6f331013eadde181d50e1aa709 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.parsing.translation;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import java.util.ArrayList;\r
 import java.util.Collection;\r
 \r
@@ -9,6 +7,8 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;\r
 import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class RelationRepository {\r
     THashMap<String, ArrayList<DRelationAst>> relations = \r
             new THashMap<String, ArrayList<DRelationAst>>();\r
index bd563120bd49770a159cb2339e1f6ad445606d9b..bfde4677352e4cff7e74661811f8e654a91c8c02 100644 (file)
@@ -1,13 +1,13 @@
 package org.simantics.scl.compiler.internal.types;
 
-import gnu.trove.map.hash.THashMap;
-
 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;
 import org.simantics.scl.compiler.types.util.ITypeEnvironment;
 
+import gnu.trove.map.hash.THashMap;
+
 public class TypeElaborationContext {
 
     THashMap<String, TVar> vars; 
index 5e7aec1a0b4b9ded0efff5298963158578a37b2f..742325caaaacd4d49b3f2abc6894ce88947e5e26 100644 (file)
@@ -1,9 +1,9 @@
 package org.simantics.scl.compiler.internal.types;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-
 import org.simantics.scl.compiler.types.TVar;
 
+import gnu.trove.map.hash.TObjectIntHashMap;
+
 public class TypeHashCodeContext {
         
     public static final int APPLY = 0x12345678;
index 149e139bdbd1dff5d1e5b1bc17a16917cf326732..4168fff931241574484b794ce94e40fe4de043b0 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.internal.types.effects;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -11,6 +9,8 @@ import org.simantics.scl.compiler.types.TUnion;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 
+import gnu.trove.map.hash.TObjectIntHashMap;
+
 public class EffectIdMap {
 
     public static final int MIN = 0;
index f39901c3b9e4b0a60e61bd3cf167513bb5a17f7c..93c8c8d2f17ee8a816e7811f58b13d5eb8a0a6db 100644 (file)
@@ -1,15 +1,15 @@
 package org.simantics.scl.compiler.markdown.html;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectProcedure;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.List;\r
 \r
 import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectProcedure;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
 public class HierarchicalDocumentationRef implements Comparable<HierarchicalDocumentationRef> {\r
     final String name;\r
     final ArrayList<HierarchicalDocumentationRef> children = new ArrayList<HierarchicalDocumentationRef>();\r
index 6a505fabb272fe39786186ba25a655c8c9fe7708..d971f7d0faf8735fe1bb8377432e1de0fa34ff1b 100644 (file)
@@ -1,9 +1,5 @@
 package org.simantics.scl.compiler.markdown.html;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 import java.util.Collections;
 
@@ -27,6 +23,10 @@ import org.simantics.scl.compiler.types.TVar;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
 public class SCLDocumentationExtensionNodeHandler implements ExtensionNodeHandler {
 
     final ModuleRepository moduleRepository;
index f2d8917b88fb7aecf7b24e7f72850945d5df1386..9be7ca24b7264d4e010e16464eea7078a8fbcc97 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.markdown.inlines;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.nio.charset.Charset;
 
+import gnu.trove.map.hash.THashMap;
+
 public class Entities {
     public static final THashMap<String, String> ENTITY_MAP = new THashMap<String, String>();
     public static int MAX_ENTITY_LENGTH;
index 163d70708ce53ee5957bb27a24ec16be6b3cab80..a6a3abdae696095ae5c78ac68260de75d9b29e7b 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.markdown.inlines;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.simantics.scl.compiler.markdown.internal.Scanner;
 import org.simantics.scl.compiler.markdown.nodes.AutolinkNode;
 import org.simantics.scl.compiler.markdown.nodes.CodeNode;
@@ -14,6 +12,8 @@ import org.simantics.scl.compiler.markdown.nodes.Node;
 import org.simantics.scl.compiler.markdown.nodes.Reference;
 import org.simantics.scl.compiler.markdown.nodes.TextNode;
 
+import gnu.trove.map.hash.THashMap;
+
 public class Subject {
     THashMap<String, Reference> referenceMap;
     StringBuilder input;
index a31c70655364df5a1820bbf662ae971ce78a9146..bd2ba47b8eb9f31a7d5e03f299860c642913b072 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.markdown.internal;
 
-import gnu.trove.map.hash.TCharObjectHashMap;
-
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 
+import gnu.trove.map.hash.TCharObjectHashMap;
+
 public class HtmlEscape {
 
     private static final Charset UTF8 = Charset.forName("UTF-8");
index 7d30856c8d65b7a3491a7e924bb65434d2e27d93..eb4626f662ef38bc7face6bf34232d23a177be08 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.markdown.internal;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
@@ -20,6 +18,8 @@ import org.simantics.scl.compiler.markdown.nodes.Node;
 import org.simantics.scl.compiler.markdown.nodes.ParagraphNode;
 import org.simantics.scl.compiler.markdown.nodes.Reference;
 
+import gnu.trove.map.hash.THashMap;
+
 public class MarkdownParser {
     public static final boolean DEBUG = false;
     public static final int CODE_INDENT = 4;
index 437d80c117c1b3390751dcd01b157b9b46d1b8b0..0254e8e597301b3c757c5087912740823f522145 100644 (file)
@@ -1,9 +1,9 @@
 package org.simantics.scl.compiler.markdown.internal;
 
-import gnu.trove.set.hash.THashSet;
-
 import org.simantics.scl.compiler.markdown.inlines.Subject;
 
+import gnu.trove.set.hash.THashSet;
+
 public class Scanner {
 
     public int level;
index 54914dd42d7545acb2b804a2c145750898da5373..a5399e88f1f642c2212ee7004b8d60f8757df441 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.module;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Collection;
 import java.util.Collections;
 
@@ -20,6 +18,8 @@ import org.simantics.scl.compiler.top.ModuleInitializer;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.runtime.profiling.BranchPoint;
 
+import gnu.trove.map.hash.THashMap;
+
 public abstract class LazyModule implements Module {
 
     String moduleName;
index 3a39c4e0e2252ecc823eb238e2ba33cf601aaaaa..13157f9fbb26bc470d682a54de78ed05612f5cc3 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.module.repository;\r
 \r
-import gnu.trove.procedure.TObjectProcedure;\r
-\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 import java.util.regex.Pattern;\r
@@ -11,6 +9,8 @@ import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;
 import org.simantics.scl.compiler.errors.Failable;\r
 import org.simantics.scl.compiler.module.Module;\r
 \r
+import gnu.trove.procedure.TObjectProcedure;\r
+\r
 public class ModuleRepositories {\r
     public static List<SCLValue> allValuesMatching(final ModuleRepository repository, String pattern) {\r
         final Pattern compiledPattern = pattern == null ? null \r
index bb2e5efc0a7deb57fc5081c9918a7683f40775c6..c91daab91147480b6437b32a52be87a261b50261 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.runtime;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Map;
 
 import org.simantics.scl.compiler.constants.Constant;
 
+import gnu.trove.map.hash.THashMap;
+
 public class ExpressionClassLoader extends ClassLoader implements MutableClassLoader {
     public static final boolean VALIDATE_CLASS_NAMES = true;
     public static final boolean TRACE_CLASS_CREATION = false;
index 8fd9a7a0b3f81226b30a03076c8952cf326e618a..adf36f8af062a615b069bf86993233dc2d484759 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.runtime;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Map;
 
 import org.simantics.scl.compiler.constants.Constant;
 
+import gnu.trove.map.hash.THashMap;
+
 public interface MutableClassLoader {
 
     public static final String SCL_PACKAGE_PREFIX = "scl.";
index cbac0c85ac213df1a0b7cdcaf1c61836a9dfc58b..8d7080394fc59a64c06709bc0238e3cafd32129d 100644 (file)
@@ -1,9 +1,9 @@
 package org.simantics.scl.compiler.runtime;
 
-import gnu.trove.map.hash.THashMap;
-
 import org.simantics.scl.compiler.environment.Environment;
 
+import gnu.trove.map.hash.THashMap;
+
 public class RuntimeEnvironmentImpl implements RuntimeEnvironment {
 
     private final Environment environment;
index d1d897174e6ec19c77eddacd0c49dbb41c3d5115..80db43ef0b1e2debda2904a3dcc0d4ce6e3f1732 100644 (file)
@@ -1,9 +1,9 @@
 package org.simantics.scl.compiler.runtime;\r
 \r
-import gnu.trove.map.hash.THashMap;\r
-\r
 import java.util.Collection;\r
 \r
+import gnu.trove.map.hash.THashMap;\r
+\r
 public class RuntimeModuleMap {\r
     THashMap<String, RuntimeModule> moduleMap = new THashMap<String, RuntimeModule>(); \r
     \r
index efdc630000c9932a39a413509cbcccc64a1ff158..1316ee5d7075afcb65c05ec9aad3eaf5b1d0d2f1 100644 (file)
@@ -2,7 +2,6 @@ package org.simantics.scl.compiler.source;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.charset.Charset;
 
 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
 import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator;
index 310472cdc9838ccbfee1539b4f3b276d32536db5..873859a2de6a65c5a2eec24e853523bafae09913 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.source.repository;
 
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.io.IOException;
 import java.net.URL;
 
@@ -11,6 +8,9 @@ import org.simantics.scl.compiler.module.repository.UpdateListener;
 import org.simantics.scl.compiler.source.ClassModuleSource;
 import org.simantics.scl.compiler.source.ModuleSource;
 
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
 public class ClassModuleSourceRepository extends AbstractModuleSourceRepository {
     
     private final Class<?> clazz;
index ce3f775ce969ddb756064146dae9ba1e82dc4f50..82bb0bcf94368296ccc083adb5f3e6e196777878 100644 (file)
@@ -1,10 +1,10 @@
 package org.simantics.scl.compiler.source.repository;
 
-import gnu.trove.procedure.TObjectProcedure;
-
 import org.simantics.scl.compiler.module.repository.UpdateListener;
 import org.simantics.scl.compiler.source.ModuleSource;
 
+import gnu.trove.procedure.TObjectProcedure;
+
 public class CompositeModuleSourceRepository implements ModuleSourceRepository {
     public final ModuleSourceRepository[] children;
 
index 5a4e93ce57eb707530acd90cb09bc4177b3e2107..805dd77f465b90b999ecc27aec7f3a3643842139 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.scl.compiler.source.repository;
 
-import gnu.trove.procedure.TObjectProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.io.File;
 import java.io.IOException;
 
@@ -12,6 +9,9 @@ import org.simantics.scl.compiler.source.ClassModuleSource;
 import org.simantics.scl.compiler.source.FileModuleSource;
 import org.simantics.scl.compiler.source.ModuleSource;
 
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
 public class FileModuleSourceRepository extends AbstractModuleSourceRepository {
     
     private final File path;
index 6cbf03aef8756df416144fbf649922b40bb1f4b2..9872451c311e904cb72aec9bd34bad833184a240 100644 (file)
@@ -1,13 +1,13 @@
 package org.simantics.scl.compiler.source.repository;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TObjectProcedure;
-
 import org.simantics.scl.compiler.module.Module;
 import org.simantics.scl.compiler.module.repository.UpdateListener;
 import org.simantics.scl.compiler.source.ModuleSource;
 import org.simantics.scl.compiler.source.PrecompiledModuleSource;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
 /**
  * An implementation of {@link ModuleSourceRepository} as a finite map.
  * This implementation does not support listening module changes,
index 71e08dcd65979a3b7b2ccfa6cf3115dd35696363..76698f5be6a44d9cea0db368d933b2e2d3251deb 100644 (file)
@@ -1,11 +1,11 @@
 package org.simantics.scl.compiler.source.repository;
 
-import gnu.trove.procedure.TObjectProcedure;
-
 import org.simantics.scl.compiler.module.repository.ModuleRepository;
 import org.simantics.scl.compiler.module.repository.UpdateListener;
 import org.simantics.scl.compiler.source.ModuleSource;
 
+import gnu.trove.procedure.TObjectProcedure;
+
 /**
  * An interface for locating modules descriptors and listening if they change.
  * An instance of this interface is used to create a {@link ModuleRepository}.
index 6cb68b67364046470a52ebcc7b3c6486bfaf9480..5c8f59bb2dcee005fc5c006f72c4f453fa987990 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.top;
 
-import gnu.trove.set.hash.THashSet;
-
 import java.io.StringReader;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -59,6 +57,8 @@ import org.simantics.scl.compiler.types.util.ProcedureType;
 import org.simantics.scl.runtime.function.FunctionImpl1;
 import org.simantics.scl.runtime.tuple.Tuple0;
 
+import gnu.trove.set.hash.THashSet;
+
 public class ExpressionEvaluator {
 
     public static final boolean TRACE_INTERPRETATION_VS_COMPILATION = false;
index e80883969a95ed2c7453b45810fe544c5262ca4b..8b788c2ffe459faea2c045099cdc4e8efdfffdb2 100644 (file)
@@ -1,13 +1,13 @@
 package org.simantics.scl.compiler.top;
 
-import gnu.trove.impl.Constants;
-import gnu.trove.map.hash.TObjectIntHashMap;
-
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.elaboration.expressions.Variable;
 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
 
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
 
 public class ExpressionInterpretationContext {
 
index 799a1495addbe0897c8fcc8bb4dec0a37a3133ac..d7b896a98ff90edd0f2d60e917f8779c6537cb2e 100755 (executable)
@@ -33,4 +33,6 @@ public interface SCLCompilerConfiguration {
     public static final boolean EVERY_RULE_ENFORCEMENT_IN_SEPARATE_METHOD = true;
     public static final boolean EVERY_DATALOG_STRATUM_IN_SEPARATE_METHOD = true;
     
+    public static final boolean ALLOW_OVERLOADING = false;
+    
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Skeletons.java
new file mode 100644 (file)
index 0000000..81dec24
--- /dev/null
@@ -0,0 +1,292 @@
+package org.simantics.scl.compiler.types;
+
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
+import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
+import org.simantics.scl.compiler.types.exceptions.UnificationException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+import gnu.trove.map.hash.THashMap;
+
+public class Skeletons {
+    
+    public static Type canonicalSkeleton(Type type) {
+        while(type instanceof TMetaVar) {
+            TMetaVar metaVar = (TMetaVar)type;
+            if(metaVar.ref != null)
+                type = metaVar.ref;
+            else if(metaVar.skeletonRef != null)
+                type = metaVar.skeletonRef;
+            else
+                return metaVar;
+        }
+        return type;
+    }
+    
+    public static Type canonicalSkeleton(THashMap<TMetaVar,Type> unifications, Type type) {
+        while(type instanceof TMetaVar) {
+            TMetaVar metaVar = (TMetaVar)type;
+            if(metaVar.ref != null)
+                type = metaVar.ref;
+            else if(metaVar.skeletonRef != null)
+                type = metaVar.skeletonRef;
+            else {
+                Type temp = unifications.get(metaVar);
+                if(temp == null)
+                    return metaVar;
+                else
+                    type = temp;
+            }
+        }
+        return type;
+    }
+    
+    public static boolean doesSkeletonContain(THashMap<TMetaVar,Type> unifications, Type type, TMetaVar metaVar) {
+        type = canonicalSkeleton(unifications, type);
+        if(type == metaVar)
+            return true;
+        if(type instanceof TFun) {
+            TFun fun = (TFun)type;
+            return doesSkeletonContain(unifications, fun.domain, metaVar)
+                    || doesSkeletonContain(unifications, fun.range, metaVar); 
+        }
+        if(type instanceof TApply) {
+            TApply apply = (TApply)type;
+            return doesSkeletonContain(unifications, apply.function, metaVar)
+                    || doesSkeletonContain(unifications, apply.parameter, metaVar); 
+        }
+        if(type instanceof TForAll) {
+            TForAll forAll = (TForAll)type;
+            return doesSkeletonContain(unifications, forAll.type, metaVar); 
+        }
+        if(type instanceof TPred) {
+            TPred pred = (TPred)type;
+            for(Type param : pred.parameters)
+                if(doesSkeletonContain(unifications, param, metaVar))
+                    return true;
+            return false;
+        }
+        else
+            return false;
+    }
+
+    /**
+     * Returns true, if unification of the skeletons of the types would succeed.
+     */
+    public static boolean areSkeletonsCompatible(THashMap<TMetaVar,Type> unifications, Type a, Type b) {
+        a = canonicalSkeleton(unifications, a);
+        b = canonicalSkeleton(unifications, b);
+        if(a == b)
+            return true;
+        Class<?> ca = a.getClass();
+        Class<?> cb = b.getClass();
+        
+        if(ca == TMetaVar.class) {
+            TMetaVar ma = (TMetaVar)a;
+            if(doesSkeletonContain(unifications, b, ma))
+                return false;
+            unifications.put(ma, b);
+            return true;
+        }
+        if(cb == TMetaVar.class) {
+            TMetaVar mb = (TMetaVar)b;
+            if(doesSkeletonContain(unifications, a, mb))
+                return false;
+            unifications.put(mb, a);
+            return true;
+        }
+        if(ca != cb)
+            return false;
+        if(ca == TFun.class) {
+            TFun funA = (TFun)a;
+            TFun funB = (TFun)b;
+            return areSkeletonsCompatible(unifications, funA.domain, funB.domain)
+                    && areSkeletonsCompatible(unifications, funA.range, funB.range);
+        }
+        if(ca == TApply.class) {
+            TApply applyA = (TApply)a;
+            TApply applyB = (TApply)b;
+            return areSkeletonsCompatible(unifications, applyA.function, applyB.function)
+                    && areSkeletonsCompatible(unifications, applyA.parameter, applyB.parameter);
+        }
+        if(ca == TPred.class) {
+            TPred predA = (TPred)a;
+            TPred predB = (TPred)b;
+            if(predA.typeClass != predB.typeClass)
+                return false;
+            for(int i=0;i<predA.parameters.length;++i)
+                if(!areSkeletonsCompatible(unifications, predA.parameters[i], predB.parameters[i]))
+                    return false;
+            return true;
+        }
+        if(ca == TForAll.class) {
+            TForAll forAllA = (TForAll)a;
+            TForAll forAllB = (TForAll)b;
+            TVar temp = Types.var(forAllA.var.getKind());
+            return areSkeletonsCompatible(unifications,
+                    forAllA.type.replace(forAllA.var, temp),
+                    forAllB.type.replace(forAllB.var, temp));
+        }
+        return false;
+    }
+
+    public static void unifySkeletons(Type a, Type b) throws UnificationException {
+        a = canonicalSkeleton(a);
+        b = canonicalSkeleton(b);
+        
+        if(a == b)
+            return;
+        if(a instanceof TMetaVar) {
+            ((TMetaVar) a).setSkeletonRef(b);
+            return;
+        }
+        if(b instanceof TMetaVar) {
+            ((TMetaVar) b).setSkeletonRef(a);
+            return;
+        }
+        
+        Class<?> ca = a.getClass();
+        Class<?> cb = b.getClass();
+        if(ca != cb) {
+            throw new UnificationException(a, b);
+        }
+        if(ca == TApply.class) 
+            //unifySkeletons((TApply)a, (TApply)b);
+            Types.unify(a, b);
+        else if(ca == TFun.class) 
+            unifySkeletons((TFun)a, (TFun)b);
+        else if(ca == TForAll.class)
+            unifySkeletons((TForAll)a, (TForAll)b);
+        else if(ca == TPred.class) 
+            //unifySkeletons((TPred)a, (TPred)b);
+            Types.unify(a, b);
+        else if(ca == TUnion.class) 
+            unifySkeletons((TUnion)a, (TUnion)b);
+        else // ca == TCon.class || ca = TVar.class 
+            throw new UnificationException(a, b);
+    }
+    
+    public static void unifySkeletons(TFun a, TFun b) throws UnificationException {
+        unifySkeletons(a.domain, b.domain);
+        unifySkeletons(a.range, b.range);
+    }
+
+    public static void unifySkeletons(TApply a, TApply b) throws UnificationException {
+        unifySkeletons(a.function, b.function);
+        unifySkeletons(a.parameter, b.parameter);
+    }
+
+    public static void unifySkeletons(TForAll a, TForAll b) throws UnificationException {
+        try {
+            Kinds.unify(a.var.getKind(), b.var.getKind());
+        } catch (KindUnificationException e) {
+            throw new UnificationException(a, b);
+        }
+        TVar newVar = Types.var(a.var.getKind());
+        unifySkeletons(a.type.replace(a.var, newVar), b.type.replace(b.var, newVar));
+    }
+
+    public static void unifySkeletons(TPred a, TPred b) throws UnificationException {
+        if(a.typeClass != b.typeClass
+                || a.parameters.length != b.parameters.length)
+            throw new UnificationException(a, b);
+        for(int i=0;i<a.parameters.length;++i)
+            unifySkeletons(a.parameters[i], b.parameters[i]);
+    }
+
+    public static void unifySkeletons(TUnion a, TUnion b) throws UnificationException {
+        // Nothing to do
+    }
+    
+    public static Type commonSkeleton(Environment context, Type[] types) {
+        THashMap<Type[], TMetaVar> metaVarMap = new THashMap<Type[], TMetaVar>() {
+            @Override
+            protected boolean equals(Object a, Object b) {
+                return Types.equals((Type[])a, (Type[])b);
+            }
+            @Override
+            protected int hash(Object a) {
+                Type[] types = (Type[])a;
+                int hash = HashCodeUtils.SEED;
+                for(Type type : types)
+                    hash = type.hashCode(hash);
+                return hash;
+            }
+        };
+        return commonSkeleton(context, metaVarMap, types);
+    }
+
+    private static TMetaVar metaVarFor(Environment context, THashMap<Type[], TMetaVar> metaVarMap, Type[] types) {
+        TMetaVar result = metaVarMap.get(types);
+        if(result == null) {
+            try {
+                result = Types.metaVar(types[0].inferKind(context));
+            } catch (KindUnificationException e) {
+                result = Types.metaVar(Kinds.STAR);
+            }
+            metaVarMap.put(types, result);
+        }
+        return result;
+    }
+    
+    /**
+     * Finds the most specific type that can be unified with the all the types
+     * given as a parameter.
+     */
+    private static Type commonSkeleton(Environment context, THashMap<Type[], TMetaVar> metaVarMap, Type[] types) {
+        for(int i=0;i<types.length;++i)
+            types[i] = canonicalSkeleton(types[i]);
+
+        Type first = types[0];
+        Class<?> clazz = first.getClass();
+        for(int i=1;i<types.length;++i)
+            if(types[i].getClass() != clazz)
+                return metaVarFor(context, metaVarMap, types);
+
+        if(clazz == TCon.class) {
+            for(int i=1;i<types.length;++i)
+                if(types[i] != first)
+                    return metaVarFor(context, metaVarMap, types);
+            return first;
+        }
+        else if(clazz == TApply.class) {
+            Type[] functions = new Type[types.length];
+            Type[] parameters = new Type[types.length];
+            for(int i=0;i<types.length;++i) {
+                TApply apply = (TApply)types[i];
+                functions[i] = apply.function;
+                parameters[i] = apply.parameter;
+            }
+            return Types.apply(
+                    commonSkeleton(context, metaVarMap, functions),
+                    commonSkeleton(context, metaVarMap, parameters));
+        }
+        else if(clazz == TFun.class) {
+            Type[] domains = new Type[types.length];
+            Type[] effects = new Type[types.length];
+            Type[] ranges = new Type[types.length];
+            for(int i=0;i<types.length;++i) {
+                TFun fun = (TFun)types[i];
+                if(fun.domain instanceof TPred)
+                    return metaVarFor(context, metaVarMap, types);
+                domains[i] = fun.domain;
+                effects[i] = fun.effect;
+                ranges[i] = fun.range;
+            }
+            return Types.functionE(
+                    commonSkeleton(context, metaVarMap, domains),
+                    commonEffect(effects),
+                    commonSkeleton(context, metaVarMap, ranges));
+        }
+        else
+            return metaVarFor(context, metaVarMap, types);
+    }
+
+    private static Type commonEffect(Type[] effects) {
+        Type first = effects[0];
+        for(int i=1;i<effects.length;++i)
+            if(!Types.equals(first, effects[i]))
+                return Types.metaVar(Kinds.EFFECT);
+        return first;
+    }
+}
index ced969286a869109ea739c2ff7fdb76edb888a14..88d80882e67312989f945ee6a81524b79418fcad 100644 (file)
@@ -1,12 +1,10 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 import java.util.List;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TApplyAst;
 import org.simantics.scl.compiler.internal.types.ast.TListAst;
@@ -19,6 +17,9 @@ import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TMultiApply;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 
 
 /**
@@ -26,8 +27,8 @@ import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
  * @author Hannu Niemist&ouml;
  */
 public class TApply extends Type {
-    public final Type function;
-    public final Type parameter;
+    public Type function;
+    public Type parameter;
     
     public TApply(Type function, Type parameter) {
         if(NULL_CHECKS) {
@@ -156,6 +157,12 @@ public class TApply extends Type {
         Kind parameterKind = parameter.inferKind(context);
         Kinds.unify(functionKind, Kinds.arrow(parameterKind, requiredKind));
     }
+       
+       @Override
+       public Kind getKind(Environment context) {
+           Kind functionKind = function.getKind(context);
+           return Kinds.rangeOfArrow(functionKind);
+       }
 
     @Override
     public boolean containsMetaVars() {
@@ -194,4 +201,43 @@ public class TApply extends Type {
         else
             return new TApply(newFunction, newParameter);
     }
+
+    @Override
+    public int hashCode(int hash) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, APPLY_HASH);
+        hash = function.hashCode(hash);
+        hash = parameter.hashCode(hash);
+        return hash;
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, APPLY_HASH);
+        hash = function.hashCode(hash, boundVars);
+        hash = parameter.hashCode(hash, boundVars);
+        return hash;
+    }
+    
+    public Type getCanonicalFunction() {
+        if(function instanceof TMetaVar)
+            function = function.canonical();
+        return function;
+    }
+    
+    public Type getCanonicalParameter() {
+        if(parameter instanceof TMetaVar)
+            parameter = parameter.canonical();
+        return parameter;
+    }
+    
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TApply.class))
+            return false;
+        TApply apply = (TApply)other;
+        return getCanonicalFunction().equalsCanonical(apply.getCanonicalFunction())
+                && getCanonicalParameter().equalsCanonical(apply.getCanonicalParameter());
+    }
 }
index 7e9d25001cbfa42f4fe38672e083e1c320935d74..16e0c29eb5b962634cce80b8fe82f904f612461d 100644 (file)
@@ -1,12 +1,10 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.internal.codegen.utils.NameMangling;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TConAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
@@ -15,10 +13,13 @@ import org.simantics.scl.compiler.types.kinds.Kind;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 /**
  * This class represents an SCL type constant with a name given in a module.
  */
-public class TCon extends Type {
+public final class TCon extends Type {
     public final String module;
     public final String name;
 
@@ -104,6 +105,10 @@ public class TCon extends Type {
        public Kind inferKind(Environment context) throws KindUnificationException {
         return context.getTypeConstructor(this).kind;
     }
+       
+       public Kind getKind(Environment context) {
+           return context.getTypeConstructor(this).kind;
+       }
 
     @Override
     public boolean containsMetaVars() {
@@ -148,4 +153,19 @@ public class TCon extends Type {
     public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
         return this;
     }
+
+    @Override
+    public int hashCode(int hash) {
+        return HashCodeUtils.update(hash, System.identityHashCode(this));
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        return HashCodeUtils.update(hash, System.identityHashCode(this));
+    }
+    
+    @Override
+    public boolean equalsCanonical(Type other) {
+        return this == other;
+    }
 }
index a22a4b244853406f0ca83dbfaff4d72e5c6ef16e..98b4578af676642e54288a161037eda249314150 100644 (file)
@@ -1,12 +1,10 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
+import java.util.Arrays;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TForAllAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
@@ -16,10 +14,14 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 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;
+
 
 public class TForAll extends Type {
     public final TVar var;
-    public final Type type;
+    public Type type;
     
     TForAll(TVar var, Type type) {
         if(NULL_CHECKS) {
@@ -150,4 +152,76 @@ public class TForAll extends Type {
         // Should never get here
         return new TMetaVar(Kinds.STAR);
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        int count=1;
+        {
+            Type t = Types.canonical(type);
+            while(t instanceof TForAll) {
+                t = Types.canonical( ((TForAll)t).type );
+                ++count;
+            }
+        }
+        TVar[] boundVars = new TVar[count];
+        boundVars[0] = var;
+        TForAll t = this;
+        {
+            for(int i=1;i<count;++i) {
+                t = (TForAll)Types.canonical(t.type);
+                boundVars[i] = t.var;
+            }
+        }
+        
+        for(int i=0;i<count;++i)
+            hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+        return t.type.hashCode(hash, boundVars);
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] oldBoundVars) {
+        int count=1;
+        {
+            Type t = Types.canonical(type);
+            while(t instanceof TForAll) {
+                t = Types.canonical( ((TForAll)t).type );
+                ++count;
+            }
+        }
+        TVar[] boundVars = Arrays.copyOf(oldBoundVars, oldBoundVars.length + count);
+        boundVars[oldBoundVars.length] = var;
+        TForAll t = this;
+        {
+            for(int i=1;i<count;++i) {
+                t = (TForAll)Types.canonical(t.type);
+                boundVars[oldBoundVars.length + i] = t.var;
+            }
+        }
+        
+        for(int i=0;i<count;++i)
+            hash = HashCodeUtils.updateWithPreprocessedValue(hash, FORALL_HASH);
+        return t.type.hashCode(hash, boundVars);
+    }
+    
+    public Type getCanonicalType() {
+        if(type instanceof TMetaVar)
+            type = type.canonical();
+        return type;
+    }
+
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TForAll.class))
+            return false;
+        TForAll forAll = (TForAll)other;
+        return getCanonicalType().equalsCanonical(forAll.getCanonicalType().replace(forAll.var, var));
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.STAR;
+    } 
+    
 }
index 917526dd0bd4494bfa3e4dc73f295f2a0cc3befd..e26c5b07ac923922a8c4e4270ede948b3b1f3cbb 100644 (file)
@@ -1,11 +1,9 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TEffectAst;
 import org.simantics.scl.compiler.internal.types.ast.TFunctionAst;
@@ -17,10 +15,13 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class TFun extends Type {
-    public final Type domain;
-    public final Type effect;
-    public final Type range;
+    public Type domain;
+    public Type effect;
+    public Type range;
     
     TFun(Type domain, Type effect, Type range) {
         if(domain == null)
@@ -189,4 +190,57 @@ public class TFun extends Type {
         Type newRange = range.copySkeleton(metaVarMap);
         return new TFun(newDomain, newEffect, newRange);
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+        hash = domain.hashCode(hash);
+        hash = effect.hashCode(hash);
+        hash = range.hashCode(hash);
+        return hash;
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, FUN_HASH);
+        hash = domain.hashCode(hash, boundVars);
+        hash = effect.hashCode(hash, boundVars);
+        hash = range.hashCode(hash, boundVars);
+        return hash;
+    }
+    
+    public Type getCanonicalDomain() {
+        if(domain instanceof TMetaVar)
+            domain = domain.canonical();
+        return domain;
+    }
+    
+    public Type getCanonicalEffect() {
+        if(effect instanceof TMetaVar)
+            effect = effect.canonical();
+        return effect;
+    }
+    
+    public Type getCanonicalRange() {
+        if(range instanceof TMetaVar)
+            range = range.canonical();
+        return range;
+    }
+
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TFun.class))
+            return false;
+        TFun fun = (TFun)other;
+        return getCanonicalDomain().equalsCanonical(fun.getCanonicalDomain())
+                && getCanonicalEffect().equalsCanonical(fun.getCanonicalEffect())
+                && getCanonicalRange().equalsCanonical(fun.getCanonicalRange());
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.STAR;
+    }
 }
index 8d2307b232423d33182cfb8a130bc912af52012a..0d3114fc5765b0bad9a3ad11df5aaef8dc803bf1 100644 (file)
@@ -1,11 +1,10 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TVarAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
@@ -17,6 +16,9 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 
 
 /**
@@ -28,10 +30,34 @@ import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
  */
 public class TMetaVar extends Type {
     public static final TMetaVar[] EMPTY_ARRAY = new TMetaVar[0];
+    public static final boolean DEBUG = false;
     
     Type ref = null;
+    Type skeletonRef = null;
     Polarity polarity = Polarity.NO_POLARITY;
     private Kind kind;
+    private TMetaVarListener listener;
+    
+    public static abstract class TMetaVarListener {
+        private Object prev; // TMetaVarListener or TMetaVar
+        private TMetaVarListener next;
+        
+        public abstract void notifyAboutChange();
+        
+        public void remove() {
+            if(prev == null)
+                return; // Not added or not anymore listening TMetaVar
+            if(prev instanceof TMetaVar)
+                ((TMetaVar)prev).listener = next;
+            else
+                ((TMetaVarListener)prev).next = next;
+            if(next != null) {
+                next.prev = prev;
+                next = null;
+            }
+            prev = null;
+        }
+    }
     
     TMetaVar(Kind kind) {
         this.kind = kind;
@@ -115,13 +141,22 @@ public class TMetaVar extends Type {
             ref.collectEffectMetaVars(vars);
     }
 
-    public void setRef(Type a) throws UnificationException {
-        a = Types.weakCanonical(a);
-        if(a.contains(this))
-            throw new UnificationException(this, a);
-        ref = a;
+    public void setRef(Type type) throws UnificationException {
+        if(DEBUG)
+            System.out.println("setRef " + System.identityHashCode(this) + " -> " + type);
+        if(ref != null)
+            throw new InternalCompilerError("Method setRef should be called only for unbound meta variables.");
+        if(type.contains(this))
+            throw new UnificationException(this, type);
+        ref = type;
         if(polarity != Polarity.NO_POLARITY)
-            a.addPolarity(polarity);
+            type.addPolarity(polarity);
+        if(skeletonRef != null) {
+            Type skeleton = skeletonRef;
+            skeletonRef = null;
+            Skeletons.unifySkeletons(skeleton, type);
+        }
+        fireNotifyAboutChange();
     }
     
     public Type getRef() {
@@ -130,10 +165,12 @@ public class TMetaVar extends Type {
     
     @Override
     public boolean contains(TMetaVar other) {
-        if(ref == null)
-            return this == other;
-        else
+        if(ref != null)
             return ref.contains(other);
+        else if(skeletonRef != null)
+            return skeletonRef.contains(other);
+        else
+            return this == other;
     }
     
     @Override
@@ -231,4 +268,79 @@ public class TMetaVar extends Type {
             return result;
         }
     }
+
+    public void setSkeletonRef(Type type) throws UnificationException {
+        if(DEBUG)
+            System.out.println("setSkeletonRef " +  System.identityHashCode(this) + " -> " + type);
+        if(ref != null || skeletonRef != null)
+            throw new InternalCompilerError("Method setRef should be called only for unbound meta variables.");
+        if(type.contains(this))
+            throw new UnificationException(this, type);
+        this.skeletonRef = type;
+        fireNotifyAboutChange();
+    }
+    
+    @Override
+    public int hashCode(int hash) {
+        if(ref == null)
+            return HashCodeUtils.update(hash, System.identityHashCode(this));
+        else
+            return ref.hashCode(hash);
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        if(ref == null)
+            return HashCodeUtils.update(hash, System.identityHashCode(this));
+        else
+            return ref.hashCode(hash, boundVars);
+    }
+    
+    @Override
+    public boolean equalsCanonical(Type other) {
+        return this == other;
+    }
+    
+    @Override
+    public Type canonical() {
+        if(ref == null)
+            return this;
+        else
+            return ref = ref.canonical();
+    }
+    
+    public void addListener(TMetaVarListener newListener) {
+        if(DEBUG)
+            System.out.println("addListener " + System.identityHashCode(this));
+        newListener.next = listener;
+        newListener.prev = this;
+        if(listener != null)
+            listener.prev = newListener;
+        listener = newListener;
+    }
+    
+    private void fireNotifyAboutChange() {
+        if(DEBUG)
+            System.out.println("fireNotifyAboutChange " + System.identityHashCode(this) + " " + ref);
+        TMetaVarListener cur = listener;
+        listener = null;
+        while(cur != null) {
+            if(DEBUG)
+                System.out.println("    call listener");
+            cur.prev = null; // This prevents TMetaVarListener.remove from doing anything
+            cur.notifyAboutChange();
+            TMetaVarListener next = cur.next;
+            cur.next = null;
+            cur = next;
+        }
+    }
+    
+    public TMetaVarListener getLatestListener() {
+        return listener;
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return kind;
+    }
 }
index d9fd79f917f3770b7f730caaacd9017d5aba348f..e8a0469c5d996f428c205c13018fe1e6e009707c 100644 (file)
@@ -1,11 +1,9 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TApplyAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
@@ -15,6 +13,9 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 
 
 public class TPred extends Type {
@@ -172,4 +173,42 @@ public class TPred extends Type {
             newParameters[i] = parameters[i].copySkeleton(metaVarMap);
         return new TPred(typeClass, parameters);
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
+        hash = typeClass.hashCode(hash);
+        for(Type parameter : parameters)
+            hash = parameter.hashCode(hash);
+        return hash;
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        hash = HashCodeUtils.updateWithPreprocessedValue(hash, PRED_HASH);
+        hash = typeClass.hashCode(hash, boundVars);
+        for(Type parameter : parameters)
+            hash = parameter.hashCode(hash, boundVars);
+        return hash;
+    }
+
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TPred.class))
+            return false;
+        TPred pred = (TPred)other;
+        if(typeClass != pred.typeClass || parameters.length != pred.parameters.length)
+            return false;
+        for(int i=0;i<parameters.length;++i)
+            if(!Types.canonical(parameters[i]).equalsCanonical(Types.canonical(pred.parameters[i])))
+                return false;
+        return true;
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.STAR;
+    }
 }
index e14ddb3052d5f30a57177753ec32fbc01b078fff..c3d88b00d1c826416e2d6af8144db9cddacde6b6 100644 (file)
@@ -1,17 +1,21 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TConAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
+import org.simantics.scl.compiler.types.kinds.Kind;
+import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class TUnion extends Type {    
     public final Type[] effects;
 
@@ -164,4 +168,64 @@ public class TUnion extends Type {
     public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
         return Types.NO_EFFECTS;
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        int sum = UNION_HASH;
+        for(Type effect : effects)
+            sum += effect.hashCode(HashCodeUtils.SEED);
+        return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        int sum = UNION_HASH;
+        for(Type effect : effects)
+            sum += effect.hashCode(HashCodeUtils.SEED, boundVars);
+        return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
+    }
+    
+    @Override
+    public boolean equalsCanonical(Type other) {
+        if(this == other)
+            return true;
+        if(!other.getClass().equals(TUnion.class))
+            return false;
+        TUnion union = (TUnion)other;
+        int length = effects.length;
+        if(length != union.effects.length)
+            return false;
+        if(length == 0)
+            return true;
+        for(int i=0;i<length;++i) {
+            effects[i] = effects[i].canonical();
+            union.effects[i] = union.effects[i].canonical();
+        }
+        if(length == 2) {
+            if(effects[0].equalsCanonical(union.effects[0]))
+                return effects[1].equalsCanonical(union.effects[1]);
+            else
+                return effects[0].equalsCanonical(union.effects[1]) &&
+                        effects[1].equalsCanonical(union.effects[0]);
+        }
+        loop: for(int i=0;i<length;++i) {
+            Type effect = effects[i]; 
+            for(int j=i;j<length;++j)
+                if(effect.equalsCanonical(union.effects[j])) {
+                    if(j > i) {
+                        effect = union.effects[i];
+                        union.effects[i] = union.effects[j];
+                        union.effects[j] = effect;
+                    }
+                    continue loop;
+                }
+            return false;
+        }
+        return true;
+    }
+    
+    @Override
+    public Kind getKind(Environment context) {
+        return Kinds.EFFECT;
+    }
 }
index 1fca6c59aa4b884fa6679dc68390e17ff82d2865..aeb9711453800ff1fce03878743880e613092d9b 100644 (file)
@@ -1,12 +1,9 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TVarAst;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
@@ -17,8 +14,12 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 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;
+
 
-public class TVar extends Type {
+public final class TVar extends Type {
     public static final TVar[] EMPTY_ARRAY = new TVar[0];
     
     private Kind kind;
@@ -139,4 +140,29 @@ public class TVar extends Type {
     public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
         return this;
     }
+    
+    @Override
+    public int hashCode(int hash) {
+        return HashCodeUtils.update(hash, System.identityHashCode(this));
+    }
+    
+    @Override
+    public int hashCode(int hash, TVar[] boundVars) {
+        for(int i=0;i<boundVars.length;++i)
+            if(boundVars[i] == this) {
+                hash = HashCodeUtils.updateWithPreprocessedValue(hash, BOUND_VAR_HASH);
+                return HashCodeUtils.update(hash, i);
+            }
+        return HashCodeUtils.update(hash, System.identityHashCode(this));
+    }
+    
+    @Override
+    public boolean equalsCanonical(Type other) {
+        return this == other;
+    }
+
+    @Override
+    public Kind getKind(Environment context) {
+        return kind;
+    }
 }
index 1709ebbeeeab415361894829982922bf8201bc13..386accc4ff5e1e941d84a1b84768740d81558877 100644 (file)
@@ -1,12 +1,10 @@
 package org.simantics.scl.compiler.types;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 import java.util.Map;
 
 import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.HashCodeUtils;
 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
@@ -16,6 +14,9 @@ import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.compiler.types.util.Polarity;
 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 
 
 /**
@@ -37,8 +38,13 @@ public abstract class Type {
     public static final int METAVAR_ID = 5;
     public static final int VAR_ID = 6;
     public static final int UNION_ID = 7;
-    public static final int ALIAS_ID = 8;
     
+    protected static final int APPLY_HASH = HashCodeUtils.preprocessValue(0);
+    protected static final int FORALL_HASH = HashCodeUtils.preprocessValue(1);
+    protected static final int FUN_HASH = HashCodeUtils.preprocessValue(2);
+    protected static final int PRED_HASH = HashCodeUtils.preprocessValue(3);
+    protected static final int UNION_HASH = HashCodeUtils.preprocessValue(4);
+    protected static final int BOUND_VAR_HASH = HashCodeUtils.preprocessValue(5);
     
     /*
      * This class is not meant to be extended outside of this package. 
@@ -107,12 +113,12 @@ public abstract class Type {
     
     @Override
     public int hashCode() {
-        TypeHashCodeContext context = new TypeHashCodeContext();
-        updateHashCode(context);
-        return context.getResult();
+        return hashCode(HashCodeUtils.SEED);
     }
     
     public abstract void updateHashCode(TypeHashCodeContext context);
+    public abstract int hashCode(int hash);
+    public abstract int hashCode(int hash, TVar[] boundVars);
 
     public abstract void collectFreeVars(ArrayList<TVar> vars);
     
@@ -160,5 +166,13 @@ public abstract class Type {
      * Creates an independent copy of the type, but replaces all effects by metavars
      */
     public abstract Type copySkeleton(THashMap<TMetaVar,TMetaVar> metaVarMap);
+    
+    public abstract boolean equalsCanonical(Type other);
+    
+    public Type canonical() {
+        return this;
+    }
+
+    public abstract Kind getKind(Environment context);
 
 }
\ No newline at end of file
index a706e2b8f17d3d9415b30c3ccd7eed14ea01b1f9..f0c9dbddfb2e1383ff746aa9b1a1ce7f1f12e552 100644 (file)
@@ -147,29 +147,9 @@ public class Types {
             function = apply(function, parameter);
         return function;
     }
-
-    /**
-     * Get the concrete type or alias type pointed to by a chain of type meta-variables,
-     * or the last metavariable in the link, if it is not linked to an actual type.
-     * Unlike {@link #canonical(Type)}, this method does not resolve type aliases. 
-     */
-    public static Type weakCanonical(Type type) {
-        while(true) {
-            if(type instanceof TMetaVar) {
-                TMetaVar metaVar = (TMetaVar)type;
-                if(metaVar.ref == null)
-                    return type;
-                else
-                    type = metaVar.ref;
-            }
-            else
-                return type;
-        }
-    }
     
     /**
-     * Get the concrete type pointed to by a chain of type meta-variables. Unlike {@link #weakCanonical(Type)}
-     * this method also resolves type aliases.
+     * Get the concrete type pointed to by a chain of type meta-variables.
      */
     public static Type canonical(Type type) {
         while(type instanceof TMetaVar) {
@@ -795,8 +775,8 @@ public class Types {
     }
 
     public static void unify(Type a, Type b) throws UnificationException {
-        a = weakCanonical(a);
-        b = weakCanonical(b);
+        a = canonical(a);
+        b = canonical(b);
         if(a == b)
             return;
         if(a instanceof TMetaVar) {
@@ -1137,4 +1117,30 @@ public class Types {
                     e.getMessage()));
         }
     }
+
+    public static Type instantiateAndStrip(Type type) {
+        while(true) {
+            if(type instanceof TForAll) {
+                TForAll forAll = (TForAll)type;
+                type = forAll.type.replace(forAll.var, metaVar(forAll.var.getKind()));
+            }
+            else if(type instanceof TFun) {
+                TFun fun = (TFun)type;
+                if(fun.domain instanceof TPred || fun.domain == Types.PUNIT)
+                    type = fun.range;
+                else
+                    return type;
+            }
+            else if(type instanceof TMetaVar) {
+                TMetaVar metaVar = (TMetaVar)type;
+                if(metaVar.ref == null)
+                    return type;
+                else
+                    type = metaVar.ref;
+            }
+            else
+                return type;
+        }
+    }
+    
 }
index edf63df740a4d871910eddde4be0708341f09ab9..4707110f8d9f374af01c761fb1200038d7a5f1ce 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.scl.compiler.types.kinds;
 
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
 
 public class Kinds {
@@ -77,5 +78,24 @@ public class Kinds {
 
     public static boolean equals(Kind a, Kind b) {
         return equalsCanonical(canonical(a), canonical(b));
+    }
+
+    public static Kind rangeOfArrow(Kind kind) {
+        kind = canonical(kind);
+        if(kind instanceof KArrow)
+            return ((KArrow)kind).range;
+        else if(kind instanceof KMetaVar) {
+            Kind domain = Kinds.metaVar();
+            Kind range = Kinds.metaVar();
+            try {
+                ((KMetaVar)kind).setRef(arrow(domain, range));
+            } catch (KindUnificationException e) {
+                // Should not fail because kind is canonical
+                e.printStackTrace();
+            }
+            return range;
+        }
+        else
+            throw new InternalCompilerError("Assumed arrow kind but encountered " + kind + ".");
     }    
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeListener.java
new file mode 100644 (file)
index 0000000..04c9e16
--- /dev/null
@@ -0,0 +1,63 @@
+package org.simantics.scl.compiler.types.util;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.types.Skeletons;
+import org.simantics.scl.compiler.types.TApply;
+import org.simantics.scl.compiler.types.TForAll;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.TMetaVar;
+import org.simantics.scl.compiler.types.TMetaVar.TMetaVarListener;
+import org.simantics.scl.compiler.types.TPred;
+import org.simantics.scl.compiler.types.Type;
+
+public abstract class TypeListener {
+    private ArrayList<TMetaVarListener> metaVarListeners = new ArrayList<TMetaVarListener>(2);
+    public abstract void notifyAboutChange();
+    
+    private static class SubListener extends TMetaVarListener {
+        private final TypeListener parent;
+        public SubListener(TypeListener parent) {
+            this.parent = parent;
+        }        @Override
+        public void notifyAboutChange() {
+            for(TMetaVarListener otherListeners : parent.metaVarListeners)
+                otherListeners.remove();
+            parent.notifyAboutChange();
+        }
+    };
+    
+    public void listenSkeleton(Type type) {
+        type = Skeletons.canonicalSkeleton(type);
+        if(type instanceof TMetaVar) {
+            TMetaVar metaVar = (TMetaVar)type;
+            TMetaVarListener latestListener = metaVar.getLatestListener();
+            if(latestListener instanceof SubListener &&
+                    ((SubListener)latestListener).parent == this)
+                return;
+            
+            SubListener subListener = new SubListener(this);
+            metaVarListeners.add(subListener);
+            metaVar.addListener(subListener);
+        }
+        else if(type instanceof TApply) {
+            TApply apply = (TApply)type;
+            listenSkeleton(apply.function);
+            listenSkeleton(apply.parameter);
+        }
+        else if(type instanceof TFun) {
+            TFun fun = (TFun)type;
+            listenSkeleton(fun.domain);
+            listenSkeleton(fun.range);
+        }
+        else if(type instanceof TForAll) {
+            TForAll forAll = (TForAll)type;
+            listenSkeleton(forAll.type);
+        }
+        else if(type instanceof TPred) {
+            TPred pred = (TPred)type;
+            for(Type parameter : pred.parameters)
+                listenSkeleton(parameter);
+        }
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeTree.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/util/TypeTree.java
new file mode 100644 (file)
index 0000000..b41dba8
--- /dev/null
@@ -0,0 +1,70 @@
+package org.simantics.scl.compiler.types.util;\r
+\r
+import org.simantics.scl.compiler.types.Skeletons;\r
+import org.simantics.scl.compiler.types.TMetaVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+\r
+public class TypeTree<T> {\r
+    \r
+    public static class Case<T> {\r
+        public Type[] types;\r
+        public T result;\r
+    }\r
+    \r
+    private static class Node<T> {\r
+        Case<T>[] cases;\r
+        Branch<T>[] branches;\r
+\r
+        public Node(Case<T>[] cases) {\r
+            this.cases = cases;\r
+            this.branches = new Branch[cases[0].types.length];\r
+        }\r
+        \r
+        Branch<T> getBranch(int i) {\r
+            // TODO\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    private static class Branch<T> {\r
+\r
+        public void improve(Iterator<T> iterator) {\r
+            // TODO Auto-generated method stub\r
+            \r
+        }\r
+        \r
+    }\r
+    \r
+    public static class Iterator<T> {\r
+        Node<T> node;\r
+        Type[] scrutinee;\r
+        \r
+        public Iterator(Node<T> node, Type[] scrutinee) {\r
+            this.node = node;\r
+            this.scrutinee = scrutinee;\r
+        }\r
+        \r
+        public void improve() {\r
+            for(int i=0;i<scrutinee.length;++i) {\r
+                Type type = scrutinee[i] = Skeletons.canonicalSkeleton(scrutinee[i]);\r
+                if(!(type instanceof TMetaVar)) {\r
+                   Branch<T> branch = node.getBranch(i);\r
+                   if(branch != null) {\r
+                       branch.improve(this);\r
+                       --i;\r
+                   }\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+    Node<T> root;\r
+    \r
+    public TypeTree(Case<T>[] cases) {\r
+        this.root = new Node<T>(cases);\r
+    }\r
+    \r
+    public Iterator<T> iterator(Type ... scrutinee) {\r
+        return new Iterator<T>(root, scrutinee);\r
+    }\r
+}\r
index b80577e5371ad7f4feaad6549de48d5c9367b0ca..0b7b52e2938a58cd0926ad8b1c0a50bab5151d17 100644 (file)
@@ -8,15 +8,12 @@ public class ActiveTests extends TestBase {
     public ActiveTests() { super("scl"); }
 
     @Test public void Equations1() { test(); }
-    @Test public void Equality() { test(); }
-    @Test public void ModuleInitialization() { test(); }
-
-    @Test public void ImportJavaConstructor() { test(); }
-    @Test public void MarketModel() { test(); }
     @Test public void MarketModel2() { test(); }
-    @Ignore
+    @Test public void Overloading2() { test(); }
+    @Test public void Overloading3() { test(); }
+    //@Ignore
     @Test public void PatternError() { test(); }
-    @Test public void TypeAliasRefsToTypeAlias() { test(); }
+    @Test public void Serialization() { test(); }
     @Ignore
     @Test public void TypeClass2() { test(); }
     @Test public void TypeClassBug2() { test(); }
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FindAllowedChars.java
new file mode 100644 (file)
index 0000000..1e40786
--- /dev/null
@@ -0,0 +1,66 @@
+package org.simantics.scl.compiler.tests;\r
+\r
+import java.lang.reflect.Method;\r
+\r
+import org.objectweb.asm.ClassWriter;\r
+import org.objectweb.asm.MethodVisitor;\r
+import org.objectweb.asm.Opcodes;\r
+\r
+public class FindAllowedChars {\r
+    public static class MyClassLoader extends ClassLoader {\r
+        final String className;\r
+        final byte[] classBytes;\r
+        \r
+        public MyClassLoader(ClassLoader parent, String className, byte[] classBytes) {\r
+            super(parent);\r
+            this.className = className;\r
+            this.classBytes = classBytes;\r
+        }\r
+        \r
+        public MyClassLoader(String className, byte[] classBytes) {\r
+            this.className = className;\r
+            this.classBytes = classBytes;\r
+        }\r
+\r
+        @Override\r
+        protected Class<?> findClass(String name) throws ClassNotFoundException {\r
+            if(name.equals(name))\r
+                return defineClass(name, classBytes, 0, classBytes.length);\r
+            else\r
+                return super.findClass(name);\r
+        }\r
+    }\r
+    \r
+    public static void test(String className, String methodName) throws Exception {\r
+        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);\r
+        classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);\r
+        \r
+        MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, "()V", null, null);\r
+        /*methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");\r
+        methodVisitor.visitLdcInsn("Hello world!");\r
+        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);*/\r
+        methodVisitor.visitInsn(Opcodes.RETURN);\r
+        methodVisitor.visitMaxs(0, 0);\r
+        methodVisitor.visitEnd();\r
+        classWriter.visitEnd();\r
\r
+        ClassLoader loader = new MyClassLoader(className, classWriter.toByteArray());\r
+        Class<?> clazz = loader.loadClass(className);\r
+        Method method = clazz.getMethod(methodName);\r
+        method.invoke(null);\r
+    }\r
+    \r
+    public static void main(String[] args) throws Exception {\r
+        for(int a=Character.MIN_VALUE;a<Character.MAX_VALUE;++a) {\r
+            //for(char b=0;b<256;++b) {\r
+                String name = new String(new char[] {(char)a});\r
+                try {\r
+                    test(name, "test");\r
+                } catch(Throwable e) {\r
+                    System.out.println(name + " (" + a + ")");\r
+                }\r
+            //}   \r
+        }\r
+        System.out.println((int)Character.MAX_VALUE);\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FutureTests.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/FutureTests.java
deleted file mode 100644 (file)
index 5b37fc5..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.simantics.scl.compiler.tests;
-
-import org.junit.Test;
-
-public class FutureTests extends TestBase {
-    
-    public FutureTests() { super("scl"); }
-    
-    @Test public void BigInstances() { test(); }    
-    @Test public void Matching3() { test(); }
-    @Test public void Seq() { test(); }
-    
-}
similarity index 51%
rename from bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTestsWithoutPrelude.java
rename to bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
index 4794304ca939ddd6d08568da0db1c179f1a5a32a..286d0f910868c883ecc2adfb9884ca2a51df6889 100644 (file)
@@ -1,27 +1,44 @@
 package org.simantics.scl.compiler.tests;
 
+import org.junit.AfterClass;
 import org.junit.Test;
+import org.simantics.scl.compiler.errors.Failable;
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.coverage.CoverageUtils;
+import org.simantics.scl.compiler.module.coverage.ModuleCoverage;
 import org.simantics.scl.compiler.top.ValueNotFound;
+import org.simantics.scl.runtime.profiling.BranchPoint;
 
-public class RegressionTestsWithoutPrelude extends TestBase {
-    
-    public RegressionTestsWithoutPrelude() { super("scl"); }
+public class ModuleRegressionTests extends TestBase {
+
+    public ModuleRegressionTests() { super("scl"); }
     
     @Test public void AmbiguousType() { test(); }
     @Test public void ApplicationOfNunfunction() { test(); }
     @Test public void Arity1() { test(); }
     @Test public void AsPattern() { test(); }
+    @Test public void BigContext() { test(); }
+    @Test public void BigFunction() { test(); }
+    @Test public void BinaryOperators1() { test(); }
     @Test public void BooleanId() { test(); }
+    @Test public void Bug4450() { test(); }
+    @Test public void Character1() { test(); }
     @Test public void ClashingClass() { test(); }
     @Test public void ClashingData() { test(); }
     @Test public void ClashingInstance() { test(); }
     @Test public void ClashingValueType() { test(); }
+    @Test public void Collaz() { test(); }
     @Test public void Compose() { test(); }
     @Test public void Composition() { test(); }
     @Test public void ConjunctionMacro() { test(); }
     @Test public void Constant() { test(); }
     @Test public void ConstructorNameClash() { test(); }
     @Test public void DefaultMethods1() { test(); }
+    @Test public void Deriving3() { test(); }
+    @Test public void Deriving4() { test(); }
+    @Test public void DifferentBranchTypes() { test(); }
+    @Test public void Div() { test(); }
+    @Test public void DoubleConversion() { test(); }
     @Test public void DoubleEffect() { test(); }    
     @Test public void Effects1() { test(); }
     @Test public void Effects2() { test(); }  
@@ -31,27 +48,48 @@ public class RegressionTestsWithoutPrelude extends TestBase {
     @Test public void Effects6() { test(); }
     @Test(expected=ValueNotFound.class) 
     public void EmptyModule() throws ValueNotFound {
-        test("EmptyModule", "");
+        test(new String[]{"EmptyModule"}, new String[]{""});
     }
+    @Test public void Equality() { test(); }
     @Test public void ExistentialData() { test(); }
     @Test public void ExistentialData2() { test(); }
+    @Test public void ExpressionParsing() { test(); }
     @Test public void FaultyRecursion() { test(); }
     @Test public void Fibonacci() { test(); }
+    @Test public void Fibonacci2() { test(); }
     @Test public void Fibonacci3() { test(); }
     @Test public void FingerTree() { test(); }
+    @Test public void FoldMissingInitialValue() { test(); }
+    @Test public void FoldlBuild1() { test(); }
+    @Test public void FoldlBuild2() { test(); }
     @Test public void Forall1() { test(); }
     @Test public void Forall2() { test(); }
     @Test public void Forall3() { test(); }
+    @Test public void Formula() { test(); }
+    @Test public void FromDynamic() { test(); }
+    @Test public void FromDynamic2() { test(); }
+    @Test public void FromDynamic3() { test(); }
+    @Test public void FromDynamic4() { test(); }
+    @Test public void FromDynamic5() { test(); }
+    @Test public void FunctionFunctor() { test(); }
     @Test public void Functor() { test(); }
+    @Test public void FunctorM1() { test(); }
     @Test public void Generalization() { test(); }
+    @Test public void GenericMutualRecursion() { test(); }
+    @Test public void GlobalVariables() { test(); }
     @Test public void GuardedExpressionBug() { test(); }
+    @Test public void Guards1() { test(); }
+    @Test public void Guards2() { test(); }
     @Test public void IdAsOperator() { test(); }    
     @Test public void IllegalChar() { test(); }
+    @Test public void ImportJavaConstructor() { test(); }
     @Test public void ImportRef() { test(); }
     @Test public void InconsistentArity() { test(); }
     @Test public void InconsistentIndentation() { test(); }
     @Test public void IndentationAndParenthesis() { test(); }
+    @Test public void Index() { test(); }
     @Test public void Inline1() { test(); }
+    @Test public void InstanceHierarchy() { test(); }
     @Test public void InstanceIsTypoedAsClass() { test(); }
     @Test public void InvalidClass1() { test(); }
     @Test public void InvalidEncoding() { test(); }
@@ -61,6 +99,7 @@ public class RegressionTestsWithoutPrelude extends TestBase {
     @Test public void InvalidKinds2() { test(); }
     @Test public void InvalidKinds3() { test(); }
     @Test public void InvalidLambda() { test(); }
+    @Test public void InvalidModule() { test(); }
     @Test public void InvalidPattern1() { test(); }
     @Test public void InvalidPattern2() { test(); }
     @Test public void InvalidPattern3() { test(); }
@@ -72,31 +111,55 @@ public class RegressionTestsWithoutPrelude extends TestBase {
     @Test public void JavaTypes() { test(); }
     @Test public void Kinds1() { test(); }
     @Test public void Lambda() { test(); }
+    @Test public void Layout1() { test(); }
     @Test public void List() { test(); }
     @Test public void ListError1() { test(); }
     @Test public void ListError2() { test(); }    
+    @Test public void ListSyntax() { test(); }
+    @Test public void ListSyntax10() { test(); }
+    @Test public void ListSyntax11() { test(); }
+    @Test public void ListSyntax12() { test(); }
+    @Test public void ListSyntax2() { test(); }
+    @Test public void ListSyntax3() { test(); }
+    @Test public void ListSyntax4() { test(); }
+    @Test public void ListSyntax5() { test(); }
+    @Test public void ListSyntax6() { test(); }
+    @Test public void ListSyntax7() { test(); }
+    @Test public void ListSyntax8() { test(); }
+    @Test public void ListSyntax9() { test(); }
     @Test public void ListSyntaxWithoutPrelude() { test(); }
     @Test public void LocalDefinitions() { test(); }
     @Test public void LocalDefinitions2() { test(); }
     @Test public void LocalDefinitions3() { test(); }
     @Test public void LocalDefinitions4() { test(); }
+    @Test public void LocalDefinitions5() { test(); }
     @Test public void Macros1() { test(); }
     @Test public void Macros2() { test(); }
     @Test public void Macros4() { test(); }
     @Test public void Map1() { test(); }
+    @Test public void MarketModel() { test(); }    
     @Test public void Matching() { test(); }
     @Test public void Matching2() { test(); }
-    @Test public void Matching5() { test(); }    
+    @Test public void Matching4() { test(); }
+    @Test public void Matching5() { test(); }
+    @Test public void MatchingWithMissingParameter() { test(); }
     @Test public void MatchingWithoutTypeAnnotations() { test(); }
+    @Test public void MaximumBy() { test(); }
     @Test public void Maybe1() { test(); }
     @Test public void Maybe2() { test(); }
     @Test public void Maybe3() { test(); }    
+    @Test public void Maybe4() { test(); }
+    @Test public void MissingEffect() { test(); }
     @Test public void MissingMethod() { test(); }
+    @Test public void ModuleInitialization() { test(); }
     @Test public void MonadBug1() { test(); }
+    @Test public void MonadSyntax1() { test(); }
+    @Test public void Monads1() { test(); }
     @Test public void NoDefinitionErrorMessage() { test(); }    
     @Test public void NoInstance() { test(); }
     @Test public void NoInstance2() { test(); }
     @Test public void NonassociativeOperator() { test(); }
+    @Test public void NonexistentTypeClassInAnnotation() { test(); }
     @Test public void NonexistingEffect() { test(); }
     @Test public void OneLineMatch() { test(); }    
     @Test public void OpenString1() { test(); }
@@ -104,36 +167,85 @@ public class RegressionTestsWithoutPrelude extends TestBase {
     @Test public void OverloadedArithmetic1() { test(); }
     @Test public void OverloadedArithmetic2() { test(); }
     @Test public void OverloadedArithmetic3() { test(); }
+    @Test public void OverloadedLiterals2() { test(); }
+    @Test public void Overloading1() { test(); }
+    @Test public void Parsing() { test(); }    
     @Test public void PolymorphicRecursion() { test(); }
     @Test public void PolymorphicRecursion2() { test(); }
+    @Test public void Polynomials() { test(); }
     @Test public void PrecedenceOfNonoperators() { test(); }    
     @Test public void Primes() { test(); }
+    @Test public void Proc1() { test(); }
+    @Test public void Proc2() { test(); }
+    @Test public void Proc3() { test(); }
     @Test public void Pythagoras() { test(); }
+    @Test public void Random1() { test(); }
+    @Test public void RangeSyntax() { test(); }
+    @Test public void Record1() { test(); }
+    @Test public void RecordShorthand() { 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 RepeatedVariableInPattern() { test(); }    
+    @Test public void SSATypingBug() { test(); }
+    @Test public void Scanl() { test(); }
+    @Test public void Search() { test(); }
+    @Test public void Sections() { test(); }
+    @Test public void Select1() { test(); }
+    @Test public void Select2() { test(); }
+    @Test public void Select3() { test(); }
+    @Test public void Select4() { test(); }
+    @Test public void Select5() { test(); }
+    @Test public void Select6() { test(); }
+    @Test public void Select7() { test(); }
+    @Test public void Select8() { test(); }
+    @Test public void Select9() { test(); }
     @Test public void SelfReferringContextInTypeClass() { test(); }
+    @Test public void Serialization2() { test(); }
+    @Test public void Serialization3() { test(); }
     @Test public void SharedTypeVariable() { test(); }
     @Test public void ShortcutFusion() { test(); }
+    @Test public void Show1() { test(); }
+    @Test public void SinConst1() { test(); }
+    @Test public void Sort() { test(); }
     @Test public void Sort2() { test(); }
     @Test public void StreamFusion() { test(); }
+    @Test public void StringEscape() { test(); }
+    @Test public void StringInterpolation1() { test(); }
     @Test public void StringMatching1() { test(); }    
+    @Test public void SumOfInverses2() { test(); }
+    @Test public void TooManyParametersToSin() { test(); }
+    @Test public void Transformation1() { test(); }
+    @Test public void Transformation2() { test(); }
+    @Test public void Transformation3() { test(); }
+    @Test public void Transformation4() { test(); }
+    @Test public void Transformation5() { test(); }
+    @Test public void Transformation6() { test(); }
+    @Test public void Transformation7() { test(); }
+    @Test public void TransformationOrder() { test(); }
     @Test public void Tuples() { test(); }
     @Test public void Tuples2() { test(); }
     @Test public void TypeAlias1() { test(); }
     @Test public void TypeAlias2() { test(); }
     @Test public void TypeAlias3() { test(); }
+    @Test public void TypeAliasRefsToTypeAlias() { test(); }
     @Test public void TypeAnnotation1() { test(); }
     @Test public void TypeAnnotation2() { test(); }
     @Test public void TypeClass() { test(); }
     @Test public void TypeClassBug1() { test(); }    
+    @Test(timeout=1000L) public void TypeInferenceBug2() { test(); }
+    @Test public void TypeOf1() { test(); }
     @Test public void TypingBug1() { test(); }
     @Test public void TypingError1() { test(); }
     @Test public void TypingError2() { test(); }
+    @Test public void UnaryMinus() { test(); }
     @Test public void UndefinedValue() { test(); }
     @Test public void UnexpectedToken() { test(); }
+    @Test public void Unification1() { test(); }
     @Test public void UnknownAnnotation() { test(); }
     @Test public void UnresolvedClass() { test(); }
     @Test public void UnresolvedTypeInAnnotation() { test(); }
@@ -141,11 +253,38 @@ public class RegressionTestsWithoutPrelude extends TestBase {
     @Test public void UnresolvedVariable() { test(); }
     @Test public void UnresolvedVariable2() { test(); }   
     @Test public void ValueAsOperator() { test(); }
+    @Test public void ValueConversion() { test(); }
+    @Test public void Vector1() { test(); }
+    @Test public void Vector2() { test(); }
     @Test public void Void1() { test(); }
     @Test public void Void2() { test(); }
     @Test public void Void3() { test(); }
     @Test public void While() { test(); }
+    @Test public void While2() { test(); }
+    @Test public void While3() { test(); }    
     @Test public void WrongDefaultMethod() { test(); }
     @Test public void WrongInstanceMethod() { test(); }
-    
+
+    @AfterClass
+    public static void checkCoverage() {
+        Failable<Module> maybeModule = PRELUDE_MODULE_REPOSITORY.getModule("Prelude");
+        if(!maybeModule.didSucceed())
+            return;
+        Module module = maybeModule.getResult();
+        ModuleCoverage coverage = CoverageUtils.getCoverage(module);
+        if(coverage == null)
+            return;
+        coverage.print(System.out);
+        printCoverageTree(module.getBranchPoints().get("lookup"), 0);
+    }
+
+    private static void printCoverageTree(BranchPoint[] branchPoints, int ind) {
+        for(BranchPoint bp : branchPoints) {
+            for(int i=0;i<ind;++i)
+                System.out.print("    ");
+            System.out.println(bp.codeSize);
+            printCoverageTree(bp.children, ind+1);
+        }
+    }
+
 }
index 17a4f7ec8f022956396ffda5c11faa42afe86644..1f397fe333b948a80029e0d02c46d215f41780bb 100644 (file)
@@ -6,8 +6,7 @@ import org.junit.runners.Suite.SuiteClasses;
 
 @RunWith(Suite.class)
 @SuiteClasses({
-    RegressionTestsWithoutPrelude.class, 
-    RegressionTestsWithPrelude.class,
+    ModuleRegressionTests.class,
     TestExpressionEvaluator.class,
     TestCommandSession.class
 })
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTestsWithPrelude.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/RegressionTestsWithPrelude.java
deleted file mode 100644 (file)
index 76d58fe..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.simantics.scl.compiler.tests;
-
-import org.junit.Test;
-
-public class RegressionTestsWithPrelude extends TestBase {
-
-    public RegressionTestsWithPrelude() { super("scl"); }
-
-    @Test public void BigContext() { test(); }
-    @Test public void BigFunction() { test(); }
-    @Test public void BinaryOperators1() { test(); }
-    @Test public void Bug4450() { test(); }
-    @Test public void Character1() { test(); }
-    @Test public void Collaz() { test(); }
-    @Test public void Deriving1() { test(); }
-    @Test public void Deriving3() { test(); }
-    @Test public void Deriving4() { test(); }
-    @Test public void Div() { test(); }
-    @Test public void DoubleConversion() { test(); }
-    @Test public void ExpressionParsing() { test(); }
-    @Test public void Fibonacci2() { test(); }
-    @Test public void FoldlBuild1() { test(); }
-    @Test public void FoldlBuild2() { test(); }
-    @Test public void FoldMissingInitialValue() { test(); }
-    @Test public void FromDynamic() { test(); }
-    @Test public void FromDynamic2() { test(); }
-    @Test public void FromDynamic3() { test(); }
-    @Test public void FromDynamic4() { test(); }
-    @Test public void FromDynamic5() { test(); }
-    @Test public void FunctionFunctor() { test(); }
-    @Test public void FunctorM1() { test(); }
-    @Test public void GenericMutualRecursion() { test(); }
-    @Test public void GlobalVariables() { test(); }
-    @Test public void Guards1() { test(); }
-    @Test public void Guards2() { test(); }
-    @Test public void Hashable1() { test(); }
-    @Test public void Hashable2() { test(); }
-    @Test public void Index() { test(); }
-    @Test public void InstanceHierarchy() { test(); }
-    @Test public void InvalidModule() { test(); }
-    @Test public void Layout1() { test(); }
-    @Test public void ListSyntax() { test(); }
-    @Test public void ListSyntax2() { test(); }
-    @Test public void ListSyntax3() { test(); }
-    @Test public void ListSyntax4() { test(); }
-    @Test public void ListSyntax5() { test(); }
-    @Test public void ListSyntax6() { test(); }
-    @Test public void ListSyntax7() { test(); }
-    @Test public void ListSyntax8() { test(); }
-    @Test public void ListSyntax9() { test(); }
-    @Test public void ListSyntax10() { test(); }
-    @Test public void ListSyntax11() { test(); }
-    @Test public void ListSyntax12() { test(); }
-    @Test public void LocalDefinitions5() { test(); }
-    @Test public void Matching4() { test(); }
-    @Test public void MaximumBy() { test(); }
-    @Test public void Maybe4() { test(); }
-    @Test public void MissingEffect() { test(); }
-    @Test public void Monads1() { test(); }
-    @Test public void MonadSyntax1() { test(); }
-    @Test public void NonexistentTypeClassInAnnotation() { test(); }
-    @Test public void OverloadedLiterals2() { test(); }
-    @Test public void Parsing() { test(); }    
-    @Test public void Polynomials() { test(); }
-    @Test public void Proc1() { test(); }
-    @Test public void Proc2() { test(); }
-    @Test public void Proc3() { test(); }
-    @Test public void Random1() { test(); }
-    @Test public void RangeSyntax() { test(); }
-    @Test public void Record1() { test(); }
-    @Test public void RedBlackTrees() { test(); }
-    @Test public void Relations1() { test(); }
-    @Test public void Relations2() { test(); }
-    @Test public void Scanl() { test(); }
-    @Test public void Search() { test(); }
-    @Test public void Sections() { test(); }
-    @Test public void Select1() { test(); }
-    @Test public void Select2() { test(); }
-    @Test public void Select3() { test(); }
-    @Test public void Select4() { test(); }
-    @Test public void Select5() { test(); }
-    @Test public void Select6() { test(); }
-    @Test public void Select7() { test(); }
-    @Test public void Select8() { test(); }
-    @Test public void Select9() { test(); }
-    @Test public void Serialization() { test(); }
-    @Test public void Serialization2() { test(); }
-    @Test public void Serialization3() { test(); }
-    @Test public void Show1() { test(); }
-    @Test public void SinConst1() { test(); }
-    @Test public void Sort() { test(); }
-    @Test public void SSATypingBug() { test(); }
-    @Test public void StringInterpolation1() { test(); }
-    @Test public void SumOfInverses2() { test(); }
-    @Test public void TooManyParametersToSin() { test(); }
-    @Test public void Transformation1() { test(); }
-    @Test public void Transformation2() { test(); }
-    @Test public void Transformation3() { test(); }
-    @Test public void Transformation4() { test(); }
-    @Test public void Transformation5() { test(); }
-    @Test public void Transformation6() { test(); }
-    @Test public void Transformation7() { test(); }
-    @Test public void TransformationOrder() { test(); }
-    @Test(timeout=1000L) public void TypeInferenceBug2() { test(); }
-    @Test public void TypeOf1() { test(); }
-    @Test public void UnaryMinus() { test(); }
-    @Test public void Unification1() { test(); }
-    @Test public void ValueConversion() { test(); }
-    @Test public void Vector1() { test(); }
-    @Test public void Vector2() { test(); }
-    @Test public void While2() { test(); }
-    @Test public void While3() { test(); }
-
-}
index 7a445392db34a2d38102d8de5e5040cc9e46229e..466c0978b6ec56ac57e12c2952ea7d916ab6d10e 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.tests;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.regex.Pattern;
 
@@ -13,6 +14,7 @@ import org.simantics.scl.compiler.module.ImportDeclaration;
 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.ModuleSource;
 import org.simantics.scl.compiler.source.StringModuleSource;
 import org.simantics.scl.compiler.source.repository.CompositeModuleSourceRepository;
 import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
@@ -26,7 +28,7 @@ public class TestBase {
                     SourceRepositories.BUILTIN_SOURCE_REPOSITORY,
                     SourceRepositories.PRELUDE_SOURCE_REPOSITORY
                     ));
-    private static final Pattern TEST_SEPARATOR = Pattern.compile("^-- *$", Pattern.MULTILINE);
+    private static final Pattern TEST_SEPARATOR = Pattern.compile("^--+ *$", Pattern.MULTILINE);
     private static final Charset UTF8 = Charset.forName("UTF-8");
 
     String path;
@@ -35,17 +37,36 @@ public class TestBase {
         this.path = path;
     }
     
-    
     protected void test() {
         String testModuleName = Thread.currentThread().getStackTrace()[2].getMethodName();
         String testPath = path + "/" + testModuleName + ".scl";
         
         try {
             String[] testParts = readTestParts(testPath);
-            for(int i=0;i<testParts.length;i+=2) {
-                String input = testParts[i];
-                String expectedOutput = testParts[i+1];
-                String actualOutput = test(testModuleName, input);
+            
+            int j=0;
+            ArrayList<String> auxModuleNameList = new ArrayList<String>();
+            while(j < testParts.length) {
+                String part = testParts[j]; 
+                if(part.startsWith("// module "))
+                    auxModuleNameList.add(part.substring(10).split("\\n", 2)[0].trim());
+                else
+                    break;
+                ++j;
+            }
+            int mainId = j;
+            String[] moduleNames = new String[mainId+1];
+            String[] moduleTexts = new String[mainId+1];
+            for(int i=0;i<mainId;++i) {
+                moduleNames[i] = auxModuleNameList.get(i);
+                moduleTexts[i] = testParts[i];
+            }
+            moduleNames[mainId] = testModuleName;
+            
+            for(;j<testParts.length;j+=2) {
+                moduleTexts[mainId] = testParts[j];
+                String expectedOutput = j+1<testParts.length ? testParts[j+1] : "";
+                String actualOutput = test(moduleNames, moduleTexts);
                 Assert.assertEquals(
                         canonicalizeOutput(expectedOutput),
                         canonicalizeOutput(actualOutput));
@@ -61,22 +82,32 @@ public class TestBase {
         return text.trim().replace("\r\n", "\n");
     }
 
-    protected String test(String testModuleName, String input) throws ValueNotFound {
+    protected String test(String[] moduleNames, String[] moduleTexts) throws ValueNotFound {
+        if(moduleNames.length != moduleTexts.length)
+            throw new IllegalArgumentException();
+        /*for(int i=0;i<moduleNames.length;++i) {
+            System.out.println("-- " + moduleNames[i] + " --");
+            System.out.println(moduleTexts[i]);
+        }*/
+        
+        ModuleSource[] moduleSources = new ModuleSource[moduleNames.length];
+        for(int i=0;i<moduleNames.length;++i)
+            moduleSources[i] = new StringModuleSource(
+                    moduleNames[i], getClass().getClassLoader(), moduleTexts[i]) {
+                @Override
+                protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
+                    return ImportDeclaration.ONLY_BUILTINS;
+                }
+            };
         ModuleRepository testEnvironment = new ModuleRepository(
                 PRELUDE_MODULE_REPOSITORY,
-                new MapModuleSourceRepository(new StringModuleSource(
-                        testModuleName, getClass().getClassLoader(), input) {
-                    @Override
-                    protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
-                        return ImportDeclaration.ONLY_BUILTINS;
-                    }
-                }
-                ));
-        Failable<Module> result = testEnvironment.getModule(testModuleName);
+                new MapModuleSourceRepository(moduleSources));
+        int lastId = moduleNames.length-1;
+        Failable<Module> result = testEnvironment.getModule(moduleNames[lastId]);
         if(!result.didSucceed())
-            return ((Failure)result).toString(input);
+            return ((Failure)result).toString(moduleTexts[lastId]);
         else {
-            Object main = testEnvironment.getRuntimeModule(testModuleName).getResult().getValue("main");
+            Object main = testEnvironment.getRuntimeModule(moduleNames[lastId]).getResult().getValue("main");
             return String.valueOf(main);
         }
     }
@@ -97,9 +128,11 @@ public class TestBase {
             }
             String text = new String(buffer, 0, pos, UTF8);
             String[] result = TEST_SEPARATOR.split(text);
-            if(result.length % 2 == 1) {
-                result = Arrays.copyOf(result, result.length+2);
-                result[result.length-1] = "";
+            for(int i=1;i<result.length;++i) {
+                if(result[i].startsWith("\r\n"))
+                    result[i] = result[i].substring(2);
+                if(result[i].startsWith("\n") || result[i].startsWith("\r"))
+                    result[i] = result[i].substring(1);
             }
             return result;
         } finally {
index e6b6e0ae68a3efdc3a99577c0155c1eb7a77c212..283e0e14e4b76c368efe479afc13bd27de12c836 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.scl.compiler.tests;\r
 \r
-import junit.framework.Assert;\r
-\r
 import org.junit.Test;\r
 import org.simantics.scl.compiler.elaboration.java.Builtins;\r
 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
@@ -15,6 +13,8 @@ import org.simantics.scl.compiler.source.repository.MapModuleSourceRepository;
 import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;\r
 import org.simantics.scl.compiler.top.ExpressionEvaluator;\r
 \r
+import junit.framework.Assert;\r
+\r
 public class TestClassNaming {\r
 \r
     private static class SimpleModuleSource extends StringModuleSource {\r
index 3ed07b0e51b8e7f100b7fe8a1dce801b263dda2d..7afa6784ae097c3591f1959cdc66af1ac035010c 100644 (file)
@@ -2,8 +2,6 @@ package org.simantics.scl.compiler.tests;
 
 import java.util.Arrays;
 
-import junit.framework.Assert;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
@@ -27,6 +25,8 @@ import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.runtime.function.Function;
 import org.simantics.scl.runtime.tuple.Tuple0;
 
+import junit.framework.Assert;
+
 public class TestExpressionEvaluator {
 
     public static final boolean TIMING = false;
@@ -198,21 +198,4 @@ public class TestExpressionEvaluator {
             Assert.assertEquals(sum, result);
         }
     }
-    
-    @Test
-    public void testSeq() throws Exception {
-        String expressionText = "Sequences.runSequence mdo\n" +
-                                "  repeatForever mdo\n" +
-                                "    Sequences.wait 2\n" +
-                                "    Sequences.stop";
-        
-        try {
-            Object result = new ExpressionEvaluator(runtimeEnvironment, expressionText)
-            .parseAsBlock(true)
-            .eval();
-        } catch(SCLExpressionCompilationException e) {
-            System.out.println(CompilationErrorFormatter.toString(expressionText, e.getErrors()));
-            throw e;
-        }
-    }
 }
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestTypeDesc.java b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/TestTypeDesc.java
new file mode 100644 (file)
index 0000000..451dca8
--- /dev/null
@@ -0,0 +1,12 @@
+package org.simantics.scl.compiler.tests;
+
+import org.cojen.classfile.TypeDesc;
+
+public class TestTypeDesc {
+    public static void main(String[] args) {
+        System.out.println(TypeDesc.forClass(String.class).getFullName());
+        System.out.println(TypeDesc.forClass(String.class).getDescriptor());
+        System.out.println(TypeDesc.forClass(String.class).getRootName());
+
+    }
+}
index 898a9b1a811a9bf1ad38a20b3deaaeee90f81814..612a3ab1e82da58ef28b4294e333e434b75d76bc 100644 (file)
@@ -6,6 +6,7 @@ public class UnimplementedTests extends TestBase {
     
     public UnimplementedTests() { super("scl"); }
 
+    @Test public void BigInstances() { test(); }
     @Test public void BlankExpression() { test(); }
     @Test public void ClashingValueDefinition() { test(); }
     @Test public void FunctionalDependencies1() { test(); }
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Deriving1.scl
deleted file mode 100644 (file)
index 6eabc62..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-import "Prelude"\r
-\r
-data Vec2 = Vec2 Double Double\r
-\r
-deriving instance Eq Vec2\r
-\r
-main = Vec2 1 1 == Vec2 1 1\r
---\r
-true
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/DifferentBranchTypes.scl
new file mode 100644 (file)
index 0000000..2a0925f
--- /dev/null
@@ -0,0 +1,19 @@
+import "Prelude"
+
+foo n = n
+  where
+    if n > 0
+    then 1
+    else "asd"
+
+bar n = n
+  where
+    do 
+       c = n+1
+       if c > 0
+       then 1
+       else "asd"
+    
+main = foo 3 + bar 3
+--
+6
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Formula.scl
new file mode 100644 (file)
index 0000000..10eafb0
--- /dev/null
@@ -0,0 +1,131 @@
+import "Prelude"
+
+data Formula a = TrueF
+               | FalseF
+               | XorF (Formula a) (Formula a)
+               | AndF (Formula a) (Formula a)
+               | ConditionF a
+               | NextF (Formula a)
+               | UntilF (Formula a) (Formula a)
+
+deriving instance (Ord a) => Ord (Formula a)
+
+instance (Show a) => Show (Formula a) where
+    sb <+ TrueF = sb << "true"
+    sb <+ FalseF = sb << "false"
+    sb <+ XorF a b = sb << "(" <+ a << " `XorF` " <+ b << ")"
+    sb <+ AndF a b = sb  << "(" <+ a << " &&& " <+ b << ")"
+    sb <+ ConditionF c = sb  <+ c
+    sb <+ NextF a = sb  << "(next " <+ a << ")"
+    sb <+ UntilF a b = sb << "(" <+ a << " `UntilF` " <+ b << ")"
+
+xorF FalseF f2 = f2
+xorF f1 FalseF = f1             
+xorF f1@(XorF h1 t1) f2@(XorF h2 t2) = 
+    let cmp = compare h1 h2 
+    in  if cmp < 0
+        then XorF h1 (xorF t1 f2)
+        else if cmp > 0
+        then XorF h2 (xorF f1 t2)
+        else xorF t1 t2
+xorF f1@(XorF h1 t1) f2 = 
+    let cmp = compare h1 f2
+    in  if cmp < 0
+        then XorF h1 (xorF t1 f2)
+        else if cmp > 0
+        then XorF f2 f1
+        else t1
+xorF f1 f2@(XorF h2 t2) =
+    let cmp = compare f1 h2
+    in  if cmp < 0
+        then XorF f1 f2
+        else if cmp > 0
+        then XorF h2 (xorF f1 t2)
+        else t2
+xorF f1 f2 =
+    let cmp = compare f1 f2
+    in  if cmp < 0
+        then XorF f1 f2
+        else if cmp > 0
+        then XorF f2 f1
+        else TrueF
+        
+notF f = xorF TrueF f
+
+TrueF &&& f2 = f2
+f1 &&& TrueF = f1
+FalseF &&& _ = FalseF
+_ &&& FalseF = FalseF
+XorF h1 t1 &&& f2 = xorF (h1 &&& f2) (t1 &&& f2)
+f1 &&& XorF h2 t2 = xorF (f1 &&& h2) (f1 &&& t2)
+f1@(AndF h1 t1) &&& f2@(AndF h2 t2) = 
+    let cmp = compare h1 h2 
+    in  if cmp < 0
+        then AndF h1 (t1 &&& f2)
+        else if cmp > 0
+        then AndF h2 (f1 &&& t2)
+        else AndF h1 (t1 &&& t2)
+f1@(AndF h1 t1) &&& f2 = 
+    let cmp = compare h1 f2
+    in  if cmp < 0
+        then AndF h1 (t1 &&& f2)
+        else if cmp > 0
+        then AndF f2 f1
+        else f1
+f1 &&& f2@(AndF h2 t2) =
+    let cmp = compare f1 h2
+    in  if cmp < 0
+        then AndF f1 f2
+        else if cmp > 0
+        then AndF h2 (f1 &&& t2)
+        else f2
+f1 &&& f2 =
+    let cmp = compare f1 f2
+    in  if cmp < 0
+        then AndF f1 f2
+        else if cmp > 0
+        then AndF f2 f1
+        else f1
+
+f1 ||| f2 = xorF (xorF f1 f2) (f1 &&& f2)
+        
+eval :: Ord a => (a -> <e> Boolean) -> Formula a -> <e> Formula a
+eval s TrueF = TrueF
+eval s FalseF = FalseF
+eval s (XorF f1 f2) = xorF (eval s f1) (eval s f2)
+eval s (AndF f1 f2) = eval s f1 &&& eval s f2
+eval s (ConditionF c) = if s c then TrueF else FalseF
+eval s (NextF f) = f
+eval s (UntilF f1 f2) = eval s f2 ||| (eval s f1 &&& UntilF f1 f2)
+
+// Concrete conditions
+
+data V = V String (Ref Boolean)
+
+instance Ord V where
+    compare (V a _) (V b _) = compare a b
+instance Show V where
+    sb <+ V a _ = sb <+ a 
+
+cond :: String -> Ref Boolean -> Formula V
+cond name ref = ConditionF (V name ref) 
+
+// Testing
+
+x = ref True
+y = ref False
+
+f = cond "x" x `UntilF` cond "y" y
+
+evalV = eval (\(V _ c) -> getRef c) 
+
+main = do
+    print (evalV f)
+    x := False
+    print (evalV f)
+    y = ref True
+    print (evalV f)
+    x := True
+    print (evalV f)
+--
+()
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable1.scl
deleted file mode 100644 (file)
index dc72fb0..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-import "Prelude"\r
-\r
-l :: [Integer]\r
-l = [1,2,3,4,5]\r
-main = hash l - foldl (\c x -> 31*c + x) 0 l\r
---\r
--1625180697
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Hashable2.scl
deleted file mode 100644 (file)
index ce3c5b7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-import "Prelude"\r
-\r
-l :: [Double]\r
-l = [1,2,3,4,5]\r
-main = hash l\r
---\r
-849277455
\ No newline at end of file
index 723a017d34c1a3d9fd5d150e56c6688b27e95ef6..8897d43ddd063b8b71e25a5d674aa9d3196a6de2 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, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
+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, LBRACKET, LET, LPAREN, MATCH, MDO, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Matching3b.scl
new file mode 100644 (file)
index 0000000..4864345
--- /dev/null
@@ -0,0 +1,8 @@
+import "StandardLibrary"
+
+foo 1 = "one"
+foo 2 = "two"
+
+main = if True then foo (2 :: Long) else foo (1 :: Integer)
+--
+two
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/MatchingWithMissingParameter.scl
new file mode 100644 (file)
index 0000000..33a681f
--- /dev/null
@@ -0,0 +1,10 @@
+data Foo = Foo Integer Integer
+         | Bar
+         
+isFoo (Foo _) = True
+isFoo _ = False
+
+main = "Hello world!"
+--
+4:7-4:14: The function is applied with too few parameters.
+
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading1.scl
new file mode 100644 (file)
index 0000000..dfb6079
--- /dev/null
@@ -0,0 +1,19 @@
+// module Foo1
+import "Prelude"
+
+foo :: Integer -> Boolean
+foo i = i == 5
+--
+// module Foo2
+import "Prelude"
+
+foo :: Integer -> Integer -> Boolean
+foo i j = i == j
+--
+import "Prelude"
+import "Foo1"
+import "Foo2"
+
+main = foo 5 && foo 5 4
+--
+false
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading2.scl
new file mode 100644 (file)
index 0000000..e7a28de
--- /dev/null
@@ -0,0 +1,20 @@
+// module Max1
+import "Prelude"
+
+myMax :: Ord a => a -> a -> a
+myMax = max
+--
+// module Max2
+import "Prelude"
+
+myMax :: Ord a => a -> a -> a -> a
+myMax a b c = max a (max b c)
+--
+import "Prelude"
+import "Max1"
+import "Max2"
+
+main = myMax (1 :: Integer) 2 3 + myMax (3 :: Integer) 2 1 + myMax 4 2 :: Integer
+--
+10
+
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Overloading3.scl
new file mode 100644 (file)
index 0000000..9385ce7
--- /dev/null
@@ -0,0 +1,23 @@
+// module M1
+import "Prelude"
+
+foo :: Ring a => Boolean -> a -> a
+foo True v = v+1
+foo False v = v+1 
+--
+// module M2
+import "Prelude"
+
+foo :: Ring a => String -> a -> a
+foo cond v = if cond=="true"
+             then v+1
+             else v-1 
+--
+import "Prelude"
+import "M1"
+import "M2"
+
+main = foo False (foo "True" 10) :: Integer
+--
+10
+
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/RecordShorthand.scl
new file mode 100644 (file)
index 0000000..d3af73e
--- /dev/null
@@ -0,0 +1,11 @@
+import "Prelude"
+
+data Vec = Vec { x :: Double, y :: Double }
+deriving instance Show Vec
+
+createVec x y = Vec {x, y}
+sumVec Vec { x1, y1 } Vec { x2, y2 } = Vec { x = x1+x2, y = y1 + y2 }
+
+main = sumVec (createVec 1 2) (createVec 3 4)
+-- 
+(Vec 4.0 6.0)
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Seq.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Seq.scl
deleted file mode 100644 (file)
index 4b60e52..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-import "Prelude"\r
-import "JavaBuiltin" as Java\r
-\r
-class Seq seq el where\r
-    myLength :: seq -> Integer\r
-    myGet :: seq -> Integer -> el\r
-\r
-instance (b ~ Character) => Seq String b where\r
-    myLength = Java.method "length"\r
-    myGet = Java.method "charAt"\r
-    \r
-instance (b ~ a) => Seq [a] b where\r
-    myLength = Java.method "size"\r
-    myGet = Java.method "get"\r
-\r
-//main :: (Character, String)\r
-main = (myGet "abc" 1, myGet ["a", "b", "c"] 1)\r
---\r
-(b,b)
\ No newline at end of file
diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/StringEscape.scl
new file mode 100644 (file)
index 0000000..51a75d3
--- /dev/null
@@ -0,0 +1,12 @@
+main = "a\nb\"c\'d"\r
+--\r
+a\r
+b"c'd\r
+--\r
+main = "a\u0053"\r
+--\r
+aS\r
+--\r
+main = "a\xb"\r
+--\r
+1:8-1:10: Illegal string escape character.\r
index 891815259e46f059a7c8a0612853f6ee8f9a305b..270d5751b12a559597f6385fea282838840286ee 100644 (file)
@@ -1,4 +1,4 @@
-a = =\r
-b = 4\r
---\r
-1:5-1:6: Unexpected token '=' (EQUALS). Expected one of ATTACHED_HASH, BEGIN_STRING, BLANK, CHAR, DO, ENFORCE, ESCAPED_SYMBOL, FLOAT, ID, IF, INTEGER, LAMBDA, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.\r
+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, LBRACKET, LET, LPAREN, MATCH, MDO, MINUS, SELECT, SELECT_DISTINCT, SELECT_FIRST, TRANSFORMATION, WHEN.
\ No newline at end of file
index 5fbc73cf9d13a70907f2e45c166afd7d2cd840c8..fa3bd9f65988011ca71f8fa7f46fdeec2f7dd4cb 100644 (file)
@@ -1,11 +1,7 @@
 package org.simantics.scl.compiler.tests.unit;\r
 \r
-import gnu.trove.set.hash.THashSet;\r
-\r
 import java.util.Collection;\r
 \r
-import junit.framework.Assert;\r
-\r
 import org.junit.Test;\r
 import org.simantics.scl.compiler.environment.filter.AcceptAllNamespaceFilter;\r
 import org.simantics.scl.compiler.environment.filter.NamespaceFilter;\r
@@ -13,6 +9,9 @@ import org.simantics.scl.compiler.environment.filter.NamespaceFilters;
 import org.simantics.scl.compiler.environment.filter.NegativeNamespaceFilter;\r
 import org.simantics.scl.compiler.environment.filter.PositiveNamespaceFilter;\r
 \r
+import gnu.trove.set.hash.THashSet;\r
+import junit.framework.Assert;\r
+\r
 public class TestNamespaceFilter {\r
     \r
     private void testBooleanOperations(Collection<String> all, NamespaceFilter a, NamespaceFilter b) {\r
index 66431fe50628ac47e7dd8bfcdf6681da31d688cb..975dd57fd843548bc8433c5e19d80feca1bdc9d9 100644 (file)
@@ -105,7 +105,6 @@ public class BundleModuleSource extends EncodedTextualModuleSource {
     }\r
 \r
     public void checkUpdates() {\r
-        System.out.println(url + " checkUpdates");\r
         if(digest != null && listeners != null) {\r
             byte[] newDigest = computeDigest();\r
             if(!Arrays.equals(digest, newDigest)) {\r
@@ -137,7 +136,6 @@ public class BundleModuleSource extends EncodedTextualModuleSource {
     \r
     @Override\r
     public void update(String newSourceText) {\r
-        System.out.println(url + " update");\r
         try {\r
             Path path = getPath();\r
             Files.write(path, newSourceText.getBytes(Charset.forName("UTF-8")));\r
index 2a5d56d7e53f3f24d2130a478374f21a2f7e13ad..c064bd79cad0ecf986a1edc358f3e87a3c6d6c13 100644 (file)
@@ -43,9 +43,6 @@ public class BundleTestScriptRunnable implements TestRunnable {
         try {
             CommandSession session = new CommandSession(SCLOsgi.MODULE_REPOSITORY, handler);
             new TestScriptExecutor(session, reader, handler).execute();
-        } catch(Throwable e) {
-            CommandSession.formatException(handler, e);
-            throw e;
         } finally {
             reader.close();
         }
index ea449d36c200bff82cdc1685fcceab49471c0b72..64d5ac63dbeccba336c6b73cc6fd463e016a9497 100755 (executable)
@@ -6,7 +6,7 @@ Bundle-Version: 0.4.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.simantics.scl.runtime,
  org.simantics.scl.runtime.collection,
- org.simantics.scl.runtime.equations,
+ org.simantics.scl.runtime.exceptions,
  org.simantics.scl.runtime.function,
  org.simantics.scl.runtime.io,
  org.simantics.scl.runtime.lazy,
index accef0636d562b9c0c80ad4f68f76744dda153f9..cbbb8252da9b540f127d71c919d632dd206ff4d7 100755 (executable)
@@ -3,5 +3,4 @@ output.. = bin/
 bin.includes = META-INF/,\\r
                .,\\r
                scl/,\\r
-               schema/,\\r
-               plugin.xml
\ No newline at end of file
+               schema/
\ No newline at end of file
index 50376a61b6d61c0139f4187eccfab09f95e86078..7149fc63ef9d8d8ddc9256aa9ce4319213a8c924 100755 (executable)
@@ -1,9 +1,5 @@
 package org.simantics.scl.runtime;
 
-import gnu.trove.map.hash.TCustomHashMap;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.strategy.HashingStrategy;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -15,6 +11,10 @@ import org.simantics.scl.runtime.function.FunctionImpl1;
 import org.simantics.scl.runtime.function.FunctionImpl2;
 import org.simantics.scl.runtime.tuple.Tuple2;
 
+import gnu.trove.map.hash.TCustomHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.strategy.HashingStrategy;
+
 
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class Lists {
index 63fa2f1e28dc6b1240feb08ac2dd57ca233507cf..9b3da5232f49f186d2a718fdd983cdd8b2928473 100644 (file)
@@ -2,8 +2,6 @@ package org.simantics.scl.runtime;
 \r
 import gnu.trove.map.hash.THashMap;\r
 \r
-import java.util.Map;\r
-\r
 public class SCLContext extends THashMap<String,Object> {\r
     private static ThreadLocal<SCLContext> CONTEXT = new ThreadLocal<SCLContext>();\r
     private static ThreadLocal<OldContextNode> OLD_CONTEXT = new ThreadLocal<OldContextNode>();\r
index 8b1c71ef90370fbb9beaac0a8a190b3433192528..856ef28707e0967ede41e68a4bebd0549a0d454f 100644 (file)
@@ -2,7 +2,6 @@ package org.simantics.scl.runtime.equations;
 \r
 import java.util.ArrayList;\r
 import java.util.Collections;\r
-import java.util.Comparator;\r
 import java.util.List;\r
 \r
 import org.simantics.scl.runtime.SCLContext;\r
diff --git a/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/exceptions/MatchingException.java b/bundles/org.simantics.scl.runtime/src/org/simantics/scl/runtime/exceptions/MatchingException.java
new file mode 100644 (file)
index 0000000..9bca8d8
--- /dev/null
@@ -0,0 +1,13 @@
+package org.simantics.scl.runtime.exceptions;\r
+\r
+public class MatchingException extends RuntimeException {\r
+    private static final long serialVersionUID = -3364111368224089448L;\r
+\r
+    public MatchingException() {\r
+        super();\r
+    }\r
+    \r
+    public MatchingException(String message) {\r
+        super(message);\r
+    }\r
+}\r
index 5b515c26258041cd919eb0bab6381a95b7611545..69cfa77be98cdba4f9d1c246b73b1c10165c8e91 100644 (file)
@@ -1,13 +1,13 @@
 package org.simantics.scl.runtime.io;\r
 \r
-import gnu.trove.list.array.TByteArrayList;\r
-\r
 import java.io.EOFException;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
 import java.io.OutputStream;\r
 import java.nio.charset.Charset;\r
 \r
+import gnu.trove.list.array.TByteArrayList;\r
+\r
 public class SclIO {\r
 \r
     private static final Charset UTF8 = Charset.forName("UTF-8");\r
index 0a5b99dc6a342a2f5bb721ed44d3a20193150118..4294ee96aeaa5859958ed05df0589515482748cb 100644 (file)
@@ -1,12 +1,5 @@
 package org.simantics.scl.runtime.minigraph;
 
-import gnu.trove.impl.Constants;
-import gnu.trove.map.hash.TIntObjectHashMap;
-import gnu.trove.map.hash.TLongObjectHashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -15,6 +8,13 @@ import org.simantics.scl.runtime.SCLContext;
 import org.simantics.scl.runtime.function.Function;
 import org.simantics.scl.runtime.tuple.Tuple0;
 
+import gnu.trove.impl.Constants;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.TIntHashSet;
+
 public class Minigraph {
 
     private static final int[] EMPTY_INT_ARRAY = new int[0];
index 8bc899370bf341b59bf099b77683e4794174f939..4b465732344c617c470ff273c67c112c11be842a 100644 (file)
@@ -1,12 +1,12 @@
 package org.simantics.scl.runtime.unification;
 
-import gnu.trove.map.hash.THashMap;
-
 import java.util.Map;
 
 import org.simantics.scl.runtime.function.Function;
 import org.simantics.scl.runtime.tuple.Tuple0;
 
+import gnu.trove.map.hash.THashMap;
+
 public class UMapUtils {
     public static void put(Map<Object,Object> map, Object key, Object value) {
         if(map.containsKey(key))
index 15454c697905796bfa54049ee6db50eb44c686fc..fb164279d32b25779889cf3b7a5500310f85e3ea 100644 (file)
@@ -2,6 +2,5 @@ source.. = src/
 output.. = bin/\r
 bin.includes = META-INF/,\\r
                .,\\r
-               graphs/*.tg,\\r
                graph.tg\r
 src.includes = graph/\r
index 15454c697905796bfa54049ee6db50eb44c686fc..fb164279d32b25779889cf3b7a5500310f85e3ea 100644 (file)
@@ -2,6 +2,5 @@ source.. = src/
 output.. = bin/\r
 bin.includes = META-INF/,\\r
                .,\\r
-               graphs/*.tg,\\r
                graph.tg\r
 src.includes = graph/\r
diff --git a/bundles/org.simantics.threadlog/.classpath b/bundles/org.simantics.threadlog/.classpath
new file mode 100644 (file)
index 0000000..23e107f
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="examples"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/bundles/org.simantics.threadlog/.project b/bundles/org.simantics.threadlog/.project
new file mode 100644 (file)
index 0000000..2b62393
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.threadlog</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/bundles/org.simantics.threadlog/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.threadlog/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..81b6610
--- /dev/null
@@ -0,0 +1,8 @@
+#Fri Oct 30 22:48:46 EET 2009\r
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6\r
+org.eclipse.jdt.core.compiler.compliance=1.6\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.6\r
diff --git a/bundles/org.simantics.threadlog/META-INF/MANIFEST.MF b/bundles/org.simantics.threadlog/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..79b038e
--- /dev/null
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Threadlog
+Bundle-SymbolicName: org.simantics.threadlog
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.threadlog.internal.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ gnu.trove2;bundle-version="2.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.simantics.threadlog
diff --git a/bundles/org.simantics.threadlog/build.properties b/bundles/org.simantics.threadlog/build.properties
new file mode 100644 (file)
index 0000000..b088bf1
--- /dev/null
@@ -0,0 +1,15 @@
+###############################################################################\r
+# Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+# in Industry THTH ry.\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Eclipse Public License v1.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.eclipse.org/legal/epl-v10.html\r
+#\r
+# Contributors:\r
+#     VTT Technical Research Centre of Finland - initial API and implementation\r
+###############################################################################\r
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .\r
diff --git a/bundles/org.simantics.threadlog/examples/org/simantics/threadlog/examples/Example1.java b/bundles/org.simantics.threadlog/examples/org/simantics/threadlog/examples/Example1.java
new file mode 100644 (file)
index 0000000..9530553
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.examples;\r
+\r
+import static org.simantics.threadlog.ThreadLog.BEGIN;\r
+\r
+import org.simantics.threadlog.Task;\r
+import org.simantics.threadlog.ui.ThreadLogController;\r
+\r
+public class Example1 {\r
+\r
+       public static void main(String[] args) throws InterruptedException {\r
+               ThreadLogController.start();\r
+               \r
+               while(true) {\r
+                       Thread.sleep(50);\r
+                       Task t = BEGIN("Foo");\r
+                       Thread.sleep(100);\r
+                       t.end();\r
+               }               \r
+       }\r
+       \r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/Task.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/Task.java
new file mode 100644 (file)
index 0000000..d9198ca
--- /dev/null
@@ -0,0 +1,16 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog;\r
+\r
+public interface Task {\r
+       void end();\r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ThreadLog.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ThreadLog.java
new file mode 100644 (file)
index 0000000..a621474
--- /dev/null
@@ -0,0 +1,175 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog;\r
+\r
+import gnu.trove.TDoubleArrayList;\r
+import gnu.trove.TLongArrayList;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.BufferedOutputStream;\r
+import java.io.DataInput;\r
+import java.io.DataInputStream;\r
+import java.io.DataOutput;\r
+import java.io.DataOutputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.StreamCorruptedException;\r
+import java.util.ArrayList;\r
+\r
+public class ThreadLog {\r
+\r
+    private static final transient String HDR             = "TLOG";\r
+    private static final transient int    CURRENT_VERSION = 1;\r
+\r
+    static ThreadLog defaultLog;\r
+\r
+    ArrayList<String> tasks = new ArrayList<String>();\r
+    TDoubleArrayList times = new TDoubleArrayList();\r
+    TLongArrayList threads = new TLongArrayList();\r
+\r
+    public double[] getTimes() {\r
+        return times.toNativeArray();\r
+    }\r
+\r
+    public String[] getTasks() {\r
+        return tasks.toArray(new String[tasks.size()]);\r
+    }\r
+\r
+    public long[] getThreads() {\r
+        return threads.toNativeArray();\r
+    }\r
+\r
+    private class TaskImpl implements Task {\r
+        public String name;\r
+        public long thread;\r
+        public long beginTime;\r
+\r
+        public TaskImpl(String name) {\r
+            this.name = name;\r
+            this.thread = Thread.currentThread().getId();\r
+            this.beginTime = System.nanoTime();\r
+        }\r
+\r
+        @Override\r
+        public void end() {\r
+            long endTime = System.nanoTime();\r
+            synchronized(tasks) {\r
+                tasks.add(name);\r
+                times.add(beginTime*1e-9);\r
+                times.add(endTime*1e-9);\r
+                threads.add(thread);\r
+            }\r
+        }\r
+    }\r
+\r
+    private static enum DummyTask implements Task {\r
+        INSTANCE;\r
+\r
+        @Override\r
+        public void end() {\r
+        }\r
+    }\r
+\r
+    public Task begin(String name) {\r
+        return new TaskImpl(name);\r
+    }\r
+\r
+    public static Task BEGIN(String name) {\r
+        try {\r
+            if(defaultLog != null)\r
+                return defaultLog.begin(name);\r
+        } catch(NullPointerException e) {\r
+        }\r
+        return DummyTask.INSTANCE;\r
+    }\r
+\r
+    public static ThreadLog setDefaultThreadLog(ThreadLog log) {\r
+        ThreadLog currentLog = defaultLog;\r
+        defaultLog = log;\r
+        return currentLog;\r
+    }\r
+\r
+    // ------------------------------------------------------------------------\r
+    // SERIALIZATION\r
+    // ------------------------------------------------------------------------\r
+\r
+    public static ThreadLog deserialize(File file) throws IOException {\r
+        DataInputStream in = null;\r
+        try {\r
+            in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));\r
+            ThreadLog log = new ThreadLog();\r
+            log.doDeserialize(in);\r
+            return log;\r
+        } finally {\r
+            if (in != null) {\r
+                in.close();\r
+            }\r
+        }\r
+    }\r
+\r
+    public static ThreadLog deserialize(DataInput in) throws IOException {\r
+        ThreadLog log = new ThreadLog();\r
+        log.doDeserialize(in);\r
+        return log;\r
+    }\r
+\r
+    private void doDeserialize(DataInput in) throws IOException {\r
+        String hdr = in.readUTF();\r
+        if (!HDR.equals(hdr)) {\r
+            throw new StreamCorruptedException("invalid header '" + hdr + "', expected " + HDR);\r
+        }\r
+        int ver = in.readInt();\r
+        if (ver == CURRENT_VERSION) {\r
+            int taskCount = in.readInt();\r
+            for (int i = 0; i < taskCount; ++i) {\r
+                String task = in.readUTF();\r
+                double beginTime = in.readDouble();\r
+                double endTime = in.readDouble();\r
+                long threadId = in.readLong();\r
+                tasks.add(task);\r
+                times.add(beginTime);\r
+                times.add(endTime);\r
+                threads.add(threadId);\r
+            }\r
+        } else {\r
+            throw new StreamCorruptedException("unrecognized log version: " + ver);\r
+        }\r
+    }\r
+\r
+    public void serialize(File file) throws IOException {\r
+        DataOutputStream out = null;\r
+        try {\r
+            out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));\r
+            serialize(out);\r
+        } finally {\r
+            if (out != null) {\r
+                out.close();\r
+            }\r
+        }\r
+    }\r
+\r
+    public void serialize(DataOutput out) throws IOException {\r
+        out.writeUTF(HDR);\r
+        out.writeInt(CURRENT_VERSION);\r
+        int len = tasks.size();\r
+        out.writeInt(len);\r
+        for (int i = 0; i < len; ++i) {\r
+            out.writeUTF(tasks.get(i));\r
+            out.writeDouble(times.getQuick(i*2));\r
+            out.writeDouble(times.getQuick(i*2+1));\r
+            out.writeLong(threads.getQuick(i));\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/internal/Activator.java
new file mode 100644 (file)
index 0000000..908fbd0
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.internal;\r
+\r
+import org.eclipse.core.runtime.Plugin;\r
+import org.osgi.framework.BundleContext;\r
+import org.simantics.threadlog.ui.ThreadLogController;\r
+\r
+/**\r
+ * The activator class controls the plug-in life cycle\r
+ */\r
+public class Activator extends Plugin {\r
+\r
+       // The plug-in ID\r
+       public static final String PLUGIN_ID = "org.simantics.threadlog";\r
+\r
+       // The shared instance\r
+       private static Activator plugin;\r
+       \r
+       /**\r
+        * The constructor\r
+        */\r
+       public Activator() {\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext context) throws Exception {\r
+               super.start(context);\r
+               plugin = this;\r
+               \r
+               ThreadLogController.start();\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext context) throws Exception {\r
+               plugin = null;\r
+               super.stop(context);\r
+       }\r
+\r
+       /**\r
+        * Returns the shared instance\r
+        *\r
+        * @return the shared instance\r
+        */\r
+       public static Activator getDefault() {\r
+               return plugin;\r
+       }\r
+\r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Interval.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Interval.java
new file mode 100644 (file)
index 0000000..e7f2fa1
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.ui;\r
+\r
+public class Interval implements Comparable<Interval> {\r
+       String text;\r
+       double begin;\r
+       double end;\r
+       \r
+       public Interval(String text, double begin, double end) {\r
+               this.text = text;\r
+               this.begin = begin;\r
+               this.end = end;\r
+       }\r
+\r
+       @Override\r
+       public int compareTo(Interval o) {\r
+               return Double.compare(begin, o.begin);\r
+       }       \r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Lane.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/Lane.java
new file mode 100644 (file)
index 0000000..2c06e41
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.ui;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+public class Lane {\r
+       List<Interval> intervals = new ArrayList<Interval>();\r
+       \r
+       public void addInterval(Interval interval) {\r
+               intervals.add(interval);\r
+       }\r
+       \r
+       public double getEnd() {\r
+               return intervals.get(intervals.size()-1).end;\r
+       }\r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogController.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogController.java
new file mode 100644 (file)
index 0000000..36a605d
--- /dev/null
@@ -0,0 +1,101 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.ui;\r
+\r
+import java.awt.GridLayout;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.io.IOException;\r
+\r
+import javax.swing.JButton;\r
+import javax.swing.JFileChooser;\r
+import javax.swing.JFrame;\r
+import javax.swing.filechooser.FileNameExtensionFilter;\r
+\r
+import org.simantics.threadlog.ThreadLog;\r
+\r
+public class ThreadLogController extends JFrame {\r
+\r
+    private static final long serialVersionUID = -2487997716157625672L;\r
+    \r
+    boolean isLogging = false;\r
+    JButton logButton;\r
+    JButton loadButton;\r
+\r
+    public ThreadLogController() {\r
+        super("Thread log controller");\r
+        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\r
+\r
+        logButton = new JButton("Start logging");\r
+        logButton.addActionListener(new ActionListener() {\r
+\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+                if(isLogging) {\r
+                    logButton.setText("Start logging");\r
+                    isLogging = false;\r
+                    ThreadLog log = ThreadLog.setDefaultThreadLog(null);\r
+\r
+                    ThreadLogVisualizer visualizer = new ThreadLogVisualizer();\r
+                    visualizer.setLog(log);\r
+                    visualizer.setVisible(true);\r
+                }\r
+                else {\r
+                    logButton.setText("Stop logging");\r
+                    isLogging = true;\r
+                    ThreadLog.setDefaultThreadLog(new ThreadLog());\r
+                }\r
+            }\r
+\r
+        });\r
+        loadButton = new JButton("Load log");\r
+        loadButton.addActionListener(new ActionListener() {\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+                JFileChooser chooser = new JFileChooser();\r
+                FileNameExtensionFilter filter = new FileNameExtensionFilter(\r
+                        "Thread Logs (*.tlog)", "tlog", "tlog");\r
+                chooser.setFileFilter(filter);\r
+                int returnVal = chooser.showOpenDialog(ThreadLogController.this);\r
+                if (returnVal != JFileChooser.APPROVE_OPTION)\r
+                    return;\r
+\r
+                try {\r
+                    ThreadLog log = ThreadLog.deserialize(chooser.getSelectedFile());\r
+                    ThreadLogVisualizer visualizer = new ThreadLogVisualizer();\r
+                    visualizer.setLog(log);\r
+                    visualizer.setVisible(true);\r
+                } catch (IOException ex) {\r
+                    ex.printStackTrace();\r
+                }\r
+            }\r
+        });\r
+        getContentPane().setLayout(new GridLayout(2, 1));\r
+        getContentPane().add(logButton);\r
+        getContentPane().add(loadButton);\r
+\r
+        setSize(200, 100);\r
+    }\r
+\r
+    public static void start() {\r
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {\r
+            public void run() {\r
+                new ThreadLogController().setVisible(true);\r
+            }\r
+        });\r
+    }\r
+\r
+    public static void main(String[] args) {\r
+        start();\r
+    }\r
+\r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogVisualizer.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/ThreadLogVisualizer.java
new file mode 100644 (file)
index 0000000..db29a91
--- /dev/null
@@ -0,0 +1,187 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.ui;\r
+\r
+import gnu.trove.TLongObjectHashMap;\r
+import gnu.trove.TObjectProcedure;\r
+\r
+import java.awt.BorderLayout;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.KeyEvent;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+\r
+import javax.swing.AbstractAction;\r
+import javax.swing.JButton;\r
+import javax.swing.JFileChooser;\r
+import javax.swing.JFrame;\r
+import javax.swing.JToolBar;\r
+import javax.swing.filechooser.FileNameExtensionFilter;\r
+\r
+import org.simantics.threadlog.Task;\r
+import org.simantics.threadlog.ThreadLog;\r
+\r
+public class ThreadLogVisualizer extends JFrame {\r
+\r
+    private static final long serialVersionUID = 6250996509358338304L;\r
+    \r
+    TimeLineViewer viewer = new TimeLineViewer();\r
+    JToolBar toolbar = new JToolBar("Thread Log Visualizer Tools");\r
+    JButton saveButton = new JButton(new SaveAction());\r
+\r
+    ThreadLog currentLog;\r
+\r
+    public ThreadLogVisualizer() {\r
+        super("Thread log visualizer");\r
+        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\r
+        setSize(800, 600);\r
+\r
+        getContentPane().setLayout(new BorderLayout());\r
+        getContentPane().add(toolbar, BorderLayout.NORTH);\r
+        getContentPane().add(viewer, BorderLayout.CENTER);\r
+\r
+        toolbar.add(saveButton);\r
+    }\r
+\r
+    class SaveAction extends AbstractAction {\r
+        private static final long serialVersionUID = 1L;\r
+\r
+        public SaveAction() {\r
+            super("Save");\r
+            putValue(SHORT_DESCRIPTION, "Save the Current Log");\r
+            putValue(MNEMONIC_KEY, KeyEvent.VK_S);\r
+        }\r
+\r
+        @Override\r
+        public void actionPerformed(ActionEvent e) {\r
+            JFileChooser chooser = new JFileChooser();\r
+            FileNameExtensionFilter filter = new FileNameExtensionFilter(\r
+                    "Thread Logs (*.tlog)", "tlog", "tlog");\r
+            chooser.setFileFilter(filter);\r
+            int returnVal = chooser.showSaveDialog(ThreadLogVisualizer.this);\r
+            if (returnVal != JFileChooser.APPROVE_OPTION)\r
+                return;\r
+\r
+            try {\r
+                currentLog.serialize(chooser.getSelectedFile());\r
+            } catch (IOException ex) {\r
+                ex.printStackTrace();\r
+            }\r
+        }\r
+    }\r
+\r
+    public void setLog(ThreadLog log) {\r
+        this.currentLog = log;\r
+\r
+        String[] tasks = log.getTasks();\r
+        double[] times = log.getTimes();\r
+\r
+        // Relativize to the first task\r
+        double minTime = Double.POSITIVE_INFINITY;\r
+        double maxTime = Double.NEGATIVE_INFINITY;\r
+\r
+        for(int i=0;i<times.length;i+=2) {\r
+            double temp = times[i];\r
+            if(temp < minTime)\r
+                minTime = temp;\r
+\r
+            temp = times[i+1];\r
+            if(temp > maxTime)\r
+                maxTime = temp;\r
+        }\r
+        for(int i=0;i<times.length;++i)\r
+            times[i] -= minTime;\r
+        maxTime -= minTime;\r
+\r
+        // Group intervals by thread\r
+        TLongObjectHashMap<ArrayList<Interval>> intervals = new TLongObjectHashMap<ArrayList<Interval>>();\r
+        long[] threads = log.getThreads();\r
+        for(int i=0;i<tasks.length;++i) {\r
+            long thread = threads[i];\r
+            ArrayList<Interval> in = intervals.get(thread);\r
+            if(in == null) {\r
+                in = new ArrayList<Interval>();\r
+                intervals.put(thread, in);\r
+            }\r
+            in.add(new Interval(tasks[i], times[i*2], times[i*2+1]));\r
+        }\r
+\r
+        // Create lanes\r
+        viewer.clear();\r
+        intervals.forEachValue(new TObjectProcedure<ArrayList<Interval>>() {\r
+\r
+            @Override\r
+            public boolean execute(ArrayList<Interval> intervals) {\r
+                Collections.sort(intervals);\r
+                ArrayList<Lane> lanes = new ArrayList<Lane>();\r
+\r
+                int curLaneId = -1;\r
+                Lane curLane = null;\r
+                for(Interval in : intervals) {\r
+                    if(curLane == null || in.begin < curLane.getEnd()) {\r
+                        ++curLaneId;\r
+                        if(curLaneId < lanes.size())\r
+                            curLane = lanes.get(curLaneId);\r
+                        else {\r
+                            curLane = new Lane();\r
+                            lanes.add(curLane);\r
+                        }\r
+                    }\r
+                    else {\r
+                        while(curLaneId > 0) {\r
+                            Lane prevLane = lanes.get(curLaneId-1);\r
+                            if(prevLane.getEnd() > in.begin)\r
+                                break;\r
+                            --curLaneId;\r
+                            curLane = prevLane;\r
+                        }\r
+                    }\r
+                    curLane.addInterval(in);\r
+                }\r
+\r
+                for(Lane lane : lanes)\r
+                    viewer.addLane(lane);\r
+                return true;\r
+            }\r
+\r
+        });\r
+\r
+        // update viewer\r
+        viewer.repaint();\r
+    }\r
+\r
+    public void saveImage() {\r
+\r
+    }\r
+\r
+    public static void main(String[] args) throws Exception {\r
+        ThreadLog.setDefaultThreadLog(new ThreadLog());\r
+\r
+        {\r
+            Task A = ThreadLog.BEGIN("A");\r
+            Thread.sleep(200);\r
+            Task B = ThreadLog.BEGIN("B");\r
+            Thread.sleep(100);\r
+            B.end();\r
+            Thread.sleep(100);\r
+            Task C = ThreadLog.BEGIN("C");\r
+            Thread.sleep(100);\r
+            C.end();\r
+            A.end();\r
+        }\r
+\r
+        ThreadLogVisualizer vis = new ThreadLogVisualizer();\r
+        vis.setLog(ThreadLog.setDefaultThreadLog(null));\r
+        vis.setVisible(true);\r
+    }\r
+}\r
diff --git a/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java b/bundles/org.simantics.threadlog/src/org/simantics/threadlog/ui/TimeLineViewer.java
new file mode 100644 (file)
index 0000000..40aefb0
--- /dev/null
@@ -0,0 +1,184 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.threadlog.ui;\r
+\r
+import java.awt.Color;\r
+import java.awt.Dimension;\r
+import java.awt.Graphics;\r
+import java.awt.Graphics2D;\r
+import java.awt.Shape;\r
+import java.awt.event.MouseAdapter;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.MouseMotionAdapter;\r
+import java.awt.event.MouseWheelEvent;\r
+import java.awt.event.MouseWheelListener;\r
+import java.awt.geom.Rectangle2D;\r
+import java.awt.geom.RoundRectangle2D;\r
+import java.text.DecimalFormat;\r
+import java.text.Format;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Timer;\r
+import java.util.TimerTask;\r
+\r
+import javax.swing.JPanel;\r
+\r
+public class TimeLineViewer extends JPanel {\r
+\r
+    private static final long serialVersionUID = -7410066541298449720L;\r
+    \r
+    public static long TOOL_TIP_DELAY = 500;\r
+       public static double MIN_GRID_LINE_SEPARATION = 15;\r
+       \r
+       // Time line data\r
+       List<Lane> lanes = new ArrayList<Lane>();\r
+       \r
+       // For panning and zooming\r
+       double xScale = 100.0;\r
+       double xOffset = 0.0;\r
+       double yOffset = 0.0;\r
+       int oldX;\r
+       int oldY;\r
+       \r
+       // Tool tips\r
+       Timer toolTipTimer = new Timer();\r
+       class ToolTipTask extends TimerTask {\r
+\r
+               @Override\r
+               public void run() {\r
+                       System.out.println("show tooltip");                     \r
+               }\r
+               \r
+       }\r
+       \r
+       public TimeLineViewer() {\r
+               addMouseListener(new MouseAdapter() {\r
+               @Override\r
+               public void mousePressed(MouseEvent e) {\r
+                       oldX = e.getX();\r
+                       oldY = e.getY();\r
+               }\r
+               });\r
+        addMouseMotionListener(new MouseMotionAdapter() {              \r
+               @Override\r
+               public void mouseDragged(MouseEvent e) {\r
+                       int curX = e.getX();\r
+                       int curY = e.getY();\r
+                       int diffX = curX - oldX;\r
+                       int diffY = curY - oldY;\r
+                       oldX = curX;\r
+                       oldY = curY;\r
+                       \r
+                       xOffset -= diffX/xScale;\r
+                       yOffset -= diffY;\r
+                       repaint();\r
+               }\r
+               TimerTask toolTipTask;\r
+                       @Override\r
+               public void mouseMoved(MouseEvent e) {\r
+                               if(toolTipTask != null)\r
+                                       toolTipTask.cancel();\r
+                               toolTipTask = new ToolTipTask();\r
+                       toolTipTimer.schedule(toolTipTask, TOOL_TIP_DELAY);\r
+               }\r
+        });\r
+        addMouseWheelListener(new MouseWheelListener() {                       \r
+                       @Override\r
+                       public void mouseWheelMoved(MouseWheelEvent e) {\r
+                               xOffset += e.getX() / xScale;\r
+                               xScale *= Math.pow(1.25, -e.getWheelRotation());\r
+                               xOffset -= e.getX() / xScale;\r
+                               repaint();\r
+                       }\r
+               });\r
+       }\r
+       \r
+       public void addLane(Lane lane) {\r
+               lanes.add(lane);\r
+       }\r
+       \r
+       public void clear() {\r
+               lanes.clear();\r
+       }\r
+       \r
+       public void paintIntervals(Graphics2D g) {              \r
+               for(int laneId=0;laneId < lanes.size();++laneId) {\r
+                       Lane lane = lanes.get(laneId);\r
+                       \r
+                       double y = 35.0*laneId - yOffset;\r
+                       double height = 30.0;\r
+                       \r
+                       for(Interval interval : lane.intervals) {\r
+                               double x = (interval.begin - xOffset) * xScale; \r
+                               double width = (interval.end - interval.begin) * xScale;\r
+                               \r
+                               Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10.0, 10.0);\r
+                               g.setColor(Color.WHITE);\r
+                               g.fill(shape);\r
+                               g.setColor(Color.BLACK);\r
+                               g.draw(shape);\r
+                               \r
+                               Rectangle2D bounds = g.getFontMetrics().getStringBounds(interval.text, g);\r
+                               if(bounds.getWidth() < width)\r
+                                       g.drawString(interval.text, (float)(x+0.5*(width-bounds.getWidth())), (float)(y+20.0));\r
+                       }\r
+               }\r
+       }\r
+       \r
+       public void paintGrid(Graphics2D g) {\r
+               Dimension dim = getSize();\r
+               \r
+               g.setBackground(Color.WHITE);\r
+               g.clearRect(0, 0, dim.width, dim.height);\r
+               \r
+               double stepsize = 0.001;\r
+               double majorStepsize;\r
+               while(true) {\r
+                       majorStepsize = stepsize * 5.0;\r
+                       if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)\r
+                               break;\r
+                       stepsize = majorStepsize;\r
+                       majorStepsize = stepsize * 2.0;\r
+                       if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)\r
+                               break;\r
+                       stepsize = majorStepsize;\r
+               }\r
+               \r
+               double firstP = Math.ceil(xOffset / stepsize) * stepsize;\r
+               double lastP = Math.floor((xOffset + dim.width / xScale) / stepsize) * stepsize;\r
+               if(firstP < 0.0)\r
+                       firstP = 0.0;\r
+\r
+               Format format = new DecimalFormat();\r
+               for(double p = firstP;p <= lastP; p+=stepsize) {\r
+                       int x = (int)((p - xOffset) * xScale);\r
+                       if(Math.abs(p/majorStepsize - Math.round(p/majorStepsize)) < 1e-3) {\r
+                               g.setColor(Color.BLACK);\r
+                               String text = format.format(p);\r
+                               Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g);\r
+                               g.drawString(text, (float)(x-bounds.getWidth()*0.5), 12.0f);                            \r
+                       }\r
+                       else\r
+                               g.setColor(Color.LIGHT_GRAY);\r
+                       g.drawLine(x, 14, x, (int)dim.getHeight());\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public void paint(Graphics _g) {\r
+               Graphics2D g = (Graphics2D)_g;  \r
+                               \r
+               paintGrid(g);\r
+               paintIntervals(g);\r
+       }\r
+       \r
+}\r
index 06b47116557c835c041faa62d176d2c0d63f6b4f..b088bf189f5cea2ed5bd984e45bc934ad442ca44 100644 (file)
@@ -13,6 +13,3 @@ source.. = src/
 output.. = bin/\r
 bin.includes = META-INF/,\\r
                .\r
-javacSource=1.6\r
-javacTarget=1.6\r
-               
\ No newline at end of file
index 1dbd1ef20bdcb8f52238d43f113748b807b355dd..aa1e3ebd141d5b39475bf62254ca49847c98027c 100644 (file)
@@ -58,6 +58,7 @@
         <module>org.simantics.diagram.profile</module>\r
         <module>org.simantics.document</module>\r
         <module>org.simantics.document.base.ontology</module>\r
+        <module>org.simantics.document.linking.ontology</module>\r
         <module>org.simantics.document.linking.ui</module>\r
         <module>org.simantics.document.ontology</module>\r
         <module>org.simantics.document.server</module>\r
         <module>org.simantics.modeling.template2d.ontology</module>\r
         <module>org.simantics.modeling.template2d.ui</module>\r
         <module>org.simantics.modeling.ui</module>\r
+        <module>org.simantics.nativemem</module>\r
         <module>org.simantics.objmap2</module>\r
         <module>org.simantics.platform.ui.ontology</module>\r
         <module>org.simantics.project</module>\r
         <module>org.simantics.scl.commands</module>\r
         <module>org.simantics.scl.compiler</module>\r
         <module>org.simantics.scl.compiler.dummy</module>\r
+        <module>org.simantics.scl.data</module>\r
         <module>org.simantics.scl.db</module>\r
         <module>org.simantics.scl.expressions</module>\r
         <module>org.simantics.scl.osgi</module>\r
         <module>org.simantics.structural.ui</module>\r
         <module>org.simantics.structural2</module>\r
         <module>org.simantics.team.ui</module>\r
+        <module>org.simantics.threadlog</module>\r
         <module>org.simantics.trend</module>\r
         <module>org.simantics.ui</module>\r
         <module>org.simantics.user.ontology</module>\r
         <module>org.simantics.workbench</module>\r
         <module>org.simantics.workbench.ontology</module>\r
         <module>org.simantics.workbench.search</module>\r
+        <module>winterwell.markdown</module>\r
     </modules>\r
 </project>
\ No newline at end of file
diff --git a/bundles/winterwell.markdown/.classpath b/bundles/winterwell.markdown/.classpath
new file mode 100644 (file)
index 0000000..cf4ff31
--- /dev/null
@@ -0,0 +1,10 @@
+<?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.6"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="lib" path="lib/markdownj-1.0.2b4-0.3.0.jar"/>
+       <classpathentry kind="lib" path="lib/net.sf.paperclips_1.0.1.jar"/>
+       <classpathentry kind="lib" path="lib/winterwell.utils.jar"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/winterwell.markdown/.project b/bundles/winterwell.markdown/.project
new file mode 100644 (file)
index 0000000..16de671
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>winterwell.markdown</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/winterwell.markdown/META-INF/MANIFEST.MF b/bundles/winterwell.markdown/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..3c0bdf2
--- /dev/null
@@ -0,0 +1,41 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Markdown
+Bundle-SymbolicName: winterwell.markdown;singleton:=true
+Bundle-Version: 1.2.0.qualifier
+Bundle-Activator: winterwell.markdown.Activator
+Bundle-Vendor: Winterwell Associates Ltd
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.editors,
+ org.eclipse.jface.text,
+ org.eclipse.core.resources,
+ org.eclipse.ui.views,
+ org.eclipse.jface,
+ org.eclipse.swt,
+ org.eclipse.ui.workbench
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.core.internal.resources,
+ org.eclipse.jface.text,
+ org.eclipse.ui.texteditor
+Bundle-ClassPath: .,target/classes,lib/markdownj-1.0.2b4-0.3.0.jar,
+ lib/winterwell.utils.jar,
+ lib/net.sf.paperclips_1.0.1.jar
+Export-Package: com.petebevin.markdown,
+ com.petebevin.markdown.test,
+ net.sf.paperclips,
+ net.sf.paperclips.decorator,
+ winterwell.markdown,
+ winterwell.markdown.editors,
+ winterwell.markdown.pagemodel,
+ winterwell.markdown.preferences,
+ winterwell.markdown.views,
+ winterwell.utils,
+ winterwell.utils.containers,
+ winterwell.utils.gui,
+ winterwell.utils.io,
+ winterwell.utils.reporting,
+ winterwell.utils.threads,
+ winterwell.utils.time,
+ winterwell.utils.web
diff --git a/bundles/winterwell.markdown/build.properties b/bundles/winterwell.markdown/build.properties
new file mode 100644 (file)
index 0000000..ccfe656
--- /dev/null
@@ -0,0 +1,15 @@
+source.. = src/
+bin.includes = META-INF/,\
+               plugin.xml,\
+               icons/,\
+               .,\
+               lib/
+src.includes = src/,\
+               pom.xml,\
+               plugin.xml,\
+               icons/,\
+               lib/,\
+               .project,\
+               .classpath,\
+               META-INF/,\
+               build.properties
diff --git a/bundles/winterwell.markdown/icons/coffee.png b/bundles/winterwell.markdown/icons/coffee.png
new file mode 100644 (file)
index 0000000..2a8c92b
Binary files /dev/null and b/bundles/winterwell.markdown/icons/coffee.png differ
diff --git a/bundles/winterwell.markdown/icons/github-cat_yellow.png b/bundles/winterwell.markdown/icons/github-cat_yellow.png
new file mode 100644 (file)
index 0000000..a1e5ea9
Binary files /dev/null and b/bundles/winterwell.markdown/icons/github-cat_yellow.png differ
diff --git a/bundles/winterwell.markdown/icons/notepad.gif b/bundles/winterwell.markdown/icons/notepad.gif
new file mode 100644 (file)
index 0000000..1531593
Binary files /dev/null and b/bundles/winterwell.markdown/icons/notepad.gif differ
diff --git a/bundles/winterwell.markdown/icons/settings16_yellow.png b/bundles/winterwell.markdown/icons/settings16_yellow.png
new file mode 100644 (file)
index 0000000..27e5397
Binary files /dev/null and b/bundles/winterwell.markdown/icons/settings16_yellow.png differ
diff --git a/bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar b/bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar
new file mode 100644 (file)
index 0000000..5e8f22b
Binary files /dev/null and b/bundles/winterwell.markdown/lib/markdownj-1.0.2b4-0.3.0.jar differ
diff --git a/bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar b/bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar
new file mode 100644 (file)
index 0000000..1853182
Binary files /dev/null and b/bundles/winterwell.markdown/lib/net.sf.paperclips_1.0.1.jar differ
diff --git a/bundles/winterwell.markdown/lib/winterwell.utils.jar b/bundles/winterwell.markdown/lib/winterwell.utils.jar
new file mode 100644 (file)
index 0000000..1a5784a
Binary files /dev/null and b/bundles/winterwell.markdown/lib/winterwell.utils.jar differ
diff --git a/bundles/winterwell.markdown/plugin.xml b/bundles/winterwell.markdown/plugin.xml
new file mode 100644 (file)
index 0000000..8d043e7
--- /dev/null
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.7"?>
+<plugin>
+
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            name="Markdown Editor"
+            extensions="txt,md,mdown,markdown,mdwn"
+            icon="icons/notepad.gif"
+            contributorClass="winterwell.markdown.editors.ActionBarContributor"
+            class="winterwell.markdown.editors.MarkdownEditor"
+            id="winterwell.markdown.editors.MarkdownEditor"
+            default="true">
+      </editor>
+      
+      <editor
+            class="winterwell.markdown.editors.MarkdownEditor"
+            contributorClass="winterwell.markdown.editors.ActionBarContributor"
+            default="true"
+            extensions="litcoffee"
+            icon="icons/coffee.png"
+            id="org.nodeclipse.ui.editors.LitCoffeeEditor"
+            name="LitCoffee (Markdown) Editor">
+      </editor>
+      
+   </extension>
+   
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:winterwell.markdown.views.MarkdownPreview">
+         <command
+               commandId="winterwell.markdown.commands.OpenGfmView"
+               icon="icons/github-cat_yellow.png"
+               style="push">
+         </command>
+         <command
+               commandId="winterwell.markdown.commands.Preferences"
+               icon="icons/settings16_yellow.png"
+               style="push">
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
+         <toolbar
+               id="winterwell.markdown.MarkdownEditor">
+            <command
+                  commandId="winterwell.markdown.commands.OpenMdView"
+                  icon="icons/notepad.gif"
+                  style="push">
+               <visibleWhen
+                     checkEnabled="true">
+               </visibleWhen>
+            </command>
+         </toolbar>
+      </menuContribution>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            defaultHandler="winterwell.markdown.commands.OpenGfmView"
+            id="winterwell.markdown.commands.OpenGfmView"
+            name="Open GitHub Flavored Markdown View">
+      </command>
+      <command
+            id="winterwell.markdown.commands.OpenMdView"
+            name="Open Markdown View">
+      </command>
+      <command
+            defaultHandler="winterwell.markdown.commands.Preferences"
+            id="winterwell.markdown.commands.Preferences"
+            name="Preferences">
+      </command>
+   </extension>
+   
+   <extension
+         point="org.eclipse.ui.views">
+      <category
+            id="winterwell.markdown"
+            name="Markdown"/>
+      <view
+            category="winterwell.markdown"
+            class="winterwell.markdown.views.MarkdownPreview"
+            icon="icons/notepad.gif"
+            id="winterwell.markdown.views.MarkdownPreview"
+            name="Markdown View"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            class="winterwell.markdown.preferences.MarkdownPreferencePage"
+            id="winterwell.markdown.preferences.MarkdownPreferencePage"
+            name="Markdown"
+            category="org.eclipse.ui.preferencePages.GeneralTextEditor">
+         <keywordReference
+               id="winterwell.markdown.prefsKeywordReference">
+         </keywordReference>
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.keywords">
+      <keyword
+            id="winterwell.markdown.prefsKeywordReference"
+            label="word wrapping tool tags">
+      </keyword>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            defaultHandler="winterwell.markdown.editors.FormatAction"
+            description="Format the paragraph under the caret to fit the print margins by inserting/removing line-breaks"
+            id="winterwell.markdown.formatParagraphCommand"
+            name="Format paragraph">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.bindings">
+      <key
+            commandId="winterwell.markdown.formatParagraphCommand"
+            contextId="org.eclipse.ui.contexts.window"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="Alt+Q">
+      </key>
+   </extension>
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            id="winterwell.markdown.actionSet"
+            label="winterwell.markdown.actionSet">
+         <action
+               class="winterwell.markdown.editors.FormatAction"
+               definitionId="winterwell.markdown.formatParagraphCommand"
+               id="winterwell.markdown.formatParagraphAction"
+               label="Format paragraph"
+               menubarPath="edit"
+               style="push">
+         </action>
+      </actionSet>
+   </extension>
+   <extension
+         point="org.eclipse.ui.handlers">
+      <handler
+            class="winterwell.markdown.commands.OpenMdView"
+            commandId="winterwell.markdown.commands.OpenMdView">
+         <activeWhen>
+            <with
+                  variable="activeEditorId">
+               <equals
+                     value="winterwell.markdown.editors.MarkdownEditor">
+               </equals>
+            </with>
+         </activeWhen>
+      </handler>
+   </extension>
+
+</plugin>
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/Activator.java b/bundles/winterwell.markdown/src/winterwell/markdown/Activator.java
new file mode 100644 (file)
index 0000000..3000144
--- /dev/null
@@ -0,0 +1,60 @@
+package winterwell.markdown;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import winterwell.markdown.preferences.MarkdownPreferencePage;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+       // The plug-in ID
+       public static final String PLUGIN_ID = "winterwell.markdown";
+
+       // The shared instance
+       private static Activator plugin;
+       
+       /**
+        * The constructor
+        */
+       public Activator() {
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+        */
+       public void start(BundleContext context) throws Exception {
+               super.start(context);
+               plugin = this;
+               doInstall();
+               MarkdownPreferencePage.setDefaultPreferences(getPreferenceStore());
+       }
+
+       // ?? Have this method called by start(), saving a reminder so it doesn't repeat itself?? 
+       private void doInstall() {
+               // ??Try to make this the default for file types -- but is this possible??
+               // c.f. http://stackoverflow.com/questions/15877123/eclipse-rcp-programmatically-associate-file-type-with-editor
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+        */
+       public void stop(BundleContext context) throws Exception {
+               plugin = null;
+               super.stop(context);
+       }
+
+       /**
+        * Returns the shared instance
+        *
+        * @return the shared instance
+        */
+       public static Activator getDefault() {
+               return plugin;
+       }
+
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/LogUtil.java b/bundles/winterwell.markdown/src/winterwell/markdown/LogUtil.java
new file mode 100644 (file)
index 0000000..384b951
--- /dev/null
@@ -0,0 +1,41 @@
+package winterwell.markdown;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Nodeclipse Log Util
+ * @author Lamb Gao, Paul Verest
+ */
+public class LogUtil {
+
+    public static void info(String message) {
+        log(IStatus.INFO, IStatus.OK, message, null);
+    }
+
+    public static void error(Throwable exception) {
+        error("Unexpected Exception", exception);
+    }
+
+    public static void error(String message) {
+        error(message, null);
+    }
+
+    public static void error(String message, Throwable exception) {
+        log(IStatus.ERROR, IStatus.ERROR, message, exception);
+    }
+
+    public static void log(int severity, int code, String message, Throwable exception) {
+        log(createStatus(severity, code, message, exception));
+    }
+
+    public static IStatus createStatus(int severity, int code, String message, Throwable exception) {
+        return new Status(severity, Activator.PLUGIN_ID, code, message, exception);
+    }
+
+    public static void log(IStatus status) {
+        ILog log = Activator.getDefault().getLog();
+        log.log(status);
+    }
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/StringMethods.java b/bundles/winterwell.markdown/src/winterwell/markdown/StringMethods.java
new file mode 100644 (file)
index 0000000..208e0ae
--- /dev/null
@@ -0,0 +1,557 @@
+/**\r
+ * Basic String manipulation utilities.\r
+ * (c) Winterwell 2010 and ThinkTank Mathematics 2007\r
+ */\r
+package winterwell.markdown;\r
+\r
+import java.math.BigInteger;\r
+import java.security.MessageDigest;\r
+import java.security.NoSuchAlgorithmException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Pattern;\r
+\r
+import winterwell.utils.Mutable;\r
+import winterwell.utils.containers.Pair;\r
+\r
+/**\r
+ * A collection of general-purpose String handling methods.\r
+ * \r
+ * @author daniel.winterstein\r
+ */\r
+public final class StringMethods {\r
+\r
+       /**\r
+        * Removes xml tags, comment blocks and script blocks.\r
+        * \r
+        * @param page\r
+        * @return the page with all xml tags removed.\r
+        */\r
+       public static String stripTags(String page) {\r
+               // This code is rather ugly, but it does the job\r
+               StringBuilder stripped = new StringBuilder(page.length());\r
+               boolean inTag = false;\r
+               // Comment blocks and script blocks are given special treatment\r
+               boolean inComment = false;\r
+               boolean inScript = false;\r
+               // Go through the text\r
+               for (int i = 0; i < page.length(); i++) {\r
+                       char c = page.charAt(i);\r
+                       // First check whether we are ignoring text\r
+                       if (inTag) {\r
+                               if (c == '>')\r
+                                       inTag = false;\r
+                       } else if (inComment) {\r
+                               if (c == '>' && page.charAt(i - 1) == '-'\r
+                                               && page.charAt(i - 1) == '-') {\r
+                                       inComment = false;\r
+                               }\r
+                       } else if (inScript) {\r
+                               if (c == '>' && page.substring(i - 7, i).equals("/script")) {\r
+                                       inScript = false;\r
+                               }\r
+                       } else {\r
+                               // Check for the start of a tag - looks for '<' followed by any\r
+                               // non-whitespace character\r
+                               if (c == '<' && !Character.isWhitespace(page.charAt(i + 1))) {\r
+                                       // Comment, script-block or tag?\r
+                                       if (page.charAt(i + 1) == '!' && page.charAt(i + 2) == '-'\r
+                                                       && page.charAt(i + 3) == '-') {\r
+                                               inComment = true;\r
+                                       } else if (i + 8 < page.length()\r
+                                                       && page.substring(i + 1, i + 7).equals("script")) {\r
+                                               inScript = true;\r
+                                               i += 7;\r
+                                       } else\r
+                                               inTag = true; // Normal tag by default\r
+                               } else {\r
+                                       // Append all non-tag chars\r
+                                       stripped.append(c);\r
+                               }\r
+                       } // end if...\r
+               }\r
+               return stripped.toString();\r
+       }\r
+       \r
+       /**\r
+        * The local line-end string. \n on unix, \r\n on windows, \r on mac.\r
+        */\r
+       public static final String LINEEND = System.getProperty("line.separator");\r
+\r
+       /**\r
+        * @param s\r
+        * @return A version of s where the first letter is uppercase and all others\r
+        *         are lowercase\r
+        */\r
+       public static final String capitalise(final String s) {\r
+               return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();\r
+       }\r
+\r
+       /**\r
+        * Convert all line breaks into the system line break.\r
+        */\r
+       public static final String convertLineBreaks(String text) {\r
+               return convertLineBreaks(text, LINEEND);\r
+       }\r
+\r
+       /**\r
+        * Convert all line breaks into the specified line break.\r
+        */\r
+       public static final String convertLineBreaks(String text, String br) {\r
+               text = text.replaceAll("\r\n", br);\r
+               text = text.replaceAll("\r", br);\r
+               text = text.replaceAll("\n", br);\r
+               return text;\r
+       }\r
+\r
+       /**\r
+        * @param string\r
+        * @param character\r
+        * @return the number of times character appears in the string\r
+        * @author Sam Halliday\r
+        */\r
+       static public int countCharsInString(String string, char character) {\r
+               int count = 0;\r
+               for (char c : string.toCharArray()) {\r
+                       if (c == character) {\r
+                               count++;\r
+                       }\r
+               }\r
+               return count;\r
+       }\r
+\r
+       /**\r
+        * \r
+        * E.g.\r
+        * <code>findEnclosingRegion("text with a [region] inside", 15, '[', ']')</code>\r
+        * is (??,??)\r
+        * \r
+        * @param text\r
+        * @param offset\r
+        * @param start\r
+        * @param end\r
+        * @return the smallest enclosed region (including start and end chars, the\r
+        *         1st number is inclusive, the 2nd exclusive), or null if none. So\r
+        *         text.subString(start,end) is the specified region\r
+        */\r
+       public static Pair<Integer> findEnclosingRegion(String text, int offset,\r
+                       char startMarker, char endMarker) {\r
+               // Forward\r
+               int end = findEnclosingRegion2(text, offset, endMarker, 1);\r
+               if (end == -1)\r
+                       return null;\r
+               end++; // end is exclusive\r
+               // Backward\r
+               int start = findEnclosingRegion2(text, offset, startMarker, -1);\r
+               if (start == -1)\r
+                       return null;\r
+               // Sanity\r
+               assert text.substring(start, end).charAt(0) == startMarker;\r
+               assert text.substring(start, end).endsWith("" + endMarker);\r
+               // Done\r
+               return new Pair<Integer>(start, end);\r
+       }\r
+\r
+       private static int findEnclosingRegion2(String text, int offset,\r
+                       char endMarker, int direction) {\r
+               while (offset > -1 && offset < text.length()) {\r
+                       char c = text.charAt(offset);\r
+                       if (c == endMarker)\r
+                               return offset;\r
+                       offset += direction;\r
+               }\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+        * A convenience wrapper for\r
+        * {@link #findEnclosingRegion(String, int, char, char)} E.g. <code>\r
+        findEnclosingRegion("text with a [region] inside", 15, '[', ']') .equals("[region]");\r
+        </code>\r
+        * \r
+        * @param text\r
+        * @param offset\r
+        * @param start\r
+        * @param end\r
+        * @return the smallest enclosed region (including start and end chars), or\r
+        *         null if none.\r
+        */\r
+       public static String findEnclosingText(String text, int offset,\r
+                       char startMarker, char endMarker) {\r
+               Pair<Integer> region = findEnclosingRegion(text, offset, startMarker,\r
+                               endMarker);\r
+               if (region == null)\r
+                       return null;\r
+               String s = text.substring(region.first, region.second);\r
+               return s;\r
+       }\r
+\r
+       /**\r
+        * Format a block of text to use the given line-width. I.e. adjust the line\r
+        * breaks. Also known as <i>hard</i> line-wrapping. Paragraphs are\r
+        * recognised by a line of blank space between them (e.g. two returns).\r
+        * <p>\r
+        * Note: a side-effect of this method is that it converts all line-breaks\r
+        * into the local system's line-breaks. E.g. on Windows, \n will become \r\n\r
+        * \r
+        * @param text\r
+        *            The text to format\r
+        * @param lineWidth\r
+        *            The number of columns in a line. Typically 78 or 80.\r
+        * @param respectLeadingCharacters\r
+        *            Can be null. If set, the specified leading characters will be\r
+        *            copied if the line is split. Use with " \t" to keep indented\r
+        *            paragraphs properly indented. Use with "> \t" to also handle\r
+        *            email-style quoting. Note that respected leading characters\r
+        *            receive no special treatment when they are used inside a\r
+        *            paragraph.\r
+        * @return A copy of text, formatted to the given line-width.\r
+        *         <p>\r
+        *         TODO: recognise paragraphs by changes in the respected leading\r
+        *         characters\r
+        */\r
+       public static String format(String text, int lineWidth, int tabWidth,\r
+                       String respectLeadingCharacters) {\r
+               // Switch to Linux line breaks for easier internal workings\r
+               text = convertLineBreaks(text, "\n");\r
+               // Find paragraphs\r
+               List<String> paras = format2_splitParagraphs(text,\r
+                               respectLeadingCharacters);\r
+               // Rebuild text\r
+               StringBuilder sb = new StringBuilder(text.length() + 10);\r
+               for (String p : paras) {\r
+                       String fp = format3_oneParagraph(p, lineWidth, tabWidth,\r
+                                       respectLeadingCharacters);\r
+                       sb.append(fp);\r
+                       // Paragraphs end with a double line break\r
+                       sb.append("\n\n");\r
+               }\r
+               // Pop the last line breaks\r
+               sb.delete(sb.length() - 2, sb.length());\r
+               // Convert line breaks to system ones\r
+               text = convertLineBreaks(sb.toString());\r
+               // Done\r
+               return text;\r
+       }\r
+\r
+       private static List<String> format2_splitParagraphs(String text,\r
+                       String respectLeadingCharacters) {\r
+               List<String> paras = new ArrayList<String>();\r
+               Mutable.Int index = new Mutable.Int(0);\r
+               // TODO The characters prefacing this paragraph\r
+               String leadingChars = "";\r
+               while (index.value < text.length()) {\r
+                       // One paragraph\r
+                       boolean inSpace = false;\r
+                       int start = index.value;\r
+                       while (index.value < text.length()) {\r
+                               char c = text.charAt(index.value);\r
+                               index.value++;\r
+                               if (!Character.isWhitespace(c)) {\r
+                                       inSpace = false;\r
+                                       continue;\r
+                               }\r
+                               // Line end?\r
+                               if (c == '\r' || c == '\n') {\r
+                                       // // Handle MS Windows 2 character \r\n line breaks\r
+                                       // if (index.value < text.length()) {\r
+                                       // char c2 = text.charAt(index.value);\r
+                                       // if (c=='\r' && c2=='\n') index.value++; // Push on past\r
+                                       // the 2nd line break char\r
+                                       // }\r
+                                       // Double line end - indicating a paragraph break\r
+                                       if (inSpace)\r
+                                               break;\r
+                                       inSpace = true;\r
+                               }\r
+                               // TODO Other paragraph markers, spotted by a change in\r
+                               // leadingChars\r
+                       }\r
+                       String p = text.substring(start, index.value);\r
+                       paras.add(p);\r
+               }\r
+               // Done\r
+               return paras;\r
+       }\r
+\r
+       /**\r
+        * Format a block of text to fit the given line width\r
+        * \r
+        * @param p\r
+        * @param lineWidth\r
+        * @param tabWidth\r
+        * @param respectLeadingCharacters\r
+        * @return\r
+        */\r
+       private static String format3_oneParagraph(String p, int lineWidth,\r
+                       int tabWidth, String respectLeadingCharacters) {\r
+               // Collect the reformatted paragraph\r
+               StringBuilder sb = new StringBuilder(p.length() + 10); // Allow for\r
+                                                                                                                               // some extra\r
+                                                                                                                               // line-breaks\r
+               // Get respected leading chars\r
+               String leadingChars = format4_getLeadingChars(p,\r
+                               respectLeadingCharacters);\r
+               // First Line\r
+               sb.append(leadingChars);\r
+               int lineLength = leadingChars.length();\r
+               int index = leadingChars.length();\r
+               // Loop\r
+               while (index < p.length()) {\r
+                       // Get the next word\r
+                       StringBuilder word = new StringBuilder();\r
+                       char c = p.charAt(index);\r
+                       index++;\r
+                       while (!Character.isWhitespace(c)) {\r
+                               word.append(c);\r
+                               if (index == p.length())\r
+                                       break;\r
+                               c = p.charAt(index);\r
+                               index++;\r
+                       }\r
+                       // Break the line if the word will not fit\r
+                       if (lineLength + word.length() > lineWidth && lineLength != 0) {\r
+                               trimEnd(sb);\r
+                               sb.append('\n'); // lineEnd(sb);\r
+                               // New line\r
+                               sb.append(leadingChars);\r
+                               lineLength = leadingChars.length();\r
+                       }\r
+                       // Add word\r
+                       sb.append(word);\r
+                       lineLength += word.length();\r
+                       // Add the whitespace\r
+                       if (index != p.length() && lineLength < lineWidth) {\r
+                               if (c == '\n') {\r
+                                       c = ' ';\r
+                               }\r
+                               sb.append(c);\r
+                               lineLength += (c == '\t') ? tabWidth : 1;\r
+                       }\r
+               }\r
+               // A final trim\r
+               trimEnd(sb);\r
+               // Done\r
+               return sb.toString();\r
+       }\r
+\r
+       /**\r
+        * \r
+        * @param text\r
+        * @param respectLeadingCharacters\r
+        *            Can be null\r
+        * @return The characters at the beginning of text which are respected. E.g.\r
+        *         ("> Hello", " \t>") --> "> "\r
+        */\r
+       private static String format4_getLeadingChars(String text,\r
+                       String respectLeadingCharacters) {\r
+               if (respectLeadingCharacters == null)\r
+                       return "";\r
+               // Line-breaks cannot be respected\r
+               assert respectLeadingCharacters.indexOf('\n') == -1;\r
+               // Look for the first non-respected char\r
+               for (int i = 0; i < text.length(); i++) {\r
+                       char c = text.charAt(i);\r
+                       if (respectLeadingCharacters.indexOf(c) == -1) {\r
+                               // Return the previous chars\r
+                               return text.substring(0, i);\r
+                       }\r
+               }\r
+               // All chars are respected\r
+               return text;\r
+       }\r
+\r
+       /**\r
+        * Ensure that line ends with the right line-end character(s)\r
+        */\r
+       public static final String lineEnd(String line) {\r
+               // strip possibly inappropriate line-endings\r
+               if (line.endsWith("\n")) {\r
+                       line = line.substring(0, line.length() - 1);\r
+               }\r
+               if (line.endsWith("\r\n")) {\r
+                       line = line.substring(0, line.length() - 2);\r
+               }\r
+               if (line.endsWith("\r")) {\r
+                       line = line.substring(0, line.length() - 1);\r
+               }\r
+               // add in proper line end\r
+               if (!line.endsWith(LINEEND)) {\r
+                       line += LINEEND;\r
+               }\r
+               return line;\r
+       }\r
+\r
+       /**\r
+        * Ensure that line ends with the right line-end character(s). This is more\r
+        * efficient than the version for Strings.\r
+        * \r
+        * @param line\r
+        */\r
+       public static final void lineEnd(final StringBuilder line) {\r
+               if (line.length() == 0) {\r
+                       line.append(LINEEND);\r
+                       return;\r
+               }\r
+               // strip possibly inappropriate line-endings\r
+               final char last = line.charAt(line.length() - 1);\r
+               if (last == '\n') {\r
+                       if ((line.length() > 1) && (line.charAt(line.length() - 2) == '\r')) {\r
+                               // \r\n\r
+                               line.replace(line.length() - 2, line.length(), LINEEND);\r
+                               return;\r
+                       }\r
+                       line.replace(line.length() - 1, line.length(), LINEEND);\r
+                       return;\r
+               }\r
+               if (last == '\r') {\r
+                       line.replace(line.length() - 1, line.length(), LINEEND);\r
+                       return;\r
+               }\r
+               line.append(LINEEND);\r
+               return;\r
+       }\r
+\r
+\r
+       \r
+       /**\r
+        * @param string\r
+        * @return the MD5 sum of the string using the default charset. Null if\r
+        *         there was an error in calculating the hash.\r
+        * @author Sam Halliday\r
+        */\r
+       public static String md5Hash(String string) {\r
+               MessageDigest md5 = null;\r
+               try {\r
+                       md5 = MessageDigest.getInstance("MD5");\r
+               } catch (NoSuchAlgorithmException e) {\r
+                       // ignore this exception, we know MD5 exists\r
+               }\r
+               md5.update(string.getBytes());\r
+               BigInteger hash = new BigInteger(1, md5.digest());\r
+               return hash.toString(16);\r
+       }\r
+\r
+       /**\r
+        * Removes HTML-style tags from a string.\r
+        * \r
+        * @param s\r
+        *            a String from which to remove tags\r
+        * @return a string with all instances of <.*> removed.\r
+        */\r
+       public static String removeTags(String s) {\r
+               StringBuffer sb = new StringBuffer();\r
+               boolean inTag = false;\r
+               for (int i = 0; i < s.length(); i++) {\r
+                       char c = s.charAt(i);\r
+                       if (c == '<')\r
+                               inTag = true;\r
+                       if (!inTag)\r
+                               sb.append(c);\r
+                       if (c == '>')\r
+                               inTag = false;\r
+               }\r
+               return sb.toString();\r
+       }\r
+\r
+       /**\r
+        * Repeat a character.\r
+        * \r
+        * @param c\r
+        * @param i\r
+        * @return A String consisting of i x c.\r
+        * @example assert repeat('-', 5).equals("-----");\r
+        */\r
+       public static String repeat(Character c, int i) {\r
+               StringBuilder dashes = new StringBuilder(i);\r
+               for (int j = 0; j < i; j++)\r
+                       dashes.append(c);\r
+               return dashes.toString();\r
+       }\r
+\r
+       /**\r
+        * Split a piece of text into separate lines. The line breaks are left at\r
+        * the end of each line.\r
+        * \r
+        * @param text\r
+        * @return The individual lines in the text.\r
+        */\r
+       public static List<String> splitLines(String text) {\r
+               List<String> lines = new ArrayList<String>();\r
+               // Search for lines\r
+               int start = 0;\r
+               for (int i = 0; i < text.length(); i++) {\r
+                       char c = text.charAt(i);\r
+                       if (c == '\r' || c == '\n') {\r
+                               // Handle MS Windows 2 character \r\n line breaks\r
+                               if (i + 1 < text.length()) {\r
+                                       char c2 = text.charAt(i + 1);\r
+                                       if (c == '\r' && c2 == '\n')\r
+                                               i++;\r
+                               }\r
+                               // Get the line, with the line break\r
+                               String line = text.substring(start, i + 1);\r
+                               lines.add(line);\r
+                               start = i + 1;\r
+                       }\r
+               }\r
+               // Last one\r
+               if (start != text.length()) {\r
+                       String line = text.substring(start);\r
+                       lines.add(line);\r
+               }\r
+               return lines;\r
+       }\r
+\r
+       /**\r
+        * Remove <i>trailing</i> whitespace. c.f. String#trim() which removes\r
+        * leading and trailing whitespace.\r
+        * \r
+        * @param sb\r
+        */\r
+       private static void trimEnd(StringBuilder sb) {\r
+               while (true) {\r
+                       // Get the last character\r
+                       int i = sb.length() - 1;\r
+                       if (i == -1)\r
+                               return; // Quit if sb is empty\r
+                       char c = sb.charAt(i);\r
+                       if (!Character.isWhitespace(c))\r
+                               return; // Finish?\r
+                       sb.deleteCharAt(i); // Remove and continue\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns true if the string is just whitespace, or empty, or null.\r
+        * \r
+        * @param s\r
+        */\r
+       public static final boolean whitespace(final String s) {\r
+               if (s == null) {\r
+                       return true;\r
+               }\r
+               for (int i = 0; i < s.length(); i++) {\r
+                       final char c = s.charAt(i);\r
+                       if (!Character.isWhitespace(c)) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * @param text\r
+        * @return the number of words in text. Uses a crude whitespace\r
+        * measure.\r
+        */\r
+       public static int wordCount(String text) {\r
+               String[] bits = text.split("\\W+");\r
+               int wc = 0;\r
+               for (String string : bits) {\r
+                       if (!whitespace(string)) wc++;\r
+               }\r
+               return wc;\r
+       }\r
+\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenGfmView.java b/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenGfmView.java
new file mode 100644 (file)
index 0000000..80dc8eb
--- /dev/null
@@ -0,0 +1,41 @@
+package winterwell.markdown.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import winterwell.markdown.LogUtil;
+
+public class OpenGfmView extends AbstractHandler {
+
+       @Override
+       public Object execute(final ExecutionEvent event) throws ExecutionException {
+               try {
+               IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+               String gfmViewId = "code.satyagraha.gfm.viewer.views.GfmView";
+               IViewPart gfmView = activePage.showView(gfmViewId);
+               activePage.activate(gfmView);
+               } catch (PartInitException e) {
+                       showError(e);
+           } catch (Exception e) {
+               showError(e);
+           }           
+               return null;
+       }
+
+       private void showError(Exception e) {
+               String title = "Exception while opening GitHub Flavored Markdown View";
+               String message = title+" (code.satyagraha.gfm.viewer.views.GfmView)"
+                               +"\nCheck Error Log View and continue at https://github.com/winterstein/Eclipse-Markdown-Editor-Plugin/issues/42"
+                               +"\n\nYou can also right-click file in Project Explorer"
+                               +"\n and select \"Show in GFM view\".";
+               LogUtil.error(message, e);
+               MessageDialog.openError(Display.getDefault().getActiveShell(), title , message);
+       }
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenMdView.java b/bundles/winterwell.markdown/src/winterwell/markdown/commands/OpenMdView.java
new file mode 100644 (file)
index 0000000..f36d7bd
--- /dev/null
@@ -0,0 +1,39 @@
+package winterwell.markdown.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+import winterwell.markdown.LogUtil;
+
+public class OpenMdView extends AbstractHandler {
+
+       @Override
+       public Object execute(final ExecutionEvent event) throws ExecutionException {
+               try {
+               IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage();
+               String mdViewId = "winterwell.markdown.views.MarkdownPreview";
+               IViewPart mdView = activePage.showView(mdViewId);
+               activePage.activate(mdView);
+               } catch (PartInitException e) {
+                       showError(e);
+           } catch (Exception e) {
+               showError(e);
+           }           
+               return null;
+       }
+
+       private void showError(Exception e) {
+               String title = "Exception while opening Markdown View";
+               String message = title+" (winterwell.markdown.views.MarkdownPreview)"
+                               +"\nCheck Error Log View";
+               LogUtil.error(message, e);
+               MessageDialog.openError(Display.getDefault().getActiveShell(), title , message);
+       }
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/commands/Preferences.java b/bundles/winterwell.markdown/src/winterwell/markdown/commands/Preferences.java
new file mode 100644 (file)
index 0000000..5c813a2
--- /dev/null
@@ -0,0 +1,20 @@
+package winterwell.markdown.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+
+public class Preferences extends AbstractHandler {
+
+       @Override
+       public Object execute(final ExecutionEvent event) throws ExecutionException {
+               PreferenceDialog pref = PreferencesUtil.createPreferenceDialogOn(
+                               PlatformUI.getWorkbench().getDisplay().getActiveShell(),
+                               "winterwell.markdown.preferences.MarkdownPreferencePage", null, null);
+               pref.open();
+               return null;
+       }
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ActionBarContributor.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ActionBarContributor.java
new file mode 100644 (file)
index 0000000..e41793f
--- /dev/null
@@ -0,0 +1,49 @@
+package winterwell.markdown.editors;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.editors.text.TextEditorActionContributor;
+
+import winterwell.markdown.views.MarkdownPreview;
+
+public class ActionBarContributor extends TextEditorActionContributor {
+       
+       private static IEditorPart activeEditor = null;
+
+//     IAction print = new PrintAction();
+
+       public void setActiveEditor(IEditorPart targetEditor) {
+               super.setActiveEditor(targetEditor);
+               activeEditor  = targetEditor;
+               // add print action
+               IActionBars bars= getActionBars();
+           if (bars != null) {
+//             todo bars.setGlobalActionHandler(ActionFactory.PRINT.getId(), print);
+//             bars.updateActionBars();
+           }
+           // Update preview?
+               if (MarkdownPreview.preview != null) {
+                       MarkdownPreview.preview.update();
+               }
+       }
+       public static IEditorPart getActiveEditor() {
+               return activeEditor;
+       }
+       
+       @Override
+       public void contributeToMenu(IMenuManager menu) {       
+               super.contributeToMenu(menu);
+               // Add format action
+               IMenuManager edit = menu.findMenuUsingPath("edit");
+               if (edit != null) {
+                       edit.add(new FormatAction());
+               }
+               // Add Export action
+               IMenuManager file = menu.findMenuUsingPath("file");
+               if (file != null) {
+                       file.appendToGroup("import.ext", new ExportHTMLAction());
+               }               
+       }
+
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ColorManager.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ColorManager.java
new file mode 100644 (file)
index 0000000..ff5728a
--- /dev/null
@@ -0,0 +1,28 @@
+package winterwell.markdown.editors;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+public class ColorManager {
+
+       protected Map fColorTable = new HashMap(10);
+
+       public void dispose() {
+               Iterator e = fColorTable.values().iterator();
+               while (e.hasNext())
+                        ((Color) e.next()).dispose();
+       }
+       public Color getColor(RGB rgb) {
+               Color color = (Color) fColorTable.get(rgb);
+               if (color == null) {
+                       color = new Color(Display.getCurrent(), rgb);
+                       fColorTable.put(rgb, color);
+               }
+               return color;
+       }
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/EmphasisRule.java
new file mode 100644 (file)
index 0000000..06f1420
--- /dev/null
@@ -0,0 +1,112 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 11 Jan 2007\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.jface.text.rules.ICharacterScanner;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.MultiLineRule;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+/**\r
+ * \r
+ *\r
+ * @author Daniel Winterstein\r
+ */\r
+public class EmphasisRule implements IRule {\r
+       private static char[][] fDelimiters = null;\r
+       private char[] fSequence;\r
+       protected IToken fToken;\r
+\r
+\r
+       public EmphasisRule(String marker, IToken token) {\r
+               assert marker.equals("*") || marker.equals("_") || marker.equals("**")\r
+                               || marker.equals("***") || marker.equals("`") || marker.equals("``");\r
+               Assert.isNotNull(token);\r
+               fSequence = marker.toCharArray();\r
+               fToken = token;\r
+       }\r
+       \r
+       // Copied from org.eclipse.jface.text.rules.PatternRule\r
+       protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {\r
+               for (int i = 1; i < sequence.length; i++) {\r
+                       int c = scanner.read();\r
+                       if (c == ICharacterScanner.EOF && eofAllowed) {\r
+                               return true;\r
+                       } else if (c != sequence[i]) {\r
+                               // Non-matching character detected, rewind the scanner back to\r
+                               // the start.\r
+                               // Do not unread the first character.\r
+                               for (int j = i; j > 0; j--)\r
+                                       scanner.unread();\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /*\r
+        * @see IRule#evaluate(ICharacterScanner)\r
+        * \r
+        * @since 2.0\r
+        */\r
+       public IToken evaluate(ICharacterScanner scanner) {\r
+               // Should be connected only on the right side\r
+               scanner.unread();\r
+               boolean sawSpaceBefore = Character.isWhitespace(scanner.read());\r
+               if (!sawSpaceBefore && scanner.getColumn() != 0) {\r
+                       return Token.UNDEFINED;\r
+               }\r
+\r
+               int c = scanner.read();\r
+               // Should be connected only on right side\r
+               if (c != fSequence[0] || !sequenceDetected(scanner, fSequence, false)) {\r
+                       scanner.unread();\r
+                       return Token.UNDEFINED;\r
+               }\r
+               int readCount = fSequence.length;\r
+               if (fDelimiters == null) {\r
+                       fDelimiters = scanner.getLegalLineDelimiters();\r
+               }\r
+               // Start sequence detected\r
+               int delimiterFound = 0;\r
+               // Is it a list item marker, or just a floating *?\r
+               if (sawSpaceBefore) {\r
+                       boolean after = Character.isWhitespace(scanner.read());\r
+                       scanner.unread();\r
+                       if (after)\r
+                               delimiterFound = 2;\r
+               }\r
+\r
+               while (delimiterFound < 2\r
+                               && (c = scanner.read()) != ICharacterScanner.EOF) {\r
+                       readCount++;\r
+\r
+                       if (!sawSpaceBefore && c == fSequence[0]\r
+                                       && sequenceDetected(scanner, fSequence, false)) {\r
+                               return fToken;\r
+                       }\r
+\r
+                       int i;\r
+                       for (i = 0; i < fDelimiters.length; i++) {\r
+                               if (c == fDelimiters[i][0]\r
+                                               && sequenceDetected(scanner, fDelimiters[i], true)) {\r
+                                       delimiterFound++;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (i == fDelimiters.length)\r
+                               delimiterFound = 0;\r
+                       sawSpaceBefore = Character.isWhitespace(c);\r
+               }\r
+               // Reached ICharacterScanner.EOF\r
+               for (; readCount > 0; readCount--)\r
+                       scanner.unread();\r
+               return Token.UNDEFINED;\r
+       }\r
+       \r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ExportHTMLAction.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ExportHTMLAction.java
new file mode 100644 (file)
index 0000000..3c9d26e
--- /dev/null
@@ -0,0 +1,37 @@
+package winterwell.markdown.editors;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPathEditorInput;
+
+import winterwell.utils.io.FileUtils;
+
+
+public class ExportHTMLAction extends Action {
+       public ExportHTMLAction() {
+               super("Export to HTML");
+       }
+       @Override
+       public void run() {
+               IEditorPart ed = ActionBarContributor.getActiveEditor();
+               if (!(ed instanceof MarkdownEditor)) {
+                       return;
+               }
+               MarkdownEditor editor = (MarkdownEditor) ed;
+               IEditorInput i = editor.getEditorInput();
+               if (i instanceof IPathEditorInput) {
+                       IPathEditorInput input = (IPathEditorInput) i;
+                       IPath path = input.getPath();
+                       path = path.removeFileExtension();
+                       path = path.addFileExtension("html");
+                       File file = path.toFile();
+                       String html = editor.getMarkdownPage().html();
+                       FileUtils.write(file, html);
+               }
+       }
+
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/FormatAction.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/FormatAction.java
new file mode 100644 (file)
index 0000000..cd16589
--- /dev/null
@@ -0,0 +1,190 @@
+package winterwell.markdown.editors;
+
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+import winterwell.markdown.pagemodel.MarkdownFormatter;
+import winterwell.markdown.pagemodel.MarkdownPage;
+import winterwell.markdown.pagemodel.MarkdownPage.KLineType;
+import winterwell.utils.containers.IntRange;
+
+/**
+ * TODO An action for formatting text (via hard wrapping, i.e. inserting returns).
+ * 
+ *
+ * @author daniel
+ */
+public class FormatAction extends Action implements IHandler {
+
+       public FormatAction() {
+               super("&Format paragraph");
+               setActionDefinitionId("winterwell.markdown.formatParagraphCommand");
+               setToolTipText("Format the paragraph under the caret by inserting/removing line-breaks");
+       }
+       
+       @Override
+       public void run() {
+               try {
+                       MarkdownEditor ed = (MarkdownEditor) ActionBarContributor.getActiveEditor();
+                       if (ed == null) return; // The active editor is not a markdown editor.
+                       int cols = ed.getPrintColumns();
+                       // Do we have a selection?
+                       ITextSelection s = (ITextSelection) ed.getSelectionProvider().getSelection();
+                       if (s != null && s.getLength() > 0) {
+                               formatSelectedRegion(ed, s, cols);
+                               return;
+                       }
+                       // Where is the caret?
+                       ISourceViewer viewer = ed.getViewer();
+                       int caretOffset = viewer.getTextWidget().getCaretOffset();
+                       int lineNum = ed.getDocument().getLineOfOffset(caretOffset);
+                       // Get a paragraph region
+                       MarkdownPage page = ed.getMarkdownPage();
+                       IRegion pRegion = getParagraph(page, lineNum, ed.getDocument());
+                       if (pRegion==null) {
+                               // Not in a paragraph - so give up
+                                // TODO tell the user why we've given up
+                               return;
+                       }
+                       String paragraph = ed.getDocument().get(pRegion.getOffset(), pRegion.getLength());
+                       // Format
+                       String formatted = MarkdownFormatter.format(paragraph, cols);
+                       if (formatted.equals(paragraph)) return; // No change!
+                       // Replace the unformatted region with the new formatted one
+                       ed.getDocument().replace(pRegion.getOffset(), pRegion.getLength(), formatted);
+                       // Done
+               } catch (Exception ex) {
+                       System.out.println(ex);
+               }
+       }
+
+       private void formatSelectedRegion(MarkdownEditor ed, ITextSelection s, int cols) 
+       throws BadLocationException {
+               int start = s.getStartLine();
+               int end = s.getEndLine();
+               IDocument doc = ed.getDocument();
+               int soff = doc.getLineOffset(start);
+               int eoff = lineEndOffset(end, doc);             
+               IntRange editedRegion = new IntRange(soff, eoff);               
+               MarkdownPage page = ed.getMarkdownPage();
+               StringBuilder sb = new StringBuilder(s.getLength());
+               for(int i=start; i<=end; i++) {
+                       IRegion para = getParagraph(page, i, ed.getDocument());
+                       if (para==null) {
+                               sb.append(page.getText().get(i));
+                               continue;
+                       }
+                       String paragraph = ed.getDocument().get(para.getOffset(), para.getLength());
+//                     int lines = StrUtils.splitLines(paragraph).length;
+                       String formatted = MarkdownFormatter.format(paragraph, cols);
+                       // append formatted and move forward
+                       sb.append(formatted);
+                       CharSequence le = lineEnd(i, doc);
+                       sb.append(le);
+                       int pEnd = doc.getLineOfOffset(para.getOffset()+para.getLength());
+                       i = pEnd;
+                       // Adjust edited region?
+                       IntRange pr = new IntRange(para.getOffset(), 
+                                       para.getOffset()+para.getLength()+le.length());                 
+                       editedRegion = new IntRange(Math.min(pr.low, editedRegion.low), 
+                                                                               Math.max(pr.high, editedRegion.high));                  
+               }               
+               // Replace the unformatted region with the new formatted one
+               String old = doc.get(editedRegion.low, editedRegion.size());
+               String newText = sb.toString();
+               if (old.equals(newText)) return;
+               ed.getDocument().replace(editedRegion.low, editedRegion.size(), newText);               
+       }
+
+       private CharSequence lineEnd(int line, IDocument doc) throws BadLocationException {
+               int eoff = doc.getLineOffset(line) + doc.getLineInformation(line).getLength();          
+               char c = doc.getChar(eoff);
+               if (c=='\r' && doc.getLength() > eoff+1 
+                               && doc.getChar(eoff+1) =='\n') return "\r\n";
+               return ""+c;
+       }
+
+       private int lineEndOffset(int end, IDocument doc) 
+       throws BadLocationException {
+               int eoff = doc.getLineOffset(end) + doc.getLineInformation(end).getLength();
+               // Include line end
+               char c = doc.getChar(eoff);
+               if (c=='\r' && doc.getLength() > eoff+1 
+                               && doc.getChar(eoff+1) =='\n') eoff += 2;
+               else eoff += 1;
+               return eoff;
+       }
+
+       /**
+        * 
+        * @param page
+        * @param lineNum
+        * @param doc
+        * @return region of paragraph containing this line, or null
+        * @throws BadLocationException
+        */
+       private IRegion getParagraph(MarkdownPage page, int lineNum, IDocument doc) 
+       throws BadLocationException {
+               // Get doc info
+               List<String> lines = page.getText();
+               List<KLineType> lineInfo = page.getLineTypes();
+               // Check we are in a paragraph or list
+               KLineType pType = lineInfo.get(lineNum);
+               switch(pType) {
+               case NORMAL: break;
+               default: // Not in a paragraph, so we cannot format.  
+                       return null;
+               }
+               // Work out the paragraph
+               // Beginning
+               int start;
+               for(start=lineNum; start>-1; start--) {
+                       if (lineInfo.get(start) != pType) {
+                               start++;
+                               break;
+                       }
+               }
+               // End
+               int end;
+               for(end=lineNum; end<lines.size(); end++) {
+                       if (lineInfo.get(end) != pType) {
+                               end--;
+                               break;
+                       }
+               }
+               // Get offset info
+               int sOff = doc.getLineOffset(start);
+               IRegion endLine = doc.getLineInformation(end);  // exclude final line end
+               int eOff = endLine.getOffset()+endLine.getLength();
+               return new Region(sOff, eOff-sOff);
+       }
+
+       public void addHandlerListener(IHandlerListener handlerListener) {
+               // Ignore
+       }
+
+       public void dispose() {
+               // Ignore               
+       }
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               run();
+               return null;
+       }
+
+       public void removeHandlerListener(IHandlerListener handlerListener) {
+               // Ignore               
+       }
+       
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/HeaderRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/HeaderRule.java
new file mode 100644 (file)
index 0000000..532e8ad
--- /dev/null
@@ -0,0 +1,22 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 11 Jan 2007\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.PatternRule;\r
+\r
+/**\r
+ * \r
+ *\r
+ * @author Daniel Winterstein\r
+ */\r
+public class HeaderRule extends PatternRule {\r
+               \r
+       public HeaderRule(IToken token) {               \r
+               super("#", null, token, (char) 0, true, true);\r
+               setColumnConstraint(0);\r
+       }\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/HeaderWithUnderlineRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/HeaderWithUnderlineRule.java
new file mode 100644 (file)
index 0000000..f5970d0
--- /dev/null
@@ -0,0 +1,73 @@
+/**\r
+ * @author Telmo Brugnara\r
+ * 10 Feb 2014\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import org.eclipse.jface.text.rules.ICharacterScanner;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+public class HeaderWithUnderlineRule implements IRule {\r
+\r
+       IToken successToken = null;\r
+       \r
+       public HeaderWithUnderlineRule(IToken token) {\r
+               successToken = token;\r
+       }\r
+       \r
+       public IToken evaluate(ICharacterScanner scanner) {\r
+               int c = -1;\r
+               int scanCount = 0;\r
+               if (scanner.getColumn()==0) {\r
+                       do {\r
+                               c = scanner.read();\r
+                               scanCount++;\r
+                       } while (!isNewLine((char) c) && c != ICharacterScanner.EOF);\r
+                       if(c == ICharacterScanner.EOF) {\r
+                               // is not a header\r
+                               for(int i=0;i<scanCount;i++) { scanner.unread(); }\r
+                               return Token.UNDEFINED;\r
+                       }\r
+                       c = scanner.read();\r
+                       scanCount++;\r
+                       if(c == '\r') {\r
+                               c = scanner.read();\r
+                               scanCount++;\r
+                       }\r
+                       if(!isUnderline((char) c)) {\r
+                               // is not a header\r
+                               for(int i=0;i<scanCount;i++) { scanner.unread(); }\r
+                               return Token.UNDEFINED;\r
+                       }\r
+                       do {\r
+                               c = scanner.read();\r
+                               scanCount++;\r
+                               if(isNewLine((char) c) || c == ICharacterScanner.EOF) {\r
+                                       //scanner.unread();\r
+                                       return successToken;\r
+                               }\r
+                               if(!isUnderline((char) c) && !isWhitespace((char) c) && c != '\r') {\r
+                                       // is not a header\r
+                                       for(int i=0;i<scanCount;i++) { scanner.unread(); }\r
+                                       return Token.UNDEFINED;\r
+                               }\r
+                       } while (true);\r
+               }\r
+\r
+               return Token.UNDEFINED;\r
+       }\r
+       \r
+       boolean isNewLine(char c) {\r
+               return c == '\n';\r
+       }\r
+\r
+       boolean isUnderline(char c) {\r
+               return c == '=' || c == '-';\r
+       }\r
+\r
+       boolean isWhitespace(char c) {\r
+               return c == ' ' || c == '\t';\r
+       }\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/LinkRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/LinkRule.java
new file mode 100644 (file)
index 0000000..4beeb68
--- /dev/null
@@ -0,0 +1,123 @@
+/**
+ * Copyright winterwell Mathematics Ltd.
+ * @author Daniel Winterstein
+ * 11 Jan 2007
+ */
+package winterwell.markdown.editors;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * 
+ *
+ * @author Amir Pakdel
+ */
+public class LinkRule implements IRule {
+       private static char[][] fDelimiters = null;
+       protected IToken fToken;
+
+       public LinkRule(IToken token) {
+               Assert.isNotNull(token);
+               fToken= token;
+       }
+       
+       /*
+        * @see IPredicateRule#getSuccessToken()
+        * @since 2.0
+        */
+       public IToken getSuccessToken() {
+               return fToken;
+       }
+
+
+       // Copied from org.eclipse.jface.text.rules.PatternRule
+       protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {
+               for (int i= 1; i < sequence.length; i++) {
+                       int c= scanner.read();
+                       if (c == ICharacterScanner.EOF && eofAllowed) {
+                               return true;
+                       } else if (c != sequence[i]) {
+                               // Non-matching character detected, rewind the scanner back to the start.
+                               // Do not unread the first character.
+                               scanner.unread();
+                               for (int j= i-1; j > 0; j--)
+                                       scanner.unread();
+                               return false;
+                       }
+               }
+               return true;
+       }
+       
+       /*
+        * @see IRule#evaluate(ICharacterScanner)
+        * @since 2.0
+        */
+       public IToken evaluate(ICharacterScanner scanner) {
+               int c;
+               if ((c = scanner.read()) != '[') {
+                       if ((c != 'h' || ( !sequenceDetected(scanner, "http://".toCharArray(), false) && !sequenceDetected(scanner, "https://".toCharArray(), false) ))
+                                       && (c != 'f' || !sequenceDetected(scanner, "ftp://".toCharArray(), false)) ) {
+                               // Not even a non-standard link
+                               scanner.unread();
+                               return Token.UNDEFINED;
+                       }
+                       
+                       //+ preventing NPE (Non-standard link should not be below as comment above suggests) by Paul Verest
+                       if (fDelimiters == null) {
+                               scanner.unread();
+                               return Token.UNDEFINED;
+                       }
+                       
+                       // Non-standard link
+                       while ((c = scanner.read()) != ICharacterScanner.EOF && !Character.isWhitespace(c)) {
+                               for (int i = 0; i < fDelimiters.length; i++) {
+                                       if (c == fDelimiters[i][0] && sequenceDetected(scanner, fDelimiters[i], true)) {
+                                               return fToken;
+                                       }
+                               }
+                       }
+                       return fToken;
+               }
+               if (fDelimiters == null) {
+                       fDelimiters = scanner.getLegalLineDelimiters();
+               }
+               int readCount = 1;
+               
+               // Find '](' and then find ')'
+               boolean sequenceFound = false;
+               int delimiterFound = 0;
+               while ((c = scanner.read()) != ICharacterScanner.EOF && delimiterFound < 2) {
+                       readCount++;
+                       if ( !sequenceFound && c == ']') {
+                               c = scanner.read();
+                               if (c == '(') {
+                                       readCount++;
+                                       sequenceFound = true;
+                               } else {
+                                       scanner.unread();
+                               }
+                       } else if (c == ')') { // '](' is already found
+                               return fToken;
+                       }
+                       
+                       int i;
+                       for (i = 0; i < fDelimiters.length; i++) {
+                               if (c == fDelimiters[i][0] && sequenceDetected(scanner, fDelimiters[i], true)) {
+                                       delimiterFound ++;
+                                       break;
+                               }       
+                       }
+                       if (i == fDelimiters.length)
+                               delimiterFound = 0;
+               }
+               
+               for (; readCount > 0; readCount--)
+                       scanner.unread();
+               return Token.UNDEFINED;
+       }
+       
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/ListRule.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/ListRule.java
new file mode 100644 (file)
index 0000000..11ff3f0
--- /dev/null
@@ -0,0 +1,77 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 11 Jan 2007\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Arrays;\r
+\r
+import org.eclipse.core.runtime.Assert;\r
+import org.eclipse.jface.text.rules.ICharacterScanner;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.Token;\r
+\r
+/**\r
+ * \r
+ *\r
+ * @author Daniel Winterstein\r
+ */\r
+public class ListRule implements IRule {\r
+       private ArrayList<Integer> markerList;\r
+       protected IToken fToken;\r
+               \r
+       public ListRule(IToken token) { \r
+               Assert.isNotNull(token);\r
+               fToken= token;\r
+       }\r
+       \r
+\r
+       /*\r
+        * @see IRule#evaluate(ICharacterScanner)\r
+        * @since 2.0\r
+        */\r
+       public IToken evaluate(ICharacterScanner scanner) {\r
+               if (scanner.getColumn() != 0) {\r
+                       return Token.UNDEFINED;\r
+               }\r
+//             // Fast mode\r
+//             if (scanner.read() != '-') {\r
+//                     scanner.unread();\r
+//                     return Token.UNDEFINED;\r
+//             }\r
+//             if (Character.isWhitespace(scanner.read())) {\r
+//                     return fToken;\r
+//             }\r
+//             scanner.unread();\r
+//             scanner.unread();\r
+//             return Token.UNDEFINED;\r
+//             // Fast mode\r
+               int readCount = 0;\r
+               int c;\r
+               while ((c = scanner.read()) != ICharacterScanner.EOF) {\r
+                       readCount++;\r
+                       if( !Character.isWhitespace( c ) ) {\r
+                               int after = scanner.read();\r
+//                             readCount++;\r
+                               scanner.unread();\r
+//                             if ( markerList.contains(c) && Character.isWhitespace( after ) ) {\r
+                               if ( (c == '-' || c == '+' || c == '*') \r
+                                               && Character.isWhitespace( after ) ) {\r
+                                       return fToken;\r
+                               } else {\r
+                                       for (; readCount > 0; readCount--)\r
+                                               scanner.unread();\r
+                                       return Token.UNDEFINED;\r
+                               }\r
+                       }\r
+               }\r
+               // Reached ICharacterScanner.EOF\r
+               for (; readCount > 0; readCount--)\r
+                       scanner.unread();\r
+               return Token.UNDEFINED;\r
+       }\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDColorConstants.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDColorConstants.java
new file mode 100644 (file)
index 0000000..7197f31
--- /dev/null
@@ -0,0 +1,9 @@
+package winterwell.markdown.editors;
+
+import org.eclipse.swt.graphics.RGB;
+
+public interface MDColorConstants {
+       RGB COMMENT = new RGB(128, 0, 0);
+       RGB HEADER = new RGB(0, 0, 128);
+       RGB DEFAULT = new RGB(0, 0, 0);
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDConfiguration.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDConfiguration.java
new file mode 100644 (file)
index 0000000..f20a642
--- /dev/null
@@ -0,0 +1,81 @@
+package winterwell.markdown.editors;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.MonoReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+
+public class MDConfiguration extends TextSourceViewerConfiguration {
+       private ColorManager colorManager;
+
+       public MDConfiguration(ColorManager colorManager, IPreferenceStore prefStore) {
+               super(prefStore);
+               this.colorManager = colorManager;
+       }
+
+       @Override
+       public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+               MDScanner scanner = new MDScanner(colorManager);
+               PresentationReconciler pr = (PresentationReconciler) super.getPresentationReconciler(sourceViewer); // FIXME
+               DefaultDamagerRepairer ddr = new DefaultDamagerRepairer(scanner);
+               pr.setRepairer(ddr, IDocument.DEFAULT_CONTENT_TYPE);
+               pr.setDamager(ddr, IDocument.DEFAULT_CONTENT_TYPE);
+               return pr;
+       }
+
+       
+       @Override
+       public IReconciler getReconciler(ISourceViewer sourceViewer) {
+               // This awful mess adds in update support
+               // Get super strategy
+               IReconciler rs = super.getReconciler(sourceViewer);
+               if (true) return rs;    // Seems to work fine?!
+               final IReconcilingStrategy fsuperStrategy = rs==null? null : rs.getReconcilingStrategy("text");
+               // Add our own
+               IReconcilingStrategy strategy = new IReconcilingStrategy() {
+                       private IDocument doc;
+                       public void reconcile(IRegion partition) {
+                               MarkdownEditor ed = MarkdownEditor.getEditor(doc);
+                               if (ed != null) ed.updatePage(partition);
+                               if (fsuperStrategy!=null) fsuperStrategy.reconcile(partition);
+                       }
+                       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+                               MarkdownEditor ed = MarkdownEditor.getEditor(doc);
+                               if (ed != null) ed.updatePage(subRegion);
+                               if (fsuperStrategy!=null) fsuperStrategy.reconcile(dirtyRegion, subRegion);
+                       }
+                       public void setDocument(IDocument document) {
+                               this.doc = document;
+                               if (fsuperStrategy!=null) fsuperStrategy.setDocument(document);
+                       }                       
+               };
+               // Make a reconciler
+               MonoReconciler m2 = new MonoReconciler(strategy, true);
+               m2.setIsIncrementalReconciler(true);
+               m2.setProgressMonitor(new NullProgressMonitor());
+               m2.setDelay(500);
+               // Done
+               return m2;
+       }
+       
+       @SuppressWarnings("unused")
+       @Override
+       public ITextHover getTextHover(ISourceViewer sourceViewer,
+                       String contentType) {
+               if (true) return super.getTextHover(sourceViewer, contentType);
+               // Add hover support for images
+               return new MDTextHover();
+       }
+}
+
+
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDScanner.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDScanner.java
new file mode 100644 (file)
index 0000000..60a307b
--- /dev/null
@@ -0,0 +1,61 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 13 Jan 2007\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.preference.PreferenceConverter;\r
+import org.eclipse.jface.text.TextAttribute;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.IWhitespaceDetector;\r
+import org.eclipse.jface.text.rules.MultiLineRule;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+import org.eclipse.jface.text.rules.WhitespaceRule;\r
+import org.eclipse.swt.SWT;\r
+\r
+import winterwell.markdown.Activator;\r
+import winterwell.markdown.preferences.MarkdownPreferencePage;\r
+\r
+/**\r
+ * \r
+ *\r
+ * @author Daniel Winterstein\r
+ */\r
+public class MDScanner extends RuleBasedScanner {\r
+       ColorManager cm;\r
+    public MDScanner(ColorManager cm) {\r
+       this.cm = cm;\r
+       IPreferenceStore pStore = Activator.getDefault().getPreferenceStore();\r
+       Token heading = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_HEADER)), null, SWT.BOLD));\r
+       Token comment = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_COMMENT))));\r
+       Token emphasis = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_DEFUALT)), null, SWT.ITALIC));\r
+       Token list = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_HEADER)), null, SWT.BOLD));\r
+       Token link = new Token(new TextAttribute(cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_LINK)), null, TextAttribute.UNDERLINE));\r
+       Token code = new Token(new TextAttribute(\r
+                       cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_CODE)),\r
+                       cm.getColor(PreferenceConverter.getColor(pStore, MarkdownPreferencePage.PREF_CODE_BG)),\r
+                       SWT.NORMAL));\r
+        setRules(new IRule[] {\r
+           new LinkRule(link),\r
+           new HeaderRule(heading),\r
+           new HeaderWithUnderlineRule(heading),\r
+           new ListRule(list),\r
+           new EmphasisRule("_", emphasis),\r
+           new EmphasisRule("***", emphasis),\r
+           new EmphasisRule("**", emphasis),\r
+           new EmphasisRule("*", emphasis),\r
+           new EmphasisRule("``", code),\r
+           new EmphasisRule("`", code),\r
+           new MultiLineRule("<!--", "-->", comment),\r
+           // WhitespaceRule messes up with the rest of rules\r
+//           new WhitespaceRule(new IWhitespaceDetector() {\r
+//              public boolean isWhitespace(char c) {\r
+//                 return Character.isWhitespace(c);\r
+//              }\r
+//           }),\r
+        });\r
+     }\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDTextHover.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MDTextHover.java
new file mode 100644 (file)
index 0000000..04377a6
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * (c) Winterwell 2010 and ThinkTank Mathematics 2007
+ */
+package winterwell.markdown.editors;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+
+import winterwell.markdown.StringMethods;
+import winterwell.utils.containers.Pair;
+
+/**
+ * 
+ *
+ * @author daniel
+ */
+public class MDTextHover implements ITextHover //, ITextHoverExtension 
+{
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
+        */
+       public String getHoverInfo(ITextViewer textViewer, IRegion region) {
+               try {
+                       IDocument doc = textViewer.getDocument();
+                       String text = doc.get(region.getOffset(), region.getLength());
+                       return "<b>"+text+"</b>";
+               } catch (Exception e) {
+                       return null;
+               }               
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
+        */
+       public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+               try {
+                       IDocument doc = textViewer.getDocument();
+                       int line = doc.getLineOfOffset(offset);
+                       int lineOffset = doc.getLineOffset(line);
+                       int lineLength = doc.getLineLength(line);
+                       String text = doc.get(lineOffset, lineLength);
+                       // Look for image tags
+                       Pair<Integer> altRegion;
+                       Pair<Integer> urlRegion = 
+                               StringMethods.findEnclosingRegion(text, offset-lineOffset, '(', ')');
+                       if (urlRegion==null) {
+                               altRegion = StringMethods.findEnclosingRegion(text, offset-lineOffset, '[', ']');
+                               if (altRegion == null) return null;
+                               urlRegion = StringMethods.findEnclosingRegion(text, altRegion.second, '(', ')');
+                       } else {
+                               altRegion = StringMethods.findEnclosingRegion(text, urlRegion.first-1, '[', ']');
+                       }
+                       if (urlRegion==null || altRegion==null) return null;
+                       // Is it an image link?
+                       if (text.charAt(altRegion.first-1) != '!') return null;
+                       Region r = new Region(urlRegion.first+1+lineOffset, urlRegion.second-urlRegion.first-2);
+                       return r;
+               } catch (Exception ex) {
+                       return null;
+               }
+       }
+
+//     public IInformationControlCreator getHoverControlCreator() {
+//             return new IInformationControlCreator() {
+//                     public IInformationControl createInformationControl(Shell parent) {
+//                             int style= fIsFocusable ? SWT.V_SCROLL | SWT.H_SCROLL : SWT.NONE;
+//                             
+//                             if (BrowserInformationControl.isAvailable(parent)) {
+//                         final int shellStyle= SWT.TOOL | (fIsFocusable ? SWT.RESIZE : SWT.NO_TRIM);
+//                         return new BrowserInformationControl(parent, shellStyle, style, null);
+//                 }
+//                             return new DefaultInformationControl(parent, style, new HTMLTextPresenter());
+//                     }                                               
+//             };
+//     }
+
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownContentOutlinePage.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownContentOutlinePage.java
new file mode 100644 (file)
index 0000000..445a322
--- /dev/null
@@ -0,0 +1,538 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 11 Jan 2007\r
+ */\r
+package winterwell.markdown.editors;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.jface.action.IAction;\r
+import org.eclipse.jface.action.IToolBarManager;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.DocumentEvent;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.IDocumentListener;\r
+import org.eclipse.jface.text.IRegion;\r
+import org.eclipse.jface.text.Region;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.ITreeContentProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.SelectionChangedEvent;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.ui.IActionBars;\r
+import org.eclipse.ui.part.IPageSite;\r
+import org.eclipse.ui.texteditor.IDocumentProvider;\r
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;\r
+\r
+import winterwell.markdown.pagemodel.MarkdownPage;\r
+import winterwell.markdown.pagemodel.MarkdownPage.Header;\r
+import winterwell.markdown.pagemodel.MarkdownPage.KLineType;\r
+import winterwell.utils.StrUtils;\r
+import winterwell.utils.Utils;\r
+import winterwell.utils.web.WebUtils;\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Daniel Winterstein\r
+ */\r
+public final class MarkdownContentOutlinePage extends ContentOutlinePage {\r
+\r
+       /**\r
+        *\r
+        *\r
+        * @author Daniel Winterstein\r
+        */\r
+       public final class ContentProvider implements ITreeContentProvider,\r
+                       IDocumentListener {\r
+\r
+               // protected final static String SEGMENTS= "__md_segments";\r
+               // //$NON-NLS-1$\r
+               // protected IPositionUpdater fPositionUpdater= new\r
+               // DefaultPositionUpdater(SEGMENTS);\r
+               private MarkdownPage fContent;\r
+               // protected List fContent= new ArrayList(10);\r
+               private MarkdownEditor fTextEditor;\r
+\r
+               private void parse() {\r
+                       fContent = fTextEditor.getMarkdownPage();\r
+               }\r
+\r
+               /*\r
+                * @see IContentProvider#inputChanged(Viewer, Object, Object)\r
+                */\r
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
+                       // Detach from old\r
+                       if (oldInput != null) {\r
+                               IDocument document = fDocumentProvider.getDocument(oldInput);\r
+                               if (document != null) {\r
+                                       document.removeDocumentListener(this);\r
+                               }\r
+                       }\r
+                       fContent = null;\r
+                       // Attach to new\r
+                       if (newInput == null)\r
+                               return;\r
+                       IDocument document = fDocumentProvider.getDocument(newInput);\r
+                       if (document == null)\r
+                               return;\r
+                       fTextEditor = MarkdownEditor.getEditor(document);\r
+                       document.addDocumentListener(this);\r
+                       parse();\r
+               }\r
+\r
+               /*\r
+                * @see IContentProvider#dispose\r
+                */\r
+               public void dispose() {\r
+                       fContent = null;\r
+               }\r
+\r
+               /*\r
+                * @see IContentProvider#isDeleted(Object)\r
+                */\r
+               public boolean isDeleted(Object element) {\r
+                       return false;\r
+               }\r
+\r
+               /*\r
+                * @see IStructuredContentProvider#getElements(Object)\r
+                */\r
+               public Object[] getElements(Object element) {\r
+                       return fContent.getHeadings(null).toArray();\r
+               }\r
+\r
+               /*\r
+                * @see ITreeContentProvider#hasChildren(Object)\r
+                */\r
+               public boolean hasChildren(Object element) {\r
+                       if (element == fInput) {\r
+                               return true;\r
+                       }\r
+                       if (element instanceof MarkdownPage.Header) {\r
+                               MarkdownPage.Header header = (MarkdownPage.Header) element;\r
+                               return header.getSubHeaders().size() > 0;\r
+                       }\r
+                       ;\r
+                       return false;\r
+               }\r
+\r
+               /*\r
+                * @see ITreeContentProvider#getParent(Object)\r
+                */\r
+               public Object getParent(Object element) {\r
+                       if (!(element instanceof MarkdownPage.Header))\r
+                               return null;\r
+                       return ((MarkdownPage.Header) element).getParent();\r
+               }\r
+\r
+               /*\r
+                * @see ITreeContentProvider#getChildren(Object)\r
+                */\r
+               public Object[] getChildren(Object element) {\r
+                       if (element == fInput) {\r
+                               return fContent.getHeadings(null).toArray();\r
+                       }\r
+                       if (!(element instanceof MarkdownPage.Header))\r
+                               return null;\r
+                       return ((MarkdownPage.Header) element).getSubHeaders().toArray();\r
+               }\r
+\r
+               public void documentAboutToBeChanged(DocumentEvent event) {\r
+                       // nothing\r
+               }\r
+\r
+               public void documentChanged(DocumentEvent event) {\r
+                       parse();\r
+                       update();\r
+               }\r
+       }\r
+\r
+       private Object fInput = null;\r
+       private final IDocumentProvider fDocumentProvider;\r
+       private final MarkdownEditor fTextEditor;\r
+       protected boolean showWordCounts;\r
+       private List<Header> selectedHeaders;\r
+\r
+       /**\r
+        * @param documentProvider\r
+        * @param mdEditor\r
+        */\r
+       public MarkdownContentOutlinePage(IDocumentProvider documentProvider,\r
+                       MarkdownEditor mdEditor) {\r
+               fDocumentProvider = documentProvider;\r
+               fTextEditor = mdEditor;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc) Method declared on ContentOutlinePage\r
+        */\r
+       @Override\r
+       public void createControl(Composite parent) {\r
+               super.createControl(parent);\r
+               TreeViewer viewer = getTreeViewer();\r
+               viewer.setContentProvider(new ContentProvider());\r
+               // Add word count annotations\r
+               viewer.setLabelProvider(new LabelProvider() {\r
+                       @Override\r
+                       public String getText(Object element) {\r
+                               if (!(element instanceof MarkdownPage.Header))\r
+                                       return super.getText(element);\r
+                               Header header = ((MarkdownPage.Header) element);\r
+                               String hText = header.toString();\r
+                               if (!showWordCounts)\r
+                                       return hText;\r
+                               IRegion region = getRegion(header);\r
+                               String text;\r
+                               try {\r
+                                       text = fTextEditor.getDocument().get(region.getOffset(),\r
+                                                       region.getLength());\r
+                                       text = WebUtils.stripTags(text);\r
+                                       text = text.replaceAll("#", "").trim();\r
+                                       assert text.startsWith(hText);\r
+                                       text = text.substring(hText.length());\r
+                                       int wc = StrUtils.wordCount(text);\r
+                                       return hText + " (" + wc + ":" + text.length() + ")";\r
+                               } catch (BadLocationException e) {\r
+                                       return hText;\r
+                               }\r
+                       }\r
+               });\r
+               viewer.addSelectionChangedListener(this);\r
+\r
+               if (fInput != null)\r
+                       viewer.setInput(fInput);\r
+\r
+               // Buttons\r
+               IPageSite site = getSite();\r
+               IActionBars bars = site.getActionBars();\r
+               IToolBarManager toolbar = bars.getToolBarManager();\r
+               // Word count action\r
+               Action action = new Action("123", IAction.AS_CHECK_BOX) {\r
+                       @Override\r
+                       public void run() {\r
+                               showWordCounts = isChecked();\r
+                               update();\r
+                       }\r
+               };\r
+               action.setToolTipText("Show/hide section word:character counts");\r
+               toolbar.add(action);\r
+               // +/- actions\r
+               action = new Action("<") {\r
+                       @Override\r
+                       public void run() {\r
+                               doPromoteDemote(-1);\r
+                       }\r
+               };\r
+               action.setToolTipText("Promote the selected section\n -- move it up a level.");\r
+               toolbar.add(action);\r
+               //\r
+               action = new Action(">") {\r
+                       @Override\r
+                       public void run() {\r
+                               doPromoteDemote(1);\r
+                       }\r
+               };\r
+               action.setToolTipText("Demote the selected section\n -- move it down a level.");\r
+               toolbar.add(action);\r
+               // up/down actions\r
+               action = new Action("/\\") {\r
+                       @Override\r
+                       public void run() {\r
+                               try {\r
+                                       doMove(-1);\r
+                               } catch (BadLocationException e) {\r
+                                       throw Utils.runtime(e);\r
+                               }\r
+                       }\r
+               };\r
+               action.setToolTipText("Move the selected section earlier");\r
+               toolbar.add(action);\r
+               //\r
+               action = new Action("\\/") {\r
+                       @Override\r
+                       public void run() {\r
+                               try {\r
+                                       doMove(1);\r
+                               } catch (BadLocationException e) {\r
+                                       throw Utils.runtime(e);\r
+                               }\r
+                       }\r
+               };\r
+               action.setToolTipText("Move the selected section later");\r
+               toolbar.add(action);\r
+               // Collapse\r
+               ImageDescriptor id = ImageDescriptor.createFromFile(getClass(), "collapseall.gif");\r
+               action = new Action("collapse", id) {\r
+                       @Override\r
+                       public void run() {\r
+                               doCollapseAll();\r
+                       }\r
+               };\r
+               action.setImageDescriptor(id);\r
+               action.setToolTipText("Collapse outline tree");\r
+               toolbar.add(action);\r
+               // Sync\r
+               id = ImageDescriptor.createFromFile(getClass(), "synced.gif");\r
+               action = new Action("sync") {\r
+                       @Override\r
+                       public void run() {\r
+                               try {\r
+                                       doSyncToEditor();\r
+                               } catch (BadLocationException e) {\r
+                                       throw Utils.runtime(e);\r
+                               }\r
+                       }\r
+               };\r
+               action.setImageDescriptor(id);\r
+               action.setToolTipText("Link with editor");\r
+               toolbar.add(action);\r
+               // Add edit ability\r
+               viewer.getControl().addKeyListener(new KeyListener() {\r
+                       public void keyPressed(KeyEvent e) {\r
+                               if (e.keyCode==SWT.F2) {\r
+                                       doEditHeader();\r
+                               }\r
+                       }\r
+                       public void keyReleased(KeyEvent e) {\r
+                               //\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * @throws BadLocationException\r
+        *\r
+        */\r
+       protected void doSyncToEditor() throws BadLocationException {\r
+               TreeViewer viewer = getTreeViewer();\r
+               if (viewer == null) return;\r
+               // Get header\r
+               MarkdownPage page = fTextEditor.getMarkdownPage();\r
+               int caretOffset = fTextEditor.getViewer().getTextWidget().getCaretOffset();\r
+               IDocument doc = fTextEditor.getDocument();\r
+               int line = doc.getLineOfOffset(caretOffset);\r
+               List<KLineType> lineTypes = page.getLineTypes();\r
+               for(; line>-1; line--) {\r
+                       KLineType lt = lineTypes.get(line);\r
+                       if (lt.toString().startsWith("H")) break;\r
+               }\r
+               if (line<0) return;\r
+               Header header = (Header) page.getPageObject(line);\r
+               // Set\r
+               IStructuredSelection selection = new StructuredSelection(header);\r
+               viewer.setSelection(selection , true);\r
+       }\r
+\r
+       void doEditHeader() {\r
+               TreeViewer viewer = getTreeViewer();\r
+               viewer.editElement(selectedHeaders.get(0), 0);\r
+       }\r
+\r
+       protected void doCollapseAll() {\r
+               TreeViewer viewer = getTreeViewer();\r
+               if (viewer == null) return;\r
+//             Control control = viewer.getControl();\r
+//             if (control != null && !control.isDisposed()) {\r
+//                     control.setRedraw(false);\r
+               viewer.collapseAll();\r
+//                     control.setRedraw(true);\r
+//             }\r
+       }\r
+\r
+       /**\r
+        * Move the selected sections up/down\r
+        * @param i 1 or -1. 1==move later, -1=earlier\r
+        * @throws BadLocationException\r
+        */\r
+       protected void doMove(int i) throws BadLocationException {\r
+               assert i==1 || i==-1;\r
+               if (selectedHeaders == null || selectedHeaders.size() == 0)\r
+                       return;\r
+               // Get text region to move\r
+               MarkdownPage.Header first = selectedHeaders.get(0);\r
+               MarkdownPage.Header last = selectedHeaders.get(selectedHeaders.size()-1);\r
+               int start = fTextEditor.getDocument().getLineOffset(\r
+                               first.getLineNumber());\r
+               IRegion r = getRegion(last);\r
+               int end = r.getOffset() + r.getLength();\r
+               int length = end - start;\r
+               // Get new insertion point\r
+               int insert;\r
+               if (i==1) {\r
+                       Header nextSection = last.getNext();\r
+                       if (nextSection==null) return;\r
+                       IRegion nr = getRegion(nextSection);\r
+                       insert = nr.getOffset()+nr.getLength();\r
+               } else {\r
+                       Header prevSection = first.getPrevious();\r
+                       if (prevSection==null) return;\r
+                       IRegion nr = getRegion(prevSection);\r
+                       insert = nr.getOffset();\r
+               }\r
+               // Get text\r
+               String text = fTextEditor.getDocument().get();\r
+               // Move text\r
+               String section = text.substring(start, end);\r
+               String pre, post;\r
+               if (i==1) {\r
+                       pre = text.substring(0, start) + text.substring(end, insert);\r
+                       post = text.substring(insert);\r
+               } else {\r
+                       pre = text.substring(0, insert);\r
+                       post = text.substring(insert,start)+text.substring(end);\r
+               }\r
+               text =  pre + section + post;\r
+               assert text.length() == fTextEditor.getDocument().get().length() :\r
+                       text.length()-fTextEditor.getDocument().get().length()+" chars gained/lost";\r
+               // Update doc\r
+               fTextEditor.getDocument().set(text);\r
+       }\r
+\r
+       /**\r
+        * Does not support -------- / ========= underlining, only # headers\r
+        * @param upDown 1 for demote (e.g. h2 -> h3), -1 for promote (e.g. h2 -> h1)\r
+        */\r
+       protected void doPromoteDemote(int upDown) {\r
+               assert upDown==1 || upDown==-1;\r
+               if (selectedHeaders == null || selectedHeaders.size() == 0)\r
+                       return;\r
+               HashSet<Header> toAdjust = new HashSet<Header>(selectedHeaders);\r
+               HashSet<Header> adjusted = new HashSet<Header>();\r
+               // Adjust\r
+               MarkdownPage mdPage = fTextEditor.getMarkdownPage();\r
+               List<String> lines = new ArrayList<String>(mdPage.getText());\r
+               while(toAdjust.size() != 0) {\r
+                       Header h = toAdjust.iterator().next();\r
+                       toAdjust.remove(h);\r
+                       adjusted.add(h);\r
+                       String line = lines.get(h.getLineNumber());\r
+                       if (upDown==-1) {\r
+                               if (h.getLevel() == 1) return; // Level 1; can't promote\r
+                               if (line.startsWith("##")) line = line.substring(1);\r
+                               else {\r
+                                       return; // TODO support for ------ / ========\r
+                               }\r
+                       } else line = "#" + line;\r
+                       int ln = h.getLineNumber();\r
+                       lines.set(ln, line);\r
+                       // kids\r
+                       ArrayList<Header> kids = new ArrayList<Header>(h.getSubHeaders());\r
+                       for (Header header : kids) {\r
+                               if ( ! adjusted.contains(header)) toAdjust.add(header);\r
+                       }\r
+               }\r
+               // Set\r
+               StringBuilder sb = new StringBuilder();\r
+               for (String line : lines) {\r
+                       sb.append(line);\r
+               }\r
+               fTextEditor.getDocument().set(sb.toString());\r
+       }\r
+\r
+       /**\r
+        * The region of text for this header. This includes the header itself.\r
+        * @param header\r
+        * @return\r
+        * @throws BadLocationException\r
+        */\r
+       protected IRegion getRegion(Header header) {\r
+               try {\r
+                       IDocument doc = fTextEditor.getDocument();\r
+                       // Line numbers\r
+                       int start = header.getLineNumber();\r
+                       Header next = header.getNext();\r
+                       int end;\r
+                       if (next != null) {\r
+                               end = next.getLineNumber() - 1;\r
+                       } else {\r
+                               end = doc.getNumberOfLines() - 1;\r
+                       }\r
+                       int offset = doc.getLineOffset(start);\r
+                       IRegion ei = doc.getLineInformation(end);\r
+                       int length = ei.getOffset() + ei.getLength() - offset;\r
+                       return new Region(offset, length);\r
+               } catch (BadLocationException ex) {\r
+                       throw Utils.runtime(ex);\r
+               }\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc) Method declared on ContentOutlinePage\r
+        */\r
+       @Override\r
+       public void selectionChanged(SelectionChangedEvent event) {\r
+               super.selectionChanged(event);\r
+               selectedHeaders = null;\r
+               ISelection selection = event.getSelection();\r
+               if (selection.isEmpty())\r
+                       return;\r
+               if (!(selection instanceof IStructuredSelection))\r
+                       return;\r
+               try {\r
+                       IStructuredSelection strucSel = (IStructuredSelection) selection;\r
+                       Object[] sections = strucSel.toArray();\r
+                       selectedHeaders = (List) Arrays.asList(sections);\r
+                       MarkdownPage.Header first = (Header) sections[0];\r
+                       MarkdownPage.Header last = (Header) sections[sections.length - 1];\r
+                       int start = fTextEditor.getDocument().getLineOffset(\r
+                                       first.getLineNumber());\r
+                       int length;\r
+                       if (first == last) {\r
+                               length = fTextEditor.getDocument().getLineLength(\r
+                                               first.getLineNumber());\r
+                       } else {\r
+                               IRegion r = getRegion(last);\r
+                               int end = r.getOffset() + r.getLength();\r
+                               length = end - start;\r
+                       }\r
+                       fTextEditor.setHighlightRange(start, length, true);\r
+               } catch (Exception x) {\r
+                       System.out.println(x.getStackTrace());\r
+                       fTextEditor.resetHighlightRange();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the input of the outline page\r
+        *\r
+        * @param input\r
+        *            the input of this outline page\r
+        */\r
+       public void setInput(Object input) {\r
+               fInput = input;\r
+               update();\r
+       }\r
+\r
+       /**\r
+        * Updates the outline page.\r
+        */\r
+       public void update() {\r
+               TreeViewer viewer = getTreeViewer();\r
+\r
+               if (viewer != null) {\r
+                       Control control = viewer.getControl();\r
+                       if (control != null && !control.isDisposed()) {\r
+                               control.setRedraw(false);\r
+                               viewer.setInput(fInput);\r
+                               viewer.expandAll();\r
+                               control.setRedraw(true);\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownEditor.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/MarkdownEditor.java
new file mode 100644 (file)
index 0000000..86699c4
--- /dev/null
@@ -0,0 +1,455 @@
+package winterwell.markdown.editors;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionSupport;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+import winterwell.markdown.Activator;
+import winterwell.markdown.pagemodel.MarkdownPage;
+import winterwell.markdown.pagemodel.MarkdownPage.Header;
+import winterwell.markdown.preferences.MarkdownPreferencePage;
+import winterwell.markdown.views.MarkdownPreview;
+
+
+/**
+ * Text editor with markdown support.
+ * @author Daniel Winterstein
+ */
+public class MarkdownEditor extends TextEditor implements IDocumentListener 
+{
+
+       /**
+        * Maximum length for a task tag message
+        */
+       private static final int MAX_TASK_MSG_LENGTH = 80;
+       private ColorManager colorManager;
+       private MarkdownContentOutlinePage fOutlinePage = null;
+       
+       IDocument oldDoc = null;
+       
+       private MarkdownPage page;
+       
+       
+       private boolean pageDirty = true;
+       
+       private ProjectionSupport projectionSupport;
+       private final IPreferenceStore pStore;
+       private IPropertyChangeListener prefChangeListener;
+       
+
+       public MarkdownEditor() {
+               super();
+               pStore = Activator.getDefault().getPreferenceStore();
+               colorManager = new ColorManager();
+               setSourceViewerConfiguration(new MDConfiguration(colorManager, getPreferenceStore()));
+       }
+
+       
+       @Override
+       public void createPartControl(Composite parent) {
+               // Over-ride to add code-folding support 
+               super.createPartControl(parent);
+               if (getSourceViewer() instanceof ProjectionViewer) {
+                   ProjectionViewer viewer =(ProjectionViewer)getSourceViewer();
+                   projectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors());
+                   projectionSupport.install();
+                   //turn projection mode on
+                   viewer.doOperation(ProjectionViewer.TOGGLE);
+               }
+       }
+       
+       /**
+        *  Returns the editor's source viewer. May return null before the editor's part has been created and after disposal.
+        */
+       public ISourceViewer getViewer() {
+               return getSourceViewer();
+       }
+       
+       @Override
+       protected ISourceViewer createSourceViewer(Composite parent,
+                       IVerticalRuler ruler, int styles) {
+//             if (true) return super.createSourceViewer(parent, ruler, styles);
+               // Create with code-folding
+               ISourceViewer viewer = new ProjectionViewer(parent, ruler,
+                               getOverviewRuler(), isOverviewRulerVisible(), styles);
+               // ensure decoration support has been created and configured.
+               SourceViewerDecorationSupport decSupport = getSourceViewerDecorationSupport(viewer);
+//             SourceViewer viewer = (SourceViewer) super.createSourceViewer(parent, ruler, styles);
+               // Setup word-wrapping          
+               final StyledText widget = viewer.getTextWidget();
+               // Listen to pref changes
+               prefChangeListener = new IPropertyChangeListener() {
+                       public void propertyChange(PropertyChangeEvent event) {
+                               if (event.getProperty().equals(MarkdownPreferencePage.PREF_WORD_WRAP)) {
+                                       widget.setWordWrap(MarkdownPreferencePage.wordWrap());
+                               }
+                       }                       
+               };
+               pStore.addPropertyChangeListener(prefChangeListener);
+               // Switch on word-wrapping
+               if (MarkdownPreferencePage.wordWrap()) {
+                       widget.setWordWrap(true);
+               }               
+               return viewer;  
+       }
+       
+       public void dispose() {
+               if (pStore != null) {
+                       pStore.removePropertyChangeListener(prefChangeListener); 
+               }
+               colorManager.dispose();
+               super.dispose();                
+       }
+       public void documentAboutToBeChanged(DocumentEvent event) {
+       }
+
+       public void documentChanged(DocumentEvent event) {
+               pageDirty  = true;
+       }
+       
+       @Override
+       protected void doSetInput(IEditorInput input) throws CoreException {
+               // Detach from old
+               if (oldDoc!= null) {
+                       oldDoc.removeDocumentListener(this);
+                       if (doc2editor.get(oldDoc) == this) doc2editor.remove(oldDoc);
+               }
+               // Set
+               super.doSetInput(input);                
+               // Attach as a listener to new doc
+               IDocument doc = getDocument();
+               oldDoc = doc;
+               if (doc==null) return;          
+               doc.addDocumentListener(this);
+               doc2editor.put(doc, this);
+               // Initialise code folding
+               haveRunFolding = false;
+               updateSectionFoldingAnnotations(null);
+       }
+
+       @Override
+       protected void editorSaved() {
+               if (MarkdownPreview.preview != null) {
+                       // Update the preview when the file is saved
+                       MarkdownPreview.preview.update();
+               }
+       }
+
+       public Object getAdapter(Class required) {
+               if (IContentOutlinePage.class.equals(required)) {
+                       if (fOutlinePage == null) {
+                               fOutlinePage= new MarkdownContentOutlinePage(getDocumentProvider(), this);
+                               if (getEditorInput() != null)
+                                       fOutlinePage.setInput(getEditorInput());
+                       }
+                       return fOutlinePage;
+               }
+               return super.getAdapter(required);
+       }
+       public IDocument getDocument() {
+               IEditorInput input = getEditorInput();
+               IDocumentProvider docProvider = getDocumentProvider();          
+               return docProvider==null? null : docProvider.getDocument(input);
+       }
+       /**
+        * 
+        * @return The {@link MarkdownPage} for the document being edited, or null
+        * if unavailable.
+        */
+       public MarkdownPage getMarkdownPage() {
+               if (pageDirty) updateMarkdownPage();
+               return page;
+       }
+
+       public int getPrintColumns() {
+                return getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN);         
+       }
+
+       /**
+        * @return The text of the editor's document, or null if unavailable.
+        */
+       public String getText() {
+               IDocument doc = getDocument();
+               return doc==null? null : doc.get();
+       }
+
+       private void updateMarkdownPage() {
+               String text = getText();
+               if (text==null) text="";
+               page = new MarkdownPage(text);
+               pageDirty = false;
+       }
+
+       void updateTaskTags(IRegion region) {
+       try {   
+               boolean useTags = pStore.getBoolean(MarkdownPreferencePage.PREF_TASK_TAGS);
+               if (!useTags) return;           
+               // Get task tags
+//             IPreferenceStore peuistore = EditorsUI.getPreferenceStore();
+////           IPreferenceStore pStore_jdt = org.eclipse.jdt.core.compiler.getDefault().getPreferenceStore();
+//             String tagString = peuistore.getString("org.eclipse.jdt.core.compiler.taskTags");
+               String tagString = pStore.getString(MarkdownPreferencePage.PREF_TASK_TAGS_DEFINED);
+               List<String> tags = Arrays.asList(tagString.split(","));
+               // Get resource for editor
+               IFile docFile = getResource(this);
+               // Get existing tasks
+               IMarker[] taskMarkers = docFile.findMarkers(IMarker.TASK, true, IResource.DEPTH_INFINITE);
+               List<IMarker> markers = new ArrayList<IMarker>(Arrays.asList(taskMarkers));
+//             Collections.sort(markers, c) sort for efficiency
+               // Find tags in doc
+               List<String> text = getMarkdownPage().getText();
+               for(int i=1; i<=text.size(); i++) {
+                       String line = text.get(i-1); // wierd off-by-one bug
+                       for (String tag : tags) {
+                               tag = tag.trim();
+                               int tagIndex = line.indexOf(tag);
+                               if (tagIndex == -1) continue;
+                               IMarker exists = updateTaskTags2_checkExisting(i, tagIndex, line, markers);
+                               if (exists!=null) {
+                                       markers.remove(exists);
+                                       continue;
+                               }
+                               IMarker marker = docFile.createMarker(IMarker.TASK);                        
+                               //Once we have a marker object, we can set its attributes
+                               marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL);
+                               String msg = line.substring(line.indexOf(tag), Math.min(tagIndex+MAX_TASK_MSG_LENGTH, line.length()-1));
+                               marker.setAttribute(IMarker.MESSAGE, msg);
+                               marker.setAttribute(IMarker.LINE_NUMBER, i);                                                                    
+                       }
+               }
+               // Remove old markers
+               for (IMarker m : markers) {
+                       try {
+                               m.delete();             
+                       } catch (Exception ex) {
+                       //
+                       }                       
+               }
+       } catch (Exception ex) {
+               // 
+       }
+       }
+
+       /**
+        * Find an existing marker, if there is one.
+        * @param i
+        * @param tagIndex
+        * @param line
+        * @param markers
+        * @return 
+        */
+       private IMarker updateTaskTags2_checkExisting(int i, int tagIndex,
+                       String line, List<IMarker> markers) {           
+               String tagMessage = line.substring(tagIndex).trim();
+               for (IMarker marker : markers) {
+                       try {
+                           Integer lineNum = (Integer) marker.getAttribute(IMarker.LINE_NUMBER);
+                           if (i != lineNum) continue;
+                           String txt = ((String) marker.getAttribute(IMarker.MESSAGE)).trim();
+                           if (tagMessage.equals(txt)) return marker;
+                       } catch (Exception ex) {
+                               // Ignore
+                       }
+               }
+               return null;
+       }
+
+
+       private IFile getResource(MarkdownEditor markdownEditor) {
+               IPathEditorInput input = (IPathEditorInput) getEditorInput();
+               IPath path = input.getPath();           
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               IWorkspaceRoot root = workspace.getRoot();
+               IFile[] files = root.findFilesForLocation(path);
+               if (files.length != 1) return null;
+               IFile docFile = files[0];               
+               return docFile;
+       }
+
+
+       /**
+        * @param doc
+        * @return
+        */
+       public static MarkdownEditor getEditor(IDocument doc) {
+               return doc2editor.get(doc);
+       }
+
+       private static final Map<IDocument, MarkdownEditor> doc2editor = new HashMap<IDocument, MarkdownEditor>();
+
+
+       /**
+        * @param region 
+        * 
+        */
+       public void updatePage(IRegion region) {
+//             if (!pageDirty) return;
+               updateTaskTags(region);
+               updateSectionFoldingAnnotations(region);
+       }
+       
+       
+       private static final Annotation[] ANNOTATION_ARRAY = new Annotation[0];
+
+       private static final Position[] POSITION_ARRAY = new Position[0];
+       
+       private boolean haveRunFolding = false;
+       private Map<Annotation, Position> oldAnnotations = new HashMap<Annotation, Position>(0);
+
+       /**
+        * @param region can be null
+        */
+       private void updateSectionFoldingAnnotations(IRegion region) {
+               if (!haveRunFolding) region = null; // Do the whole doc
+               if ( ! (getSourceViewer() instanceof ProjectionViewer)) return;
+               ProjectionViewer viewer = ((ProjectionViewer)getSourceViewer());
+               MarkdownPage mPage = getMarkdownPage();
+               List<Header> headers = mPage.getHeadings(null);
+               // this will hold the new annotations along
+               // with their corresponding positions
+               Map<Annotation, Position> annotations = new HashMap<Annotation, Position>();
+               IDocument doc = getDocument();
+               updateSectionFoldingAnnotations2(doc, headers, annotations, doc.getLength());
+               // Filter existing ones
+               Position[] newValues = annotations.values().toArray(POSITION_ARRAY);            
+               List<Annotation> deletedAnnotations = new ArrayList<Annotation>();
+               for(Entry<Annotation, Position> ae : oldAnnotations.entrySet()) {
+                       Position oldp = ae.getValue();
+                       boolean stillExists = false;
+                       for (Position newp : newValues) {
+                               if (oldp.equals(newp)) {
+                                       annotations.remove(newp);
+                                       stillExists = true;
+                                       break;
+                               }
+                       }
+                       if (!stillExists && intersectsRegion(oldp, region)) {
+                               deletedAnnotations.add(ae.getKey());
+                       }
+               }
+               // Filter out-of-region ones
+               for(Annotation a : annotations.keySet().toArray(ANNOTATION_ARRAY)) {
+                       Position p = annotations.get(a);
+                       if (!intersectsRegion(p , region)) annotations.remove(a);
+               }
+               // Adjust the page
+           ProjectionAnnotationModel annotationModel = viewer.getProjectionAnnotationModel();
+           if (annotationModel==null) return;
+               annotationModel.modifyAnnotations(deletedAnnotations.toArray(ANNOTATION_ARRAY), annotations, null);
+               // Remember old values
+               oldAnnotations.putAll(annotations);
+               for (Annotation a : deletedAnnotations) {
+                       oldAnnotations.remove(a);       
+               }               
+               haveRunFolding = true;
+       }
+
+
+       /**
+        * @param p
+        * @param region
+        * @return true if p overlaps with region, or if region is null
+        */
+       private boolean intersectsRegion(Position p, IRegion region) {
+               if (region==null) return true;
+               if (p.offset > region.getOffset()+region.getLength()) return false;
+               if (p.offset+p.length < region.getOffset()) return false;
+               return true;
+       }
+
+
+       /**
+        * Calculate where to fold, sticking the info into newAnnotations
+        * @param doc 
+        * @param headers
+        * @param newAnnotations
+        * @param endParent
+        */
+       private void updateSectionFoldingAnnotations2(IDocument doc, List<Header> headers,
+                       Map<Annotation, Position> newAnnotations, int endParent) {
+               for (int i=0; i<headers.size(); i++) {
+                       Header header = headers.get(i);
+                       ProjectionAnnotation annotation = new ProjectionAnnotation();
+                       try {
+                               int line = header.getLineNumber();
+                               int start = doc.getLineOffset(line);
+                               int end = (i==headers.size()-1)? endParent
+                                               : doc.getLineOffset(headers.get(i+1).getLineNumber());
+                               Position position = new Position(start, end-start);
+                               newAnnotations.put(annotation, position);
+                               // Recurse
+                               List<Header> subHeaders = header.getSubHeaders();
+                               if (subHeaders.size() > 0) {
+                                       updateSectionFoldingAnnotations2(doc, subHeaders, newAnnotations, end);
+                               }
+                       } catch (Exception ex) {
+                               System.out.println(ex);
+                       }                       
+               }               
+       }
+
+
+}
+
+
+
+/*
+
+  <?xml version="1.0" encoding="UTF-8" ?> 
+- <templates>
+  <template name="updateSWT" description="Performs an update to an SWT control in the SWT thread" context="java" enabled="true">${control}.getDisplay().syncExec(new Runnable() { public void run() { ${control}.${cursor} } });</template> 
+  <template name="findView" description="Find a workbench view by ID" context="java" enabled="true" deleted="false">${viewType} ${view} = null; IWorkbenchWindow ${window} = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (${window} != null) { IWorkbenchPage ${activePage} = ${window}.getActivePage(); if (${activePage} != null) ${view} = (${viewType}) ${activePage}.findView("${viewID}"); } if (${view} != null) { ${cursor}//${todo}: Add operations for opened view }</template> 
+  <template name="getActiveEditor" description="Retrieves the currently active editor in the active page" context="java" enabled="true" deleted="false">IEditorPart ${editor} = null; IWorkbenchWindow ${window} = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (${window} != null) { IWorkbenchPage ${activePage} = ${window}.getActivePage(); if (${activePage} != null) ${editor} = ${activePage}.getActiveEditor(); } if (${editor} != null) { ${cursor}//${todo}: Add operations for active editor }</template>
+   IEditorPart editor = null; 
+               IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 
+               if (window != null) { 
+                       IWorkbenchPage activePage = window.getActivePage(); 
+                       if (activePage != null) editor = activePage.getActiveEditor(); 
+               } 
+               if (editor != null) { 
+                       // todo: Add operations for active editor                       
+               }
+               
+  <template name="openDialog" description="Creates and opens a JFace dialog" context="java" enabled="true" deleted="false">${dialogType} ${dialog} = new ${dialogType}(${cursor}); ${dialog}.create(); //${todo}: Complete dialog creation if (${dialog}.open() == Dialog.OK) { //${todo}: Perform actions on success };</template> 
+  <template name="scanExtensionRegistry" description="Scans the extension registry for extensions of a given extension point" context="java" enabled="true" deleted="false">IExtensionRegistry ${registry} = Platform.getExtensionRegistry(); IExtensionPoint ${point} = ${registry}.getExtensionPoint(${pluginId}, ${expointId}); IExtension[] ${extensions} = ${point}.getExtensions(); for (int ${index} = 0; ${index} < ${extensions}.length; ${index}++) { IConfigurationElement[] ${elements} = ${extensions}[${index}].getConfigurationElements(); for (int ${index2} = 0; ${index2} < ${elements}.length; ${index2}++) { IConfigurationElement ${element} = ${elements}[${index2}]; String ${attValue} = ${element}.getAttribute(${attName}); ${cursor}//${todo}: Implement processing for configuration element } }</template> 
+  <template name="showView" description="finds a workbench view by ID and shows it" context="java" enabled="true" deleted="false">${viewType} ${view} = null; IWorkbenchWindow ${window} = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (${window} != null) { IWorkbenchPage ${activePage} = ${window}.getActivePage(); if (${activePage} != null) try { ${view} = (${viewType}) ${activePage}.showView("${viewID}"); } catch (${Exception} e) { // ${todo}: handle exception } } if (${view} != null) { ${cursor} }</template> 
+  <template name="signalError" description="Shows an error message in the editors status line" context="java" enabled="true" deleted="false">IEditorActionBarContributor ${contributor} = ${editor}.getEditorSite().getActionBarContributor(); if (${contributor} instanceof EditorActionBarContributor) { IActionBars ${actionBars} = ((EditorActionBarContributor) ${contributor}).getActionBars(); if (${actionBars} != null) { IStatusLineManager ${manager} = ${actionBars}.getStatusLineManager(); if (${manager} != null) ${manager}.setErrorMessage(msg); } }</template> 
+  </templates>
+
+*/
\ No newline at end of file
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/PrintAction.java b/bundles/winterwell.markdown/src/winterwell/markdown/editors/PrintAction.java
new file mode 100644 (file)
index 0000000..8d089f1
--- /dev/null
@@ -0,0 +1,75 @@
+//package winterwell.markdown.editors;
+//
+//import java.util.List;
+//
+//import net.sf.paperclips.PaperClips;
+//import net.sf.paperclips.Print;
+//import net.sf.paperclips.PrintJob;
+//import net.sf.paperclips.TextPrint;
+//
+//import org.eclipse.core.commands.ExecutionEvent;
+//import org.eclipse.core.commands.ExecutionException;
+//import org.eclipse.core.commands.IHandler;
+//import org.eclipse.core.commands.IHandlerListener;
+//import org.eclipse.jface.action.Action;
+//import org.eclipse.jface.text.BadLocationException;
+//import org.eclipse.jface.text.DocumentEvent;
+//import org.eclipse.jface.text.IDocument;
+//import org.eclipse.jface.text.IDocumentListener;
+//import org.eclipse.jface.text.IRegion;
+//import org.eclipse.jface.text.ITextSelection;
+//import org.eclipse.jface.text.Region;
+//import org.eclipse.jface.text.source.ISourceViewer;
+//import org.eclipse.jface.viewers.ISelection;
+//import org.eclipse.swt.SWT;
+//import org.eclipse.swt.printing.PrintDialog;
+//import org.eclipse.swt.printing.PrinterData;
+//import org.eclipse.swt.widgets.Display;
+//import org.eclipse.ui.IEditorPart;
+//import org.eclipse.ui.IPropertyListener;
+//import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+//
+//import winterwell.markdown.pagemodel.MarkdownFormatter;
+//import winterwell.markdown.pagemodel.MarkdownPage;
+//import winterwell.markdown.pagemodel.MarkdownPage.KLineType;
+//import winterwell.utils.containers.Pair;
+//import winterwell.utils.containers.Range;
+//
+///**
+// * Print the file
+// * 
+// *
+// * @author daniel
+// */
+//public class PrintAction extends Action {
+//
+//     public PrintAction() {
+//             super("Print...");
+//     }
+//     
+//     @Override
+//     public void run() {
+//             try {
+//                     MarkdownEditor ed = (MarkdownEditor) ActionBarContributor.getActiveEditor();
+//                     if (ed == null) return; // The active editor is not a markdown editor.
+//                     PrintDialog dialog = new PrintDialog(Display.getDefault().getActiveShell(), SWT.NONE);
+//                     PrinterData printerData = dialog.open ();
+//                     if (printerData == null) return;
+//                     Print doc = new TextPrint(ed.getText());
+//                     PrintJob job = new PrintJob(ed.getTitle(), doc );
+//                     PaperClips.print(job, printerData);
+//                     // Done
+//             } catch (Exception ex) {
+//                     System.out.println(ex);
+//             }
+//     }
+//
+//
+//
+//     public void dispose() {
+//             // Ignore               
+//     }
+//
+//     
+//}
+// 
\ No newline at end of file
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif b/bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif
new file mode 100644 (file)
index 0000000..a2d80a9
Binary files /dev/null and b/bundles/winterwell.markdown/src/winterwell/markdown/editors/collapseall.gif differ
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif b/bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif
new file mode 100644 (file)
index 0000000..870934b
Binary files /dev/null and b/bundles/winterwell.markdown/src/winterwell/markdown/editors/synced.gif differ
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatter.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatter.java
new file mode 100644 (file)
index 0000000..4c38f19
--- /dev/null
@@ -0,0 +1,351 @@
+
+package winterwell.markdown.pagemodel;
+
+import java.util.List;
+
+import winterwell.utils.StrUtils;
+
+/**
+ * Formats a string that is compatible with the Markdown syntax.
+ * Strings must not include headers.
+ * 
+ * @author Howard Abrams
+ */
+public class MarkdownFormatter
+{
+  // Expect everyone to simply use the public static methods...
+  private MarkdownFormatter ()
+  {
+  }
+  
+  /**
+   * Formats a collection of lines to a particular width and honors typical
+   * Markdown syntax and formatting. 
+   * 
+   * The method <i>assumes</i> that if the first line ends with a line
+   * termination character, all the other lines will as well.
+   * 
+   * @param lines     A list of strings that should be formatted and wrapped.
+   * @param lineWidth The width of the page
+   * @return          A string containing each 
+   */
+  public static String format (List<String> lines, int lineWidth)
+  {
+    if (lines == null)
+      return null;      // Should we return an empty string?
+    
+    final String lineEndings;
+    if ( lines.get(0).endsWith ("\r\n") )
+      lineEndings = "\r\n";
+    else if ( lines.get(0).endsWith ("\r") )
+      lineEndings = "\r";
+    else
+      lineEndings = StrUtils.LINEEND;
+    
+    final StringBuilder buf = new StringBuilder();
+    for (String line : lines) {
+      buf.append (line);
+      buf.append (' ');     // We can add extra spaces with impunity, and this
+                            // makes sure our lines don't run together.
+    }
+    return format ( buf.toString(), lineWidth, lineEndings );
+  }
+  
+
+  /**
+   * Formats a string of text. The formatting does line wrapping at the 
+   * <code>lineWidth</code> boundary, but it also honors the formatting
+   * of initial paragraph lines, allowing indentation of the entire
+   * paragraph.
+   * 
+   * @param text       The line of text to format
+   * @param lineWidth  The width of the lines
+   * @return           A string containing the formatted text.
+   */
+  public static String format ( final String text, final int lineWidth)
+  {
+    return format(text, lineWidth, StrUtils.LINEEND);
+  }
+  
+  /**
+   * Formats a string of text. The formatting does line wrapping at the 
+   * <code>lineWidth</code> boundary, but it also honors the formatting
+   * of initial paragraph lines, allowing indentation of the entire
+   * paragraph.
+   * 
+   * @param text       The line of text to format
+   * @param lineWidth  The width of the lines
+   * @param lineEnding The line ending that overrides the default System value
+   * @return           A string containing the formatted text.
+   */
+  public static String format (final String text, final int lineWidth, final String lineEnding)
+  {
+    return new String( format(text.toCharArray (), lineWidth, lineEnding));
+  }
+  
+  /**
+   * The available cursor position states as it sits in the buffer.
+   */
+  private enum StatePosition { 
+    /** The beginning of a paragraph ... the start of the buffer */
+    BEGIN_FIRST_LINE, 
+    
+    /** The beginning of the next line, which may be completely ignored. */
+    BEGIN_OTHER_LINE, 
+    
+    /** The beginning of a new line that will not be ignored, but appended. */
+    BEGIN_NEW_LINE, 
+    
+    /** The middle of a line. */
+    MIDDLE_OF_LINE 
+  }
+
+  /**
+   * The method that does the work of formatting a string of text. The text,
+   * however, is a character array, which is more efficient to work with.
+   * 
+   * TODO: Should we make the format(char[]) method public?
+   * 
+   * @param text       The line of text to format
+   * @param lineWidth  The width of the lines
+   * @param lineEnding The line ending that overrides the default System value
+   * @return           A string containing the formatted text.
+   */
+  static char[] format ( final char[] text, final int lineWidth, final String lineEnding )
+  {
+    final StringBuilder word   = new StringBuilder();
+    final StringBuilder indent = new StringBuilder();
+    final StringBuilder buffer = new StringBuilder(text.length + 10);
+    
+    StatePosition state = StatePosition.BEGIN_FIRST_LINE;
+    int lineLength = 0;
+
+    // There are times when we will run across a character(s) that will 
+    // cause us to stop doing word wrap until we get to the 
+    // "end of non-wordwrap" character(s).
+    //
+    // If this string is set to null, it tells us to "do" word-wrapping.
+    char endWordwrap1 = 0;
+    char endWordwrap2 = 0;
+    
+    // We loop one character past the end of the loop, and when we get to
+    // this position, we assign 'c' to be 0 ... as a marker for the end of
+    // the string...
+    
+    for (int i = 0; i <= text.length; i++)
+    {
+      final char c;
+      if (i < text.length)
+        c = text[i];
+      else
+        c = 0;
+      
+      final char nextChar;
+      if (i+1 < text.length)
+        nextChar = text[i+1];
+      else
+        nextChar = 0;
+      
+      // Are we actually word-wrapping?
+      if (endWordwrap1 != 0) {
+        // Did we get the ending sequence of the non-word-wrap?  
+        if ( ( endWordwrap2 == 0 && c == endWordwrap1 ) || 
+             ( c == endWordwrap1 && nextChar == endWordwrap2 ) )
+          endWordwrap1 = 0;
+        buffer.append (c);
+        lineLength++;
+        
+        if (endWordwrap1 == 0 && endWordwrap2 != 0) {
+          buffer.append (nextChar);
+          lineLength++;
+          i++;
+        }
+        continue;
+      }
+
+      // Check to see if we got one of our special non-word-wrapping
+      // character sequences ...
+      
+      if ( c == '['  ) {                           //    [Hyperlink]
+        endWordwrap1 = ']';
+      }
+      else if ( c == '*' && nextChar == '*' ) {    //    **Bold**
+        endWordwrap1 = '*';
+        endWordwrap2 = '*';
+      }                                            //    *Italics*
+      else if ( c == '*' && state == StatePosition.MIDDLE_OF_LINE ) {
+        endWordwrap1 = '*';
+      }
+      else if ( c == '`' ) {                       //    `code`
+        endWordwrap1 = '`';
+      }
+      else if ( c == '(' && nextChar == '(' ) {    //    ((Footnote))
+        endWordwrap1 = ')';
+        endWordwrap2 = ')';
+      }
+      else if ( c == '!' && nextChar == '[' ) {    //    ![Image]
+        endWordwrap1 = ')';
+      }
+      
+      // We are no longer doing word-wrapping, so tidy the situation up...
+      if (endWordwrap1 != 0) {
+        if (word.length() > 0)
+          lineLength = addWordToBuffer (lineWidth, lineEnding, word, indent, buffer, lineLength);
+        else if (buffer.length() > 0 && buffer.charAt (buffer.length()-1) != ']' )
+          buffer.append(' ');
+        // We are adding an extra space for most situations, unless we get a
+        // [link][ref] where we want them to be together without a space.
+        
+        buffer.append (c);
+        lineLength++;
+        continue;
+      }
+
+      // Normal word-wrapping processing continues ...
+      
+      if (state == StatePosition.BEGIN_FIRST_LINE)
+      {
+        if ( c == '\n' || c == '\r' ) { // Keep, but ignore initial line feeds
+          buffer.append (c);
+          lineLength = 0;
+          continue;
+        }
+
+        if (Character.isWhitespace (c))
+          indent.append (c);
+        else if ( (c == '*' || c == '-' || c == '.' ) &&
+                Character.isWhitespace (nextChar) )
+          indent.append (' ');
+        else if ( Character.isDigit (c) && nextChar == '.' &&
+                Character.isWhitespace (text[i+2]))
+          indent.append (' ');
+        else if ( c == '>' )
+          indent.append ('>');
+        else
+          state = StatePosition.MIDDLE_OF_LINE;
+
+        // If we are still in the initial state, then put 'er in...
+        if (state == StatePosition.BEGIN_FIRST_LINE) {
+          buffer.append (c);
+          lineLength++;
+        }
+      }
+      
+      // While it would be more accurate to explicitely state the range of
+      // possibilities, with something like:
+      //    EnumSet.range (StatePosition.BEGIN_OTHER_LINE, StatePosition.MIDDLE_OF_LINE ).contains (state)
+      // We know that what is left is just the BEGIN_FIRST_LINE ...
+      
+      if ( state != StatePosition.BEGIN_FIRST_LINE )
+      {
+        // If not the middle of the line, then it must be at the first of a line
+        // Either   BEGIN_OTHER_LINE  or  BEGIN_NEW_LINE
+        if (state != StatePosition.MIDDLE_OF_LINE)
+        {
+          if ( Character.isWhitespace(c) || c == '>' || c == '.' )
+            word.append (c);
+          else if ( ( ( c == '*' || c == '-' ) && Character.isWhitespace (nextChar) ) ||
+                    ( Character.isDigit(c) && nextChar == '.' && Character.isWhitespace( text[i+2] ) ) ) {
+            word.append (c);
+            state = StatePosition.BEGIN_NEW_LINE;
+          }
+          else {
+            if (state == StatePosition.BEGIN_NEW_LINE) {
+              buffer.append (word);
+              lineLength = word.substring ( word.indexOf("\n")+1 ).length();
+            }
+            word.setLength (0);
+            state = StatePosition.MIDDLE_OF_LINE;
+          }
+        }
+        
+        if (state == StatePosition.MIDDLE_OF_LINE)
+        {
+          // Are we at the end of a word? Then we need to calculate whether
+          // to wrap the line or not.
+          //
+          // This condition does double duty, in that is also serves to
+          // ignore multiple spaces and special characters that may be at
+          // the beginning of the line.
+          if ( Character.isWhitespace(c) || c == 0 ) 
+          {
+            if ( word.length() > 0) {
+              lineLength = addWordToBuffer (lineWidth, lineEnding, word, indent, buffer, lineLength);
+            }
+            // Do we we two spaces at the end of the line? Honor this...
+            else if ( c == ' ' && ( nextChar == '\r' || nextChar == '\n' ) &&
+                    state != StatePosition.BEGIN_OTHER_LINE ) {
+              buffer.append ("  ");
+              buffer.append (lineEnding);
+              lineLength = 0;
+            }
+
+            if ( c == '\r' || c == '\n' ) {
+              state = StatePosition.BEGIN_OTHER_LINE;
+              word.append(c);
+            }
+            
+            // Linefeeds are completely ignored and just treated as whitespace,
+            // unless, of course, there are two of 'em... and of course, end of
+            // lines are simply evil on Windows machines.
+
+            if ( (c == '\n' && nextChar == '\n') ||    // Unix-style line-ends
+                    ( c == '\r' && nextChar == '\n' &&    // Windows-style line-ends
+                            text[i+2] == '\r' && text[i+3] == '\n' )  ) 
+            {
+              state = StatePosition.BEGIN_FIRST_LINE;
+              word.setLength(0);
+              indent.setLength (0);
+              lineLength = 0;
+
+              if (c == '\r') { // If we are dealing with Windows-style line-ends,
+                i++;           // we need to skip past the next character...
+                buffer.append("\r\n");
+              } else
+                buffer.append(c);
+            }
+
+          } else {
+            word.append (c);
+            state = StatePosition.MIDDLE_OF_LINE;
+          }
+        }
+      }
+    }
+    
+    return buffer.toString().toCharArray();
+  }
+
+  /**
+   * Adds a word to the buffer, performing word wrap if necessary.
+   * @param lineWidth    The current width of the line
+   * @param lineEnding   The line ending to append, if necessary
+   * @param word         The word to append
+   * @param indent       The indentation string to insert, if necesary
+   * @param buffer       The buffer to perform all this stuff to
+   * @param lineLength   The current length of the current line
+   * @return             The new length of the current line
+   */
+  private static int addWordToBuffer (final int lineWidth, final String lineEnding, 
+                                      final StringBuilder word, 
+                                      final StringBuilder indent, 
+                                      final StringBuilder buffer, int lineLength)
+  {
+    if ( word.length() + lineLength + 1 > lineWidth )
+    {
+      buffer.append (lineEnding);
+      buffer.append (indent);
+      buffer.append (word);
+
+      lineLength = indent.length() + word.length();
+    }
+    else {
+      if ( lineLength > indent.length() )
+        buffer.append (' ');
+      buffer.append (word);
+      lineLength += word.length() + 1;
+    }
+    word.setLength (0);
+    return lineLength;
+  }
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatterTest.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownFormatterTest.java
new file mode 100644 (file)
index 0000000..4e4dd75
--- /dev/null
@@ -0,0 +1,537 @@
+//package winterwell.markdown.pagemodel;
+//
+//import java.util.Arrays;
+//import java.util.List;
+//
+//import junit.framework.TestCase;
+//// import winterwell.utils.MarkdownFormatter;
+//
+///**
+// * Test methods in the StringMethods utility class.
+// */
+//public class MarkdownFormatterTest extends TestCase
+//{
+//  /**
+//   * The local line-end string. \n on unix, \r\n on windows.
+//   * I really want to run through all of these tests with both styles.
+//   * We'll come back to that sort of a trick.
+//   */
+//  // public String LINEEND = System.getProperty("line.separator");
+//  public static final String LINEEND = "\r\n";
+//
+//  /**
+//   * Test default word wrapping of a long line of normal text.
+//   */
+//  public void testFormatStringInt ()
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to the aid of " +
+//      "their coopertino lattes, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to the aid of" + LINEEND + // This line is 30 characters
+//      "their coopertino lattes, and" + LINEEND +
+//      "begin the process of singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 30, LINEEND));
+//  }
+//
+//  /**
+//   * If the initial part of the line contains some spaces, we use that as
+//   * the "indentation" for every other line.
+//   * @throws Exception
+//   */
+//  public void testIndentOfSpaces () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "    Now is the time for all good " +
+//      "chickens to come to the aid of " +
+//      "their coopertino lattes, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      "    Now is the time for all good" + LINEEND +
+//      "    chickens to come to the aid of" + LINEEND +
+//      "    their coopertino lattes, and" + LINEEND +
+//      "    begin the process of singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * Can we maintain the format of text that is already formatted?
+//   * @throws Exception
+//   */
+//  public void testAlreadyFormatted () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "    Now is the time for all good" + LINEEND +
+//      "    chickens to come to the aid of" + LINEEND +
+//      "    their coopertino lattes, and" + LINEEND +
+//      "    begin the process of singing.";
+//    assertEquals (LONG_LINE, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//
+//  /**
+//   * Formatting a single line is all fine and dandy, but what about
+//   * formatting multiple paragraphs, that is, blank lines.
+//   * @throws Exception
+//   */
+//  public void testMultipleParagraphs () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "    Now is the time for all good " +
+//      "chickens to come to their aid." + LINEEND + LINEEND +
+//      "  And drink coopertino lattes, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      "    Now is the time for all good" + LINEEND +
+//      "    chickens to come to their aid." + LINEEND + LINEEND +
+//      "  And drink coopertino lattes," + LINEEND +
+//      "  and begin the process of" + LINEEND + "  singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * What if the section we are formatting, begins with line feeds?
+//   * Do we keep 'em? Might as well. :-)
+//   * @throws Exception
+//   */
+//  public void testInitialLineFeeds () throws Exception
+//  {
+//    final String LONG_LINE = LINEEND + LINEEND + LINEEND +
+//      "    Now is the time for all good" + LINEEND +
+//      "    chickens to come to the aid of" + LINEEND +
+//      "    their coopertino lattes, and" + LINEEND +
+//      "    begin the process of singing.";
+//    assertEquals (LONG_LINE, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * We need to be able to format bulleted lists appropriately.
+//   * @throws Exception
+//   */
+//  public void testSingleBulletedList () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "  * Now is the time for all good " +
+//      "chickens to come to the aid of " + LINEEND +
+//      "their coopertino lattes, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      "  * Now is the time for all good" + LINEEND +
+//      "    chickens to come to the aid of" + LINEEND +
+//      "    their coopertino lattes, and" + LINEEND +
+//      "    begin the process of singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * What about dealing with multiple bulleted lists.
+//   * @throws Exception
+//   */
+//  public void testMultipleBulletedList () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " * Cluck" + LINEEND + 
+//      " * Sing" + LINEEND + 
+//      " * Drink coopertino lattes.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " * Cluck" + LINEEND + 
+//      " * Sing" + LINEEND + 
+//      " * Drink coopertino lattes.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * What about dealing with multiple bulleted lists.
+//   * @throws Exception
+//   */
+//  public void testMultipleDashedBulletedList () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " - Cluck" + LINEEND + 
+//      " - Sing" + LINEEND + 
+//      " - Drink coopertino lattes.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " - Cluck" + LINEEND + 
+//      " - Sing" + LINEEND + 
+//      " - Drink coopertino lattes.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * Tests whether we can have nested bulleted lists.
+//   * @throws Exception
+//   */
+//  public void testSubindentedBulletedLists () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " * Cluck, cluck, cluck till their little feets hurt:" + LINEEND +
+//      "   * Do it again and again and again and again." + LINEEND + 
+//      "   * And maybe again and again if their mommy's say so." + LINEEND +
+//      "     * We can indent really, really, deep with three levels of subitems." + LINEEND +
+//      "     * But we aren't sure if this is getting ridiculous or just plain expected." + LINEEND +
+//      " * Sing, sing, sing till their little voices break:" + LINEEND +
+//      "   * Do it again and again and again and again." + LINEEND + 
+//      "   * And maybe again and again if their mommy's say so." + LINEEND +
+//      " * Drink coopertino lattes.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " * Cluck, cluck, cluck till their" + LINEEND + 
+//      "   little feets hurt:" + LINEEND +
+//      "   * Do it again and again and" + LINEEND +
+//      "     again and again." + LINEEND + 
+//      "   * And maybe again and again if" + LINEEND + 
+//      "     their mommy's say so." + LINEEND +
+//      "     * We can indent really," + LINEEND +
+//      "       really, deep with three" + LINEEND +
+//      "       levels of subitems." + LINEEND +
+//      "     * But we aren't sure if this" + LINEEND +
+//      "       is getting ridiculous or " + LINEEND + 
+//      "       just plain expected." + LINEEND +
+//      " * Sing, sing, sing till their" + LINEEND +
+//      "   little voices break:" + LINEEND +
+//      "   * Do it again and again and" + LINEEND +
+//      "     again and again." + LINEEND + 
+//      "   * And maybe again and again if" + LINEEND + 
+//      "     their mommy's say so." + LINEEND +
+//      " * Drink coopertino lattes.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * Tests whether we can have nested bulleted lists.
+//   * @throws Exception
+//   */
+//  public void testSubindentedBulletedLists2 () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " * Cluck, cluck, cluck till their little feets hurt:" + LINEEND + LINEEND +
+//      "   * Do it again and again and again and again." + LINEEND +  LINEEND +
+//      "   * And maybe again and again if their mommy's say so." + LINEEND + LINEEND +
+//      "     * We can indent really, really, deep with three levels of subitems." + LINEEND + LINEEND +
+//      "     * But we aren't sure if this is getting ridiculous or just plain expected." + LINEEND + LINEEND +
+//      " * Sing, sing, sing till their little voices break:" + LINEEND + LINEEND +
+//      "   * Do it again and again and again and again." + LINEEND +  LINEEND +
+//      "   * And maybe again and again if their mommy's say so." + LINEEND + LINEEND +
+//      " * Drink coopertino lattes.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " * Cluck, cluck, cluck till their" + LINEEND + 
+//      "   little feets hurt:" + LINEEND + LINEEND +
+//      "   * Do it again and again and" + LINEEND +
+//      "     again and again." + LINEEND +  LINEEND +
+//      "   * And maybe again and again if" + LINEEND + 
+//      "     their mommy's say so." + LINEEND + LINEEND +
+//      "     * We can indent really," + LINEEND +
+//      "       really, deep with three" + LINEEND +
+//      "       levels of subitems." + LINEEND + LINEEND +
+//      "     * But we aren't sure if this" + LINEEND +
+//      "       is getting ridiculous or" + LINEEND + 
+//      "       just plain expected." + LINEEND + LINEEND +
+//      " * Sing, sing, sing till their" + LINEEND +
+//      "   little voices break:" + LINEEND + LINEEND +
+//      "   * Do it again and again and" + LINEEND +
+//      "     again and again." + LINEEND +  LINEEND +
+//      "   * And maybe again and again if" + LINEEND + 
+//      "     their mommy's say so." + LINEEND + LINEEND +
+//      " * Drink coopertino lattes.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * What about dealing with a numeric list?
+//   * @throws Exception
+//   */
+//  public void testSingleNumericList () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      " 2. Now is the time for all good " +
+//      "chickens to come to the aid of " +
+//      "their coopertino lattes, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      " 2. Now is the time for all good" + LINEEND +
+//      "    chickens to come to the aid of" + LINEEND +
+//      "    their coopertino lattes, and" + LINEEND +
+//      "    begin the process of singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//
+//  /**
+//   * What about dealing with multiple bulleted lists.
+//   * @throws Exception
+//   */
+//  public void testMultipleNumericList () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " 1. Cluck" + LINEEND + 
+//      " 2. Sing" + LINEEND + 
+//      " 3. Drink coopertino lattes.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to:" + LINEEND + LINEEND +
+//      " 1. Cluck" + LINEEND + 
+//      " 2. Sing" + LINEEND + 
+//      " 3. Drink coopertino lattes.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * What about dealing with sections that should not be word wrapped, like
+//   * the text between brackets (since they are hyperlinks).
+//   * @throws Exception
+//   */
+//  public void testNoWordWrapBracket() throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to [the spurious and costly][3] " +
+//      "aid of their coopertino cups, " +
+//      "and begin sing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to [the spurious and costly][3]" + LINEEND +
+//      "aid of their coopertino cups, and" + LINEEND +
+//      "begin sing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  /**
+//   * What about dealing with bracketed sections with no extra white space
+//   * @throws Exception
+//   */
+//  public void testNoWordWrapBracket2() throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to[the spurious and costly][3] " +
+//      "aid of their coopertino cups, " +
+//      "and begin sing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to[the spurious and costly][3]" + LINEEND +
+//      "aid of their coopertino cups, and" + LINEEND +
+//      "begin sing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//  
+//  /**
+//   * What about dealing with bold sections that should not be word wrapped.
+//   * @throws Exception
+//   */
+//  public void testNoWordWrapDoubleAsterix() throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to **the spurious and costly** " +
+//      "aid of their coopertino cups, " +
+//      "and begin sing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to **the spurious and costly**" + LINEEND +
+//      "aid of their coopertino cups, and" + LINEEND +
+//      "begin sing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//
+//  /**
+//   * What about dealing with italic sections that should not be word wrapped
+//   * @throws Exception
+//   */
+//  public void testNoWordWrapSingleAsterix() throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to *the spurious and costly* " +
+//      "aid of their coopertino cups, " +
+//      "and begin sing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to *the spurious and costly*" + LINEEND +
+//      "aid of their coopertino cups, and" + LINEEND +
+//      "begin sing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//
+//  /**
+//   * What about dealing with sections that are code should not be broken.
+//   * @throws Exception
+//   */
+//  public void testNoWordWrapCode() throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to `the spurious and costly` " +
+//      "aid of their coopertino cups, " +
+//      "and begin sing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to `the spurious and costly`" + LINEEND +
+//      "aid of their coopertino cups, and" + LINEEND +
+//      "begin sing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//
+//  /**
+//   * What about dealing with double parenthesis sections ... these shouldn't
+//   * be broken up.
+//   * @throws Exception
+//   */
+//  public void testNoWordWrapDoubleParens() throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come to ((the spurious and costly)) " +
+//      "aid of their coopertino cups, " +
+//      "and begin sing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to ((the spurious and costly))" + LINEEND +
+//      "aid of their coopertino cups, and" + LINEEND +
+//      "begin sing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 34, LINEEND));
+//  }
+//
+//
+//  /**
+//   * If a line, embedded in a paragraph has two spaces at the end of the line,
+//   * these need to be honored and maintained.
+//   * @throws Exception
+//   */
+//  public void testLineBreaksHonored () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      "Now is the time for all good " +
+//      "chickens to come    " + LINEEND + 
+//      "to the aid of their coopertino lattes, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come  " + LINEEND +
+//      "to the aid of their coopertino" + LINEEND + 
+//      "lattes, and begin the process of" + LINEEND +
+//      "singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 33, LINEEND));
+//  }
+//  
+//  /**
+//   * A "blockquote" in Markdown can accept > characters at the beginning
+//   * of all of the lines. 
+//   * @throws Exception
+//   */
+//  public void testBlockQuoteSimple () throws Exception
+//  {
+//    final String LONG_LINE = 
+//      " > Now is the time for all good " +
+//      "chickens to come to the aid of " +
+//      "their coopertino <lattes>, and " +
+//      "begin the process of singing.";
+//    final String EXPECTED = 
+//      " > Now is the time for all good" + LINEEND +
+//      " > chickens to come to the aid of" + LINEEND +
+//      " > their coopertino <lattes>, and" + LINEEND +
+//      " > begin the process of singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (LONG_LINE, 33, LINEEND));
+//  }
+//
+//  /**
+//   * A "blockquote" in Markdown can accept > characters at the beginning
+//   * of all of the lines. Can we accept a version that is already formatted?
+//   * @throws Exception
+//   */
+//  public void testBlockQuoteAlreadyFormatted () throws Exception
+//  {
+//    final String EXPECTED = 
+//      " > Now is the time for all good" + LINEEND +
+//      " > chickens to come to the aid of" + LINEEND +
+//      " > their coopertino <lattes>, and" + LINEEND +
+//      " > begin the process of singing.";
+//    assertEquals (EXPECTED, MarkdownFormatter.format (EXPECTED, 33, LINEEND));
+//  }
+//  
+//  /**
+//   * Tests that the "list" interface works if each string does not have
+//   * carriage returns.
+//   * @throws Exception
+//   */
+//  public void testListWithoutLinefeeds () throws Exception
+//  {
+//    final String lineend = System.getProperty("line.separator");
+//
+//    final List<String> lines = Arrays.asList ( new String[] { 
+//      "Now is the time for all good",
+//      "chickens to come to the aid of",
+//      "their coopertino lattes, and",
+//      "begin the process of singing."
+//    } );
+//    final String EXPECTED = 
+//      "Now is the time for all good" + lineend +
+//      "chickens to come to the aid of" + lineend + // This line is 30 characters
+//      "their coopertino lattes, and" + lineend +
+//      "begin the process of singing.";
+//    
+//    final String RESULTS = MarkdownFormatter.format (lines, 30);
+//    assertEquals (EXPECTED, RESULTS);
+//  }
+//
+//  /**
+//   * Tests that the "list" interface works if each string has carriage returns.
+//   * @throws Exception
+//   */
+//  public void testListWithLinefeeds () throws Exception
+//  {
+//    final List<String> lines = Arrays.asList ( new String[] { 
+//      "Now is the time for all good chickens to come" + LINEEND,
+//      "to the aid of" + LINEEND,
+//      "their coopertino lattes, and" + LINEEND,
+//      "begin the process of singing."
+//    } );
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to the aid of" + LINEEND + // This line is 30 characters
+//      "their coopertino lattes, and" + LINEEND +
+//      "begin the process of singing.";
+//    
+//    final String RESULTS = MarkdownFormatter.format (lines, 30);
+//    assertEquals (EXPECTED, RESULTS);
+//  }
+//
+//  /**
+//   * Tests that we don't break up image tags.
+//   * @throws Exception
+//   */
+//  public void testImageTags () throws Exception
+//  {
+//    final List<String> lines = Arrays.asList ( new String[] { 
+//      "Now is the time for all good chickens to come " +
+//      "to the aid ![Some text description](http://www.google.com/images/logo.gif)" + LINEEND,
+//      "their coopertino lattes, and" + LINEEND,
+//      "begin the process of singing."
+//    } );
+//    final String EXPECTED = 
+//      "Now is the time for all good" + LINEEND +
+//      "chickens to come to the aid " + // This line is 30 characters
+//      "![Some text description](http://www.google.com/images/logo.gif)" + LINEEND +
+//      "their coopertino lattes, and" + LINEEND +
+//      "begin the process of singing.";
+//    
+//    final String RESULTS = MarkdownFormatter.format (lines, 30);
+//    assertEquals (EXPECTED, RESULTS);
+//  }
+//}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPage.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPage.java
new file mode 100644 (file)
index 0000000..a18a5de
--- /dev/null
@@ -0,0 +1,617 @@
+/**\r
+ * Copyright winterwell Mathematics Ltd.\r
+ * @author Daniel Winterstein\r
+ * 11 Jan 2007\r
+ */\r
+package winterwell.markdown.pagemodel;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+\r
+import winterwell.markdown.Activator;\r
+import winterwell.markdown.StringMethods;\r
+import winterwell.markdown.preferences.MarkdownPreferencePage;\r
+import winterwell.utils.FailureException;\r
+import winterwell.utils.Process;\r
+import winterwell.utils.StrUtils;\r
+import winterwell.utils.Utils;\r
+import winterwell.utils.io.FileUtils;\r
+\r
+import com.petebevin.markdown.MarkdownProcessor;\r
+\r
+/**\r
+ * Understands Markdown syntax.\r
+ * \r
+ * @author Daniel Winterstein\r
+ */\r
+public class MarkdownPage {\r
+\r
+       /**\r
+        * Strip leading and trailing #s and whitespace\r
+        * \r
+        * @param line\r
+        * @return cleaned up line\r
+        */\r
+       private String cleanHeader(String line) {\r
+               for (int j = 0; j < line.length(); j++) {\r
+                       char c = line.charAt(j);\r
+                       if (c != '#' && !Character.isWhitespace(c)) {\r
+                               line = line.substring(j);\r
+                               break;\r
+                       }\r
+               }\r
+               for (int j = line.length() - 1; j > 0; j--) {\r
+                       char c = line.charAt(j);\r
+                       if (c != '#' && !Character.isWhitespace(c)) {\r
+                               line = line.substring(0, j + 1);\r
+                               break;\r
+                       }\r
+               }\r
+               return line;\r
+       }\r
+\r
+       /**\r
+        * Represents information about a section header. E.g. ## Misc Warblings\r
+        * \r
+        * @author daniel\r
+        */\r
+       public class Header {\r
+               /**\r
+                * 1 = top-level (i.e. #), 2= 2nd-level (i.e. ##), etc.\r
+                */\r
+               final int level;\r
+               /**\r
+                * The text of the Header\r
+                */\r
+               final String heading;\r
+               /**\r
+                * Sub-sections, if any\r
+                */\r
+               final List<Header> subHeaders = new ArrayList<Header>();\r
+               /**\r
+                * The line on which this header occurs.\r
+                */\r
+               final int lineNumber;\r
+\r
+               public int getLineNumber() {\r
+                       return lineNumber;\r
+               }\r
+\r
+               /**\r
+                * \r
+                * @return the next section (at this depth if possible), null if none\r
+                */\r
+               public Header getNext() {\r
+                       if (parent == null) {\r
+                               int ti = level1Headers.indexOf(this);\r
+                               if (ti == -1 || ti == level1Headers.size() - 1)\r
+                                       return null;\r
+                               return level1Headers.get(ti + 1);\r
+                       }\r
+                       int i = parent.subHeaders.indexOf(this);\r
+                       assert i != -1 : this;\r
+                       if (i == parent.subHeaders.size() - 1)\r
+                               return parent.getNext();\r
+                       return parent.subHeaders.get(i + 1);\r
+               }\r
+               /**\r
+                * \r
+                * @return the next section (at this depth if possible), null if none\r
+                */\r
+               public Header getPrevious() {\r
+                       if (parent == null) {\r
+                               int ti = level1Headers.indexOf(this);\r
+                               if (ti == -1 || ti == 0)\r
+                                       return null;\r
+                               return level1Headers.get(ti - 1);\r
+                       }\r
+                       int i = parent.subHeaders.indexOf(this);\r
+                       assert i != -1 : this;\r
+                       if (i == 0)\r
+                               return parent.getPrevious();\r
+                       return parent.subHeaders.get(i - 1);\r
+               }\r
+               \r
+\r
+               /**\r
+                * The parent section. Can be null.\r
+                */\r
+               private Header parent;\r
+\r
+               /**\r
+                * Create a marker for a section Header\r
+                * \r
+                * @param level\r
+                *            1 = top-level (i.e. #), 2= 2nd-level (i.e. ##), etc.\r
+                * @param lineNumber\r
+                *            The line on which this header occurs\r
+                * @param heading\r
+                *            The text of the Header, trimmed of #s\r
+                * @param currentHeader\r
+                *            The previous Header. This is used to find the parent\r
+                *            section if there is one. Can be null.\r
+                */\r
+               Header(int level, int lineNumber, String heading, Header currentHeader) {\r
+                       this.lineNumber = lineNumber;\r
+                       this.level = level;\r
+                       this.heading = cleanHeader(heading);\r
+                       // Heading Tree\r
+                       setParent(currentHeader);\r
+               }\r
+\r
+               private void setParent(Header currentHeader) {\r
+                       if (currentHeader == null) {\r
+                               parent = null;\r
+                               return;\r
+                       }\r
+                       if (currentHeader.level < level) {\r
+                               parent = currentHeader;\r
+                               parent.subHeaders.add(this);\r
+                               return;\r
+                       }\r
+                       setParent(currentHeader.parent);\r
+               }\r
+\r
+               public Header getParent() {\r
+                       return parent;\r
+               }\r
+\r
+               /**\r
+                * Sub-sections. May be zero-length, never null.\r
+                */\r
+               public List<Header> getSubHeaders() {\r
+                       return subHeaders;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       return heading;\r
+               }\r
+\r
+               public int getLevel() {\r
+                       return level;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * The raw text, broken up into individual lines.\r
+        */\r
+       private List<String> lines;\r
+\r
+       /**\r
+        * The raw text, broken up into individual lines.\r
+        */\r
+       public List<String> getText() {\r
+               return Collections.unmodifiableList(lines);\r
+       }\r
+\r
+       public enum KLineType {\r
+               NORMAL, H1, H2, H3, H4, H5, H6, BLANK,\r
+               // TODO LIST, BLOCKQUOTE,\r
+               /** A line marking Markdown info about the preceding line, e.g. ====== */\r
+               MARKER,\r
+               /** A line containing meta-data, e.g. title: My Page */\r
+               META\r
+       }\r
+\r
+       /**\r
+        * Information about each line.\r
+        */\r
+       private List<KLineType> lineTypes;\r
+       private Map<Integer,Object> pageObjects = new HashMap<Integer, Object>();\r
+\r
+       // TODO meta-data, footnotes, tables, link & image attributes\r
+       private static Pattern multiMarkdownTag = Pattern.compile("^([\\w].*):(.*)");\r
+       private Map<String, String> multiMarkdownTags = new HashMap<String, String>();\r
+       \r
+       // Regular expression for Github support\r
+       private static Pattern githubURLDetection = Pattern.compile("((https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|])");\r
+\r
+       /**\r
+        * The top-level headers. FIXME handle documents which have a 2nd level\r
+        * header before any 1st level ones\r
+        */\r
+       private final List<Header> level1Headers = new ArrayList<Header>();\r
+       private final IPreferenceStore pStore;\r
+\r
+       /**\r
+        * Create a page.\r
+        * \r
+        * @param text\r
+        */\r
+       public MarkdownPage(String text) {\r
+               pStore = Activator.getDefault().getPreferenceStore();\r
+               setText(text);\r
+       }\r
+\r
+       /**\r
+        * Reset the text for this page.\r
+        * \r
+        * @param text\r
+        */\r
+       private void setText(String text) {\r
+               // Get lines\r
+               lines = StringMethods.splitLines(text);\r
+               // Clean out old\r
+               level1Headers.clear();\r
+               lineTypes = new ArrayList<KLineType>(lines.size());\r
+               pageObjects.clear();\r
+               // Dummy level-1 header in case there are none          \r
+               Header dummyTopHeader = new Header(1, 0, "", null);\r
+               level1Headers.add(dummyTopHeader);\r
+               Header currentHeader = dummyTopHeader;          \r
+               // Identify line types          \r
+               int lineNum = 0;\r
+\r
+               // Check if we should support the Multi-Markdown Metadata\r
+               boolean multiMarkdownMetadataSupport =\r
+                               pStore.getBoolean(MarkdownPreferencePage.PREF_MULTIMARKDOWN_METADATA);\r
+               \r
+               // Multi-markdown header\r
+               if (multiMarkdownMetadataSupport) {\r
+                       // The key is the text before the colon, and the data is the text\r
+                       // after the\r
+                       // colon. In the above example, notice that there are two lines of\r
+                       // information\r
+                       // for the Author key. If you end a line with “space-space-newline”,\r
+                       // the newline\r
+                       // will be included when converted to other formats.\r
+                       //\r
+                       // There must not be any whitespace above the metadata, and the\r
+                       // metadata block\r
+                       // ends with the first whitespace only line. The metadata is\r
+                       // stripped from the\r
+                       // document before it is passed on to the syntax parser.\r
+                       \r
+                       //\r
+                       // Check if the Metdatas are valid\r
+                       //\r
+                       boolean validMetadata = true;\r
+                       for (lineNum = 0; lineNum < lines.size(); lineNum++) {\r
+                               String line = lines.get(lineNum);\r
+                               if (Utils.isBlank(line)) {\r
+                                       break;\r
+                               }\r
+                               Matcher m = multiMarkdownTag.matcher(line);\r
+                               if (!m.find()) {\r
+                                       if (lineNum == 0) {\r
+                                               // No MultiMarkdown metadata\r
+                                               validMetadata = false;\r
+                                               break;\r
+                                       } else if (!line.matches("^\\s.*\n")) {\r
+                                               // The next line was not intended (ie. it does not start\r
+                                               // with a whitespace)\r
+                                               validMetadata = false;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       // Valid Metadatas have been found. We need to retrieve these keys/values.\r
+                       if (validMetadata) {\r
+                               String data = "";\r
+                               String tag = "";\r
+                               for (lineNum = 0; lineNum < lines.size(); lineNum++) {\r
+                                       String line = lines.get(lineNum);\r
+                                       if (Utils.isBlank(line)) {\r
+                                               break;\r
+                                       }\r
+                                       Matcher m = multiMarkdownTag.matcher(line);\r
+                                       if (!m.find()) {\r
+                                               if (lineNum == 0) {\r
+                                                       break;\r
+                                               }\r
+                                               // Multi-line tag\r
+                                               lineTypes.add(KLineType.META);\r
+                                               data += StrUtils.LINEEND + line.trim();\r
+                                               multiMarkdownTags.put(tag, data);\r
+                                       } else {\r
+                                               lineTypes.add(KLineType.META);\r
+                                               tag = m.group(0);\r
+                                               data = m.group(1).trim();\r
+                                               if (m.group(1).endsWith(line))\r
+                                                       multiMarkdownTags.put(tag, data);\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               lineNum = 0;\r
+                       }\r
+               }\r
+               for (; lineNum < lines.size(); lineNum++) {\r
+                       String line = lines.get(lineNum);\r
+                       // Headings\r
+                       int h = numHash(line);\r
+                       String hLine = line;\r
+                       int hLineNum = lineNum;\r
+                       int underline = -1;\r
+                       if (lineNum != 0) {\r
+                               underline = just(line, '=') ? 1 : just(line, '-') ? 2 : -1;\r
+                       }\r
+                       if (underline != -1) {\r
+                               h = underline;\r
+                               hLineNum = lineNum - 1;\r
+                               hLine = lines.get(lineNum - 1);\r
+                               lineTypes.set(hLineNum, KLineType.values()[h]);\r
+                               lineTypes.add(KLineType.MARKER);\r
+                       }\r
+                       // Create a Header object\r
+                       if (h > 0) {\r
+                               if (underline == -1)\r
+                                       lineTypes.add(KLineType.values()[h]);\r
+                               Header header = new Header(h, hLineNum, hLine, currentHeader);\r
+                               if (h == 1) {\r
+                                       level1Headers.add(header);\r
+                               }\r
+                               pageObjects.put(hLineNum, header);\r
+                               currentHeader = header;\r
+                               continue;\r
+                       }\r
+                       // TODO List\r
+                       // TODO Block quote\r
+                       // Blank line\r
+                       if (Utils.isBlank(line)) {\r
+                               lineTypes.add(KLineType.BLANK);\r
+                               continue;\r
+                       }\r
+                       // Normal\r
+                       lineTypes.add(KLineType.NORMAL);\r
+               } // end line-loop\r
+               // Remove dummy header?\r
+               if (dummyTopHeader.getSubHeaders().size() == 0) {\r
+                       level1Headers.remove(dummyTopHeader);\r
+               }\r
+               \r
+               boolean githubSyntaxSupport =\r
+                               pStore.getBoolean(MarkdownPreferencePage.PREF_GITHUB_SYNTAX);\r
+               if (githubSyntaxSupport) {\r
+                       /*\r
+                        * Support Code block\r
+                        */\r
+                       boolean inCodeBlock = false;\r
+                       for (lineNum = 0; lineNum < lines.size(); lineNum++) {\r
+                               String line = lines.get(lineNum);\r
+                               // Found the start or end of a code block\r
+                               if (line.matches("^```.*\n")) {\r
+                                       // We reverse the boolean value\r
+                                       inCodeBlock = !inCodeBlock;\r
+\r
+                                       // We force the line to be blank. But we mark it as normal\r
+                                       // to prevent to be stripped\r
+                                       lines.set(lineNum, "\n");\r
+                                       lineTypes.set(lineNum, KLineType.NORMAL);\r
+                                       continue;\r
+                               }\r
+                               if (inCodeBlock) {\r
+                                       lines.set(lineNum, "    " + line);\r
+                               }\r
+                       }\r
+                       \r
+                       /*\r
+                        * Support for URL Detection\r
+                        * We search for links that are not captured by Markdown syntax\r
+                        */\r
+                       for (lineNum = 0; lineNum < lines.size(); lineNum++) {\r
+                               String line = lines.get(lineNum);\r
+                               // When a link has been replaced we need to scan again the string\r
+                               // as the offsets have changed (we add '<' and '>' to the link to\r
+                               // be interpreted by the markdown library)\r
+                               boolean urlReplaced;\r
+\r
+                               do {\r
+                                       urlReplaced = false;\r
+                                       Matcher m = githubURLDetection.matcher(line);\r
+                                       while (m.find()) {\r
+                                               // Ignore the URL following the format <link>\r
+                                               if ((m.start() - 1 >= 0) && (m.end() < line.length()) &&\r
+                                                       (line.charAt(m.start() - 1) == '<') &&\r
+                                                       (line.charAt(m.end()) == '>'))\r
+                                               {\r
+                                                       continue;\r
+                                               }\r
+       \r
+                                               // Ignore the URL following the format [description](link)\r
+                                               if ((m.start() - 2 >= 0) && (m.end() < line.length()) &&\r
+                                                       (line.charAt(m.start() - 2) == ']') &&\r
+                                                       (line.charAt(m.start() - 1) == '(') &&\r
+                                                       (line.charAt(m.end()) == ')'))\r
+                                               {\r
+                                                       continue;\r
+                                               }\r
+       \r
+                                               // Ignore the URL following the format [description](link "title")\r
+                                               if ((m.start() - 2 >= 0) && (m.end() + 1 < line.length()) &&\r
+                                                       (line.charAt(m.start() - 2) == ']') &&\r
+                                                       (line.charAt(m.start() - 1) == '(') &&\r
+                                                       (line.charAt(m.end()) == ' ') &&\r
+                                                       (line.charAt(m.end() + 1) == '"'))\r
+                                               {\r
+                                                       continue;\r
+                                               }\r
+                                               \r
+                                               if (m.start() - 1 >= 0) {\r
+                                                       // Case when the link is at the beginning of the string\r
+                                                       line = line.substring(0, m.start()) + "<" + m.group(0) + ">" + line.substring(m.end());\r
+                                               } else {\r
+                                                       line = "<" + m.group(0) + ">" + line.substring(m.end());\r
+                                               }\r
+                                               \r
+                                               // We replaced the string in the array\r
+                                               lines.set(lineNum, line);\r
+                                               urlReplaced = true;\r
+                                               break;\r
+                                       }\r
+                               } while (urlReplaced);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param line\r
+        * @param c\r
+        * @return true if line is just cs (and whitespace at the start/end)\r
+        */\r
+       boolean just(String line, char c) {\r
+               return line.matches("\\s*"+c+"+\\s*");\r
+       }\r
+\r
+       /**\r
+        * @param line\r
+        * @return The number of # symbols prepending the line.\r
+        */\r
+       private int numHash(String line) {\r
+               for (int i = 0; i < line.length(); i++) {\r
+                       if (line.charAt(i) != '#')\r
+                               return i;\r
+               }\r
+               return line.length();\r
+       }\r
+\r
+       /**\r
+        * \r
+        * @param parent\r
+        *            Can be null for top-level\r
+        * @return List of sub-headers. Never null. FIXME handle documents which\r
+        *         have a 2nd level header before any 1st level ones\r
+        */\r
+       public List<Header> getHeadings(Header parent) {\r
+               if (parent == null) {\r
+                       return Collections.unmodifiableList(level1Headers);\r
+               }\r
+               return Collections.unmodifiableList(parent.subHeaders);\r
+       }\r
+\r
+       // public WebPage getWebPage() {\r
+       // WebPage page = new WebPage();\r
+       // // Add the lines, one by one\r
+       // boolean inParagraph = false;\r
+       // for (int i=0; i<lines.size(); i++) {\r
+       // String line = lines.get(i);\r
+       // KLineType type = lineTypes.get(i);\r
+       // switch(type) {\r
+       // // Heading?\r
+       // case H1: case H2: case H3:\r
+       // case H4: case H5: case H6:\r
+       // if (inParagraph) page.addText("</p>");\r
+       // line = cleanHeader(line);\r
+       // page.addText("<"+type+">"+line+"</"+type+">");\r
+       // continue;\r
+       // case MARKER: // Ignore\r
+       // continue;\r
+       // // TODO List?\r
+       // // TODO Block quote?\r
+       // }\r
+       // // Paragraph end?\r
+       // if (Utils.isBlank(line)) {\r
+       // if (inParagraph) page.addText("</p>");\r
+       // continue;\r
+       // }\r
+       // // Paragraph start?\r
+       // if (!inParagraph) {\r
+       // page.addText("<p>");\r
+       // inParagraph = true;\r
+       // }\r
+       // // Plain text\r
+       // page.addText(line);\r
+       // }\r
+       // return page;\r
+       // }\r
+\r
+       /**\r
+        * Get the HTML for this page. Uses the MarkdownJ project.\r
+        */\r
+       public String html() {\r
+               // Section numbers??\r
+               boolean sectionNumbers = pStore\r
+                               .getBoolean(MarkdownPreferencePage.PREF_SECTION_NUMBERS);\r
+               // Chop out multi-markdown header\r
+               StringBuilder sb = new StringBuilder();\r
+               assert lines.size() == lineTypes.size();\r
+               for (int i = 0, n = lines.size(); i < n; i++) {\r
+                       KLineType type = lineTypes.get(i);\r
+                       if (type == KLineType.META)\r
+                               continue;\r
+                       String line = lines.get(i);\r
+                       if (sectionNumbers && isHeader(type) && line.contains("$section")) {\r
+                               // TODO Header section = headers.get(i);\r
+                               // String secNum = section.getSectionNumber();\r
+                               // line.replace("$section", secNum);\r
+                       }\r
+                       sb.append(line);\r
+               }\r
+               String text = sb.toString();\r
+               // Use external converter?\r
+               final String cmd = pStore\r
+                               .getString(MarkdownPreferencePage.PREF_MARKDOWN_COMMAND);\r
+               if (Utils.isBlank(cmd)\r
+                               || (cmd.startsWith("(") && cmd.contains("MarkdownJ"))) {\r
+                       // Use MarkdownJ\r
+                       MarkdownProcessor markdown = new MarkdownProcessor();\r
+                       // MarkdownJ doesn't convert £s for some reason\r
+                       text = text.replace("£", "&pound;");\r
+                       String html = markdown.markdown(text);\r
+                       return html;\r
+               }\r
+               // Attempt to run external command\r
+               try {\r
+                       final File md = File.createTempFile("tmp", ".md");\r
+                       FileUtils.write(md, text);\r
+                       Process process = new Process(cmd+" "+md.getAbsolutePath());\r
+                       process.run();\r
+                       int ok = process.waitFor(10000);\r
+                       if (ok != 0) throw new FailureException(cmd+" failed:\n"+process.getError());\r
+                       String html = process.getOutput();\r
+                       FileUtils.delete(md);\r
+                       return html;\r
+               } catch (Exception e) {\r
+                       throw Utils.runtime(e);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param type\r
+        * @return\r
+        */\r
+       private boolean isHeader(KLineType type) {\r
+               return type == KLineType.H1 || type == KLineType.H2\r
+                               || type == KLineType.H3 || type == KLineType.H4\r
+                               || type == KLineType.H5 || type == KLineType.H6;\r
+       }\r
+\r
+       /**\r
+        * Return the raw text of this page.\r
+        */\r
+       @Override\r
+       public String toString() {\r
+               StringBuilder sb = new StringBuilder();\r
+               for (String line : lines) {\r
+                       sb.append(line);\r
+               }\r
+               return sb.toString();\r
+       }\r
+\r
+       /**\r
+        * Line type information for the raw text.\r
+        * \r
+        * @return\r
+        */\r
+       public List<KLineType> getLineTypes() {\r
+               return Collections.unmodifiableList(lineTypes);\r
+       }\r
+\r
+       /**\r
+        * @param line\r
+        * @return\r
+        */\r
+       public Object getPageObject(int line) {         \r
+               return pageObjects.get(line);\r
+       }\r
+\r
+}\r
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPageTest.java b/bundles/winterwell.markdown/src/winterwell/markdown/pagemodel/MarkdownPageTest.java
new file mode 100644 (file)
index 0000000..244d437
--- /dev/null
@@ -0,0 +1,30 @@
+package winterwell.markdown.pagemodel;
+
+import java.io.File;
+import java.util.List;
+
+import winterwell.markdown.pagemodel.MarkdownPage.Header;
+import winterwell.utils.io.FileUtils;
+
+
+
+public class MarkdownPageTest //extends TestCase 
+{
+
+       public static void main(String[] args) {
+               MarkdownPageTest mpt = new MarkdownPageTest();
+               mpt.testGetHeadings();
+       }
+       
+       public void testGetHeadings() {
+               // problem caused by a line beginning --, now fixed
+               String txt = FileUtils.read(new File(
+                               "/home/daniel/winterwell/companies/DTC/projects/DTC-bayes/report1.txt")); 
+               MarkdownPage p = new MarkdownPage(txt);
+               List<Header> h1s = p.getHeadings(null);
+               Header h1 = h1s.get(0);
+               List<Header> h2s = h1.getSubHeaders();
+               assert h2s.size() > 2;
+       }
+
+}
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/preferences/MarkdownPreferencePage.java b/bundles/winterwell.markdown/src/winterwell/markdown/preferences/MarkdownPreferencePage.java
new file mode 100644 (file)
index 0000000..36dadbc
--- /dev/null
@@ -0,0 +1,214 @@
+package winterwell.markdown.preferences;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.ColorFieldEditor;
+import org.eclipse.jface.preference.FieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.preference.StringFieldEditor;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+import winterwell.markdown.Activator;
+
+/**
+ * This class represents a preference page that
+ * is contributed to the Preferences dialog. By 
+ * subclassing <samp>FieldEditorPreferencePage</samp>, we
+ * can use the field support built into JFace that allows
+ * us to create a page that is small and knows how to 
+ * save, restore and apply itself.
+ * <p>
+ * This page is used to modify preferences only. They
+ * are stored in the preference store that belongs to
+ * the main plug-in class. That way, preferences can
+ * be accessed directly via the preference store.
+ */
+
+public class MarkdownPreferencePage
+       extends FieldEditorPreferencePage
+       implements IWorkbenchPreferencePage {
+
+       public static final String PREF_FOLDING = "Pref_Folding";
+       public static final String PREF_WORD_WRAP = "Pref_WordWrap";
+       public static final String PREF_TASK_TAGS = "Pref_TaskTagsOn";
+       public static final String PREF_TASK_TAGS_DEFINED = "Pref_TaskTags";
+       public static final String PREF_SECTION_NUMBERS = "Pref_SectionNumbers";
+
+       public static final String PREF_MARKDOWN_COMMAND = "Pref_Markdown_Command";
+       private static final String MARKDOWNJ = "(use built-in MarkdownJ converter)";
+       
+
+       public static final String PREF_DEFUALT = "Pref_Default";
+       public static final String PREF_COMMENT = "Pref_Comment";
+       public static final String PREF_HEADER = "Pref_Header";
+       public static final String PREF_LINK = "Pref_Link";
+       public static final String PREF_CODE = "Pref_Code";
+       public static final String PREF_CODE_BG = "Pref_Code_Background";
+       
+       public static final String PREF_GITHUB_SYNTAX = "Pref_Github_Syntax";
+       public static final String PREF_MULTIMARKDOWN_METADATA = "Pref_MultiMarkdown_Metadata";
+       
+       private static final RGB DEF_DEFAULT = new RGB(0, 0, 0);
+       private static final RGB DEF_COMMENT = new RGB(128, 0, 0);
+       private static final RGB DEF_HEADER = new RGB(0, 128, 0);
+       private static final RGB DEF_LINK = new RGB(106, 131, 199);
+       private static final RGB DEF_CODE = new RGB(0, 0, 0);
+       private static final RGB DEF_CODE_BG = new RGB(244,244,244);
+       
+       public MarkdownPreferencePage() {
+               super(GRID);
+               IPreferenceStore pStore = Activator.getDefault().getPreferenceStore();
+               setDefaultPreferences(pStore);
+               setPreferenceStore(pStore);
+               setDescription("Settings for the Markdown text editor. See also the general text editor preferences.");
+       }
+       
+       public static void setDefaultPreferences(IPreferenceStore pStore) {
+               pStore.setDefault(PREF_WORD_WRAP, false);
+               pStore.setDefault(PREF_FOLDING, true);
+               pStore.setDefault(PREF_TASK_TAGS, true);
+               pStore.setDefault(PREF_TASK_TAGS_DEFINED, "TODO,FIXME,??");
+               pStore.setDefault(PREF_MARKDOWN_COMMAND, MARKDOWNJ);
+               pStore.setDefault(PREF_SECTION_NUMBERS, true);
+               pStore.setDefault(PREF_GITHUB_SYNTAX, true);
+               pStore.setDefault(PREF_MULTIMARKDOWN_METADATA, false);
+               
+               PreferenceConverter.setDefault(pStore, PREF_DEFUALT, DEF_DEFAULT);
+               PreferenceConverter.setDefault(pStore, PREF_COMMENT, DEF_COMMENT);
+               PreferenceConverter.setDefault(pStore, PREF_HEADER, DEF_HEADER);
+               PreferenceConverter.setDefault(pStore, PREF_LINK, DEF_LINK);
+               PreferenceConverter.setDefault(pStore, PREF_CODE, DEF_CODE);
+               PreferenceConverter.setDefault(pStore, PREF_CODE_BG, DEF_CODE_BG);
+       }
+       
+       /**
+        * Creates the field editors. Field editors are abstractions of
+        * the common GUI blocks needed to manipulate various types
+        * of preferences. Each field editor knows how to save and
+        * restore itself.
+        */
+       @Override
+       public void createFieldEditors() {
+               // Word wrap
+               BooleanFieldEditor fd = new BooleanFieldEditor(PREF_WORD_WRAP,
+                               "Soft word wrapping \r\n"
++"Note: may cause line numbers and related \r\n" +
+               "functionality to act a bit strangely",
+                               getFieldEditorParent());
+               addField(fd);
+               // Task tags
+               fd = new BooleanFieldEditor(PREF_TASK_TAGS,
+                               "Manage tasks using task tags \r\n" +
+                               "If true, this will add and delete tags in sync with edits.",
+                               getFieldEditorParent());
+               addField(fd);           
+               StringFieldEditor tags = new StringFieldEditor(PREF_TASK_TAGS_DEFINED,
+                               "Task tags\nComma separated list of recognised task tags.", getFieldEditorParent());
+               addField(tags);
+               // Code folding
+               fd = new BooleanFieldEditor(PREF_FOLDING,
+                               "Document folding, a.k.a. outline support",
+                               getFieldEditorParent());
+               addField(fd);
+               // Command line         
+//             addField(new DummyField() {
+//                     protected void makeComponent(Composite parent) {
+//                             Label label = new Label(parent, 0);
+//                             label.setText("Hello!");
+//                             GridData gd = new GridData(100, 20);
+//                             label.setLayoutData(gd);
+//                     }                       
+//             });
+               StringFieldEditor cmd = new StringFieldEditor(PREF_MARKDOWN_COMMAND,
+                               "UNSTABLE: Command-line to run Markdown.\r\n" +
+                               "This should take in a file and output to std-out.\n" +
+                               "Leave blank to use the built-in Java converter.", getFieldEditorParent());             
+               addField(cmd);
+               
+               ColorFieldEditor def = new ColorFieldEditor(PREF_DEFUALT, "Default text", getFieldEditorParent());
+               addField(def);
+               
+               ColorFieldEditor com = new ColorFieldEditor(PREF_COMMENT, "Comment", getFieldEditorParent());
+               addField(com);
+               
+               ColorFieldEditor link = new ColorFieldEditor(PREF_LINK, "Link", getFieldEditorParent());
+               addField(link);
+               
+               ColorFieldEditor head = new ColorFieldEditor(PREF_HEADER, "Header and List indicator", getFieldEditorParent());
+               addField(head);
+               
+               ColorFieldEditor code = new ColorFieldEditor(PREF_CODE, "Code", getFieldEditorParent());
+               addField(code);
+
+               ColorFieldEditor codeBg = new ColorFieldEditor(PREF_CODE_BG, "Code Background", getFieldEditorParent());
+               addField(codeBg);
+               
+               /*
+                * Fields for the preview window
+                */
+
+               // Github Syntax support
+               fd = new BooleanFieldEditor(PREF_GITHUB_SYNTAX,
+                               "Support Github Syntax",
+                               getFieldEditorParent());
+               addField(fd);
+
+               // Multi-Markdown support
+               fd = new BooleanFieldEditor(PREF_MULTIMARKDOWN_METADATA,
+                               "Support Multi-Markdown Metadata",
+                               getFieldEditorParent());
+               addField(fd);
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+        */
+       public void init(IWorkbench workbench) {
+               
+       }
+
+       public static boolean wordWrap() {
+               IPreferenceStore pStore = Activator.getDefault().getPreferenceStore();
+               if (! pStore.contains(MarkdownPreferencePage.PREF_WORD_WRAP)) {
+                       return false;
+               }
+               return pStore.getBoolean(MarkdownPreferencePage.PREF_WORD_WRAP);                
+       }
+       
+}
+
+abstract class DummyField extends FieldEditor {
+       @Override
+       protected void adjustForNumColumns(int numColumns) {
+               // do nothing
+       }
+       @Override
+       protected void doFillIntoGrid(Composite parent, int numColumns) {
+               makeComponent(parent);
+       }
+       abstract protected void makeComponent(Composite parent);
+       
+       @Override
+       protected void doLoad() {
+               // 
+       }
+       @Override
+       protected void doLoadDefault() {
+               // 
+       }
+
+       @Override
+       protected void doStore() {
+               // 
+       }
+
+       @Override
+       public int getNumberOfControls() {
+               return 1;
+       }
+       
+}
\ No newline at end of file
diff --git a/bundles/winterwell.markdown/src/winterwell/markdown/views/MarkdownPreview.java b/bundles/winterwell.markdown/src/winterwell/markdown/views/MarkdownPreview.java
new file mode 100644 (file)
index 0000000..c103953
--- /dev/null
@@ -0,0 +1,100 @@
+package winterwell.markdown.views;
+
+
+import java.io.File;
+import java.net.URI;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.part.ViewPart;
+
+import winterwell.markdown.editors.ActionBarContributor;
+import winterwell.markdown.editors.MarkdownEditor;
+import winterwell.markdown.pagemodel.MarkdownPage;
+
+
+
+
+public class MarkdownPreview extends ViewPart {
+       
+       public static MarkdownPreview preview = null;
+       
+       private Browser viewer = null;
+
+       /**
+        * The constructor.
+        */
+       public MarkdownPreview() {
+               preview = this;
+       }
+
+       /**
+        * This is a callback that will allow us
+        * to create the viewer and initialize it.
+        */
+       @Override
+       public void createPartControl(Composite parent) {
+               viewer = new Browser(parent, SWT.MULTI); // | SWT.H_SCROLL | SWT.V_SCROLL
+       }
+
+
+
+
+       /**
+        * Passing the focus request to the viewer's control.
+        */
+       @Override
+       public void setFocus() {
+               if (viewer==null) return;
+               viewer.setFocus();
+               update();
+       }
+
+       public void update() {
+               if (viewer==null) return;
+               try {
+                       IEditorPart editor = ActionBarContributor.getActiveEditor();
+                       if (!(editor instanceof MarkdownEditor)) {
+                               viewer.setText("");
+                               return;
+                       }
+                       MarkdownEditor ed = (MarkdownEditor) editor;
+                       MarkdownPage page = ed.getMarkdownPage();
+                       String html = page.html();
+                       html = addBaseURL(editor, html);
+                       if (page != null) viewer.setText(html);
+                       else viewer.setText("");
+               } catch (Exception ex) {
+                       // Smother
+                       System.out.println(ex);
+                       
+                       if (viewer != null && !viewer.isDisposed())
+                               viewer.setText(ex.getMessage());
+               }
+       }
+
+       /**
+        * Adjust the URL base to be the file's directory.
+        * @param editor
+        * @param html
+        * @return
+        */
+       private String addBaseURL(IEditorPart editor, String html) {
+       try {
+               IPathEditorInput input = (IPathEditorInput) editor.getEditorInput();
+               IPath path = input.getPath();
+               path = path.removeLastSegments(1);
+               File f = path.toFile();
+               URI fileURI = f.toURI();
+               String html2 = "<html><head><base href='"+fileURI+"' /></head><body>\r\n"+html
+               +"\r\n</body></html>";
+               return html2;
+       } catch (Exception ex) {
+               return html;
+       }
+       }
+}
\ No newline at end of file
diff --git a/features/com.lowagie.text.feature/.gitignore b/features/com.lowagie.text.feature/.gitignore
new file mode 100644 (file)
index 0000000..46281dc
--- /dev/null
@@ -0,0 +1 @@
+/target/**\r
diff --git a/features/com.lowagie.text.feature/.project b/features/com.lowagie.text.feature/.project
new file mode 100644 (file)
index 0000000..d825fa3
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>com.lowagie.text.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/features/com.lowagie.text.feature/build.properties b/features/com.lowagie.text.feature/build.properties
new file mode 100644 (file)
index 0000000..82ab19c
--- /dev/null
@@ -0,0 +1 @@
+bin.includes = feature.xml\r
diff --git a/features/com.lowagie.text.feature/feature.xml b/features/com.lowagie.text.feature/feature.xml
new file mode 100644 (file)
index 0000000..e5a23fa
--- /dev/null
@@ -0,0 +1,514 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<feature\r
+      id="com.lowagie.text"\r
+      label="iText"\r
+      version="2.1.7"\r
+      provider-name="VTT Technical Research Centre of Finland">\r
+\r
+   <description url="http://www.lowagie.com/iText/">\r
+      iText is a library that allows you to generate PDF files on the\r
+fly.\r
+   </description>\r
+\r
+   <copyright url="http://www.lowagie.com/iText/">\r
+      Copyright © 1999-2007 by Bruno Lowagie, Adolf Baeyensstraat 121, 9040 Gent, BELGIUM\r
+   </copyright>\r
+\r
+   <license url="http://www.lowagie.com/iText/MPL-1.1.txt">\r
+      MOZILLA PUBLIC LICENSE\r
+                                Version 1.1\r
+\r
+                              ---------------\r
+\r
+1. Definitions.\r
+\r
+     1.0.1. &quot;Commercial Use&quot; means distribution or otherwise making the\r
+     Covered Code available to a third party.\r
+\r
+     1.1. &quot;Contributor&quot; means each entity that creates or contributes to\r
+     the creation of Modifications.\r
+\r
+     1.2. &quot;Contributor Version&quot; means the combination of the Original\r
+     Code, prior Modifications used by a Contributor, and the Modifications\r
+     made by that particular Contributor.\r
+\r
+     1.3. &quot;Covered Code&quot; means the Original Code or Modifications or the\r
+     combination of the Original Code and Modifications, in each case\r
+     including portions thereof.\r
+\r
+     1.4. &quot;Electronic Distribution Mechanism&quot; means a mechanism generally\r
+     accepted in the software development community for the electronic\r
+     transfer of data.\r
+\r
+     1.5. &quot;Executable&quot; means Covered Code in any form other than Source\r
+     Code.\r
+\r
+     1.6. &quot;Initial Developer&quot; means the individual or entity identified\r
+     as the Initial Developer in the Source Code notice required by Exhibit\r
+     A.\r
+\r
+     1.7. &quot;Larger Work&quot; means a work which combines Covered Code or\r
+     portions thereof with code not governed by the terms of this License.\r
+\r
+     1.8. &quot;License&quot; means this document.\r
+\r
+     1.8.1. &quot;Licensable&quot; means having the right to grant, to the maximum\r
+     extent possible, whether at the time of the initial grant or\r
+     subsequently acquired, any and all of the rights conveyed herein.\r
+\r
+     1.9. &quot;Modifications&quot; means any addition to or deletion from the\r
+     substance or structure of either the Original Code or any previous\r
+     Modifications. When Covered Code is released as a series of files, a\r
+     Modification is:\r
+          A. Any addition to or deletion from the contents of a file\r
+          containing Original Code or previous Modifications.\r
+\r
+          B. Any new file that contains any part of the Original Code or\r
+          previous Modifications.\r
+\r
+     1.10. &quot;Original Code&quot; means Source Code of computer software code\r
+     which is described in the Source Code notice required by Exhibit A as\r
+     Original Code, and which, at the time of its release under this\r
+     License is not already Covered Code governed by this License.\r
+\r
+     1.10.1. &quot;Patent Claims&quot; means any patent claim(s), now owned or\r
+     hereafter acquired, including without limitation,  method, process,\r
+     and apparatus claims, in any patent Licensable by grantor.\r
+\r
+     1.11. &quot;Source Code&quot; means the preferred form of the Covered Code for\r
+     making modifications to it, including all modules it contains, plus\r
+     any associated interface definition files, scripts used to control\r
+     compilation and installation of an Executable, or source code\r
+     differential comparisons against either the Original Code or another\r
+     well known, available Covered Code of the Contributor&apos;s choice. The\r
+     Source Code can be in a compressed or archival form, provided the\r
+     appropriate decompression or de-archiving software is widely available\r
+     for no charge.\r
+\r
+     1.12. &quot;You&quot; (or &quot;Your&quot;)  means an individual or a legal entity\r
+     exercising rights under, and complying with all of the terms of, this\r
+     License or a future version of this License issued under Section 6.1.\r
+     For legal entities, &quot;You&quot; includes any entity which controls, is\r
+     controlled by, or is under common control with You. For purposes of\r
+     this definition, &quot;control&quot; means (a) the power, direct or indirect,\r
+     to cause the direction or management of such entity, whether by\r
+     contract or otherwise, or (b) ownership of more than fifty percent\r
+     (50%) of the outstanding shares or beneficial ownership of such\r
+     entity.\r
+\r
+2. Source Code License.\r
+\r
+     2.1. The Initial Developer Grant.\r
+     The Initial Developer hereby grants You a world-wide, royalty-free,\r
+     non-exclusive license, subject to third party intellectual property\r
+     claims:\r
+          (a)  under intellectual property rights (other than patent or\r
+          trademark) Licensable by Initial Developer to use, reproduce,\r
+          modify, display, perform, sublicense and distribute the Original\r
+          Code (or portions thereof) with or without Modifications, and/or\r
+          as part of a Larger Work; and\r
+\r
+          (b) under Patents Claims infringed by the making, using or\r
+          selling of Original Code, to make, have made, use, practice,\r
+          sell, and offer for sale, and/or otherwise dispose of the\r
+          Original Code (or portions thereof).\r
+\r
+          (c) the licenses granted in this Section 2.1(a) and (b) are\r
+          effective on the date Initial Developer first distributes\r
+          Original Code under the terms of this License.\r
+\r
+          (d) Notwithstanding Section 2.1(b) above, no patent license is\r
+          granted: 1) for code that You delete from the Original Code; 2)\r
+          separate from the Original Code;  or 3) for infringements caused\r
+          by: i) the modification of the Original Code or ii) the\r
+          combination of the Original Code with other software or devices.\r
+\r
+     2.2. Contributor Grant.\r
+     Subject to third party intellectual property claims, each Contributor\r
+     hereby grants You a world-wide, royalty-free, non-exclusive license\r
+\r
+          (a)  under intellectual property rights (other than patent or\r
+          trademark) Licensable by Contributor, to use, reproduce, modify,\r
+          display, perform, sublicense and distribute the Modifications\r
+          created by such Contributor (or portions thereof) either on an\r
+          unmodified basis, with other Modifications, as Covered Code\r
+          and/or as part of a Larger Work; and\r
+\r
+          (b) under Patent Claims infringed by the making, using, or\r
+          selling of  Modifications made by that Contributor either alone\r
+          and/or in combination with its Contributor Version (or portions\r
+          of such combination), to make, use, sell, offer for sale, have\r
+          made, and/or otherwise dispose of: 1) Modifications made by that\r
+          Contributor (or portions thereof); and 2) the combination of\r
+          Modifications made by that Contributor with its Contributor\r
+          Version (or portions of such combination).\r
+\r
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are\r
+          effective on the date Contributor first makes Commercial Use of\r
+          the Covered Code.\r
+\r
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is\r
+          granted: 1) for any code that Contributor has deleted from the\r
+          Contributor Version; 2)  separate from the Contributor Version;\r
+          3)  for infringements caused by: i) third party modifications of\r
+          Contributor Version or ii)  the combination of Modifications made\r
+          by that Contributor with other software  (except as part of the\r
+          Contributor Version) or other devices; or 4) under Patent Claims\r
+          infringed by Covered Code in the absence of Modifications made by\r
+          that Contributor.\r
+\r
+3. Distribution Obligations.\r
+\r
+     3.1. Application of License.\r
+     The Modifications which You create or to which You contribute are\r
+     governed by the terms of this License, including without limitation\r
+     Section 2.2. The Source Code version of Covered Code may be\r
+     distributed only under the terms of this License or a future version\r
+     of this License released under Section 6.1, and You must include a\r
+     copy of this License with every copy of the Source Code You\r
+     distribute. You may not offer or impose any terms on any Source Code\r
+     version that alters or restricts the applicable version of this\r
+     License or the recipients&apos; rights hereunder. However, You may include\r
+     an additional document offering the additional rights described in\r
+     Section 3.5.\r
+\r
+     3.2. Availability of Source Code.\r
+     Any Modification which You create or to which You contribute must be\r
+     made available in Source Code form under the terms of this License\r
+     either on the same media as an Executable version or via an accepted\r
+     Electronic Distribution Mechanism to anyone to whom you made an\r
+     Executable version available; and if made available via Electronic\r
+     Distribution Mechanism, must remain available for at least twelve (12)\r
+     months after the date it initially became available, or at least six\r
+     (6) months after a subsequent version of that particular Modification\r
+     has been made available to such recipients. You are responsible for\r
+     ensuring that the Source Code version remains available even if the\r
+     Electronic Distribution Mechanism is maintained by a third party.\r
+\r
+     3.3. Description of Modifications.\r
+     You must cause all Covered Code to which You contribute to contain a\r
+     file documenting the changes You made to create that Covered Code and\r
+     the date of any change. You must include a prominent statement that\r
+     the Modification is derived, directly or indirectly, from Original\r
+     Code provided by the Initial Developer and including the name of the\r
+     Initial Developer in (a) the Source Code, and (b) in any notice in an\r
+     Executable version or related documentation in which You describe the\r
+     origin or ownership of the Covered Code.\r
+\r
+     3.4. Intellectual Property Matters\r
+          (a) Third Party Claims.\r
+          If Contributor has knowledge that a license under a third party&apos;s\r
+          intellectual property rights is required to exercise the rights\r
+          granted by such Contributor under Sections 2.1 or 2.2,\r
+          Contributor must include a text file with the Source Code\r
+          distribution titled &quot;LEGAL&quot; which describes the claim and the\r
+          party making the claim in sufficient detail that a recipient will\r
+          know whom to contact. If Contributor obtains such knowledge after\r
+          the Modification is made available as described in Section 3.2,\r
+          Contributor shall promptly modify the LEGAL file in all copies\r
+          Contributor makes available thereafter and shall take other steps\r
+          (such as notifying appropriate mailing lists or newsgroups)\r
+          reasonably calculated to inform those who received the Covered\r
+          Code that new knowledge has been obtained.\r
+\r
+          (b) Contributor APIs.\r
+          If Contributor&apos;s Modifications include an application programming\r
+          interface and Contributor has knowledge of patent licenses which\r
+          are reasonably necessary to implement that API, Contributor must\r
+          also include this information in the LEGAL file.\r
+\r
+               (c)    Representations.\r
+          Contributor represents that, except as disclosed pursuant to\r
+          Section 3.4(a) above, Contributor believes that Contributor&apos;s\r
+          Modifications are Contributor&apos;s original creation(s) and/or\r
+          Contributor has sufficient rights to grant the rights conveyed by\r
+          this License.\r
+\r
+     3.5. Required Notices.\r
+     You must duplicate the notice in Exhibit A in each file of the Source\r
+     Code.  If it is not possible to put such notice in a particular Source\r
+     Code file due to its structure, then You must include such notice in a\r
+     location (such as a relevant directory) where a user would be likely\r
+     to look for such a notice.  If You created one or more Modification(s)\r
+     You may add your name as a Contributor to the notice described in\r
+     Exhibit A.  You must also duplicate this License in any documentation\r
+     for the Source Code where You describe recipients&apos; rights or ownership\r
+     rights relating to Covered Code.  You may choose to offer, and to\r
+     charge a fee for, warranty, support, indemnity or liability\r
+     obligations to one or more recipients of Covered Code. However, You\r
+     may do so only on Your own behalf, and not on behalf of the Initial\r
+     Developer or any Contributor. You must make it absolutely clear than\r
+     any such warranty, support, indemnity or liability obligation is\r
+     offered by You alone, and You hereby agree to indemnify the Initial\r
+     Developer and every Contributor for any liability incurred by the\r
+     Initial Developer or such Contributor as a result of warranty,\r
+     support, indemnity or liability terms You offer.\r
+\r
+     3.6. Distribution of Executable Versions.\r
+     You may distribute Covered Code in Executable form only if the\r
+     requirements of Section 3.1-3.5 have been met for that Covered Code,\r
+     and if You include a notice stating that the Source Code version of\r
+     the Covered Code is available under the terms of this License,\r
+     including a description of how and where You have fulfilled the\r
+     obligations of Section 3.2. The notice must be conspicuously included\r
+     in any notice in an Executable version, related documentation or\r
+     collateral in which You describe recipients&apos; rights relating to the\r
+     Covered Code. You may distribute the Executable version of Covered\r
+     Code or ownership rights under a license of Your choice, which may\r
+     contain terms different from this License, provided that You are in\r
+     compliance with the terms of this License and that the license for the\r
+     Executable version does not attempt to limit or alter the recipient&apos;s\r
+     rights in the Source Code version from the rights set forth in this\r
+     License. If You distribute the Executable version under a different\r
+     license You must make it absolutely clear that any terms which differ\r
+     from this License are offered by You alone, not by the Initial\r
+     Developer or any Contributor. You hereby agree to indemnify the\r
+     Initial Developer and every Contributor for any liability incurred by\r
+     the Initial Developer or such Contributor as a result of any such\r
+     terms You offer.\r
+\r
+     3.7. Larger Works.\r
+     You may create a Larger Work by combining Covered Code with other code\r
+     not governed by the terms of this License and distribute the Larger\r
+     Work as a single product. In such a case, You must make sure the\r
+     requirements of this License are fulfilled for the Covered Code.\r
+\r
+4. Inability to Comply Due to Statute or Regulation.\r
+\r
+     If it is impossible for You to comply with any of the terms of this\r
+     License with respect to some or all of the Covered Code due to\r
+     statute, judicial order, or regulation then You must: (a) comply with\r
+     the terms of this License to the maximum extent possible; and (b)\r
+     describe the limitations and the code they affect. Such description\r
+     must be included in the LEGAL file described in Section 3.4 and must\r
+     be included with all distributions of the Source Code. Except to the\r
+     extent prohibited by statute or regulation, such description must be\r
+     sufficiently detailed for a recipient of ordinary skill to be able to\r
+     understand it.\r
+\r
+5. Application of this License.\r
+\r
+     This License applies to code to which the Initial Developer has\r
+     attached the notice in Exhibit A and to related Covered Code.\r
+\r
+6. Versions of the License.\r
+\r
+     6.1. New Versions.\r
+     Netscape Communications Corporation (&quot;Netscape&quot;) may publish revised\r
+     and/or new versions of the License from time to time. Each version\r
+     will be given a distinguishing version number.\r
+\r
+     6.2. Effect of New Versions.\r
+     Once Covered Code has been published under a particular version of the\r
+     License, You may always continue to use it under the terms of that\r
+     version. You may also choose to use such Covered Code under the terms\r
+     of any subsequent version of the License published by Netscape. No one\r
+     other than Netscape has the right to modify the terms applicable to\r
+     Covered Code created under this License.\r
+\r
+     6.3. Derivative Works.\r
+     If You create or use a modified version of this License (which you may\r
+     only do in order to apply it to code which is not already Covered Code\r
+     governed by this License), You must (a) rename Your license so that\r
+     the phrases &quot;Mozilla&quot;, &quot;MOZILLAPL&quot;, &quot;MOZPL&quot;, &quot;Netscape&quot;,\r
+     &quot;MPL&quot;, &quot;NPL&quot; or any confusingly similar phrase do not appear in your\r
+     license (except to note that your license differs from this License)\r
+     and (b) otherwise make it clear that Your version of the license\r
+     contains terms which differ from the Mozilla Public License and\r
+     Netscape Public License. (Filling in the name of the Initial\r
+     Developer, Original Code or Contributor in the notice described in\r
+     Exhibit A shall not of themselves be deemed to be modifications of\r
+     this License.)\r
+\r
+7. DISCLAIMER OF WARRANTY.\r
+\r
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN &quot;AS IS&quot; BASIS,\r
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,\r
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF\r
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.\r
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE\r
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,\r
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE\r
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER\r
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF\r
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\r
+\r
+8. TERMINATION.\r
+\r
+     8.1.  This License and the rights granted hereunder will terminate\r
+     automatically if You fail to comply with terms herein and fail to cure\r
+     such breach within 30 days of becoming aware of the breach. All\r
+     sublicenses to the Covered Code which are properly granted shall\r
+     survive any termination of this License. Provisions which, by their\r
+     nature, must remain in effect beyond the termination of this License\r
+     shall survive.\r
+\r
+     8.2.  If You initiate litigation by asserting a patent infringement\r
+     claim (excluding declatory judgment actions) against Initial Developer\r
+     or a Contributor (the Initial Developer or Contributor against whom\r
+     You file such action is referred to as &quot;Participant&quot;)  alleging that:\r
+\r
+     (a)  such Participant&apos;s Contributor Version directly or indirectly\r
+     infringes any patent, then any and all rights granted by such\r
+     Participant to You under Sections 2.1 and/or 2.2 of this License\r
+     shall, upon 60 days notice from Participant terminate prospectively,\r
+     unless if within 60 days after receipt of notice You either: (i)\r
+     agree in writing to pay Participant a mutually agreeable reasonable\r
+     royalty for Your past and future use of Modifications made by such\r
+     Participant, or (ii) withdraw Your litigation claim with respect to\r
+     the Contributor Version against such Participant.  If within 60 days\r
+     of notice, a reasonable royalty and payment arrangement are not\r
+     mutually agreed upon in writing by the parties or the litigation claim\r
+     is not withdrawn, the rights granted by Participant to You under\r
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of\r
+     the 60 day notice period specified above.\r
+\r
+     (b)  any software, hardware, or device, other than such Participant&apos;s\r
+     Contributor Version, directly or indirectly infringes any patent, then\r
+     any rights granted to You by such Participant under Sections 2.1(b)\r
+     and 2.2(b) are revoked effective as of the date You first made, used,\r
+     sold, distributed, or had made, Modifications made by that\r
+     Participant.\r
+\r
+     8.3.  If You assert a patent infringement claim against Participant\r
+     alleging that such Participant&apos;s Contributor Version directly or\r
+     indirectly infringes any patent where such claim is resolved (such as\r
+     by license or settlement) prior to the initiation of patent\r
+     infringement litigation, then the reasonable value of the licenses\r
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken\r
+     into account in determining the amount or value of any payment or\r
+     license.\r
+\r
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,\r
+     all end user license agreements (excluding distributors and resellers)\r
+     which have been validly granted by You or any distributor hereunder\r
+     prior to termination shall survive termination.\r
+\r
+9. LIMITATION OF LIABILITY.\r
+\r
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\r
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL\r
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,\r
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR\r
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY\r
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,\r
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER\r
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN\r
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF\r
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY\r
+     RESULTING FROM SUCH PARTY&apos;S NEGLIGENCE TO THE EXTENT APPLICABLE LAW\r
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE\r
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO\r
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.\r
+\r
+10. U.S. GOVERNMENT END USERS.\r
+\r
+     The Covered Code is a &quot;commercial item,&quot; as that term is defined in\r
+     48 C.F.R. 2.101 (Oct. 1995), consisting of &quot;commercial computer\r
+     software&quot; and &quot;commercial computer software documentation,&quot; as such\r
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48\r
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),\r
+     all U.S. Government End Users acquire Covered Code with only those\r
+     rights set forth herein.\r
+\r
+11. MISCELLANEOUS.\r
+\r
+     This License represents the complete agreement concerning subject\r
+     matter hereof. If any provision of this License is held to be\r
+     unenforceable, such provision shall be reformed only to the extent\r
+     necessary to make it enforceable. This License shall be governed by\r
+     California law provisions (except to the extent applicable law, if\r
+     any, provides otherwise), excluding its conflict-of-law provisions.\r
+     With respect to disputes in which at least one party is a citizen of,\r
+     or an entity chartered or registered to do business in the United\r
+     States of America, any litigation relating to this License shall be\r
+     subject to the jurisdiction of the Federal Courts of the Northern\r
+     District of California, with venue lying in Santa Clara County,\r
+     California, with the losing party responsible for costs, including\r
+     without limitation, court costs and reasonable attorneys&apos; fees and\r
+     expenses. The application of the United Nations Convention on\r
+     Contracts for the International Sale of Goods is expressly excluded.\r
+     Any law or regulation which provides that the language of a contract\r
+     shall be construed against the drafter shall not apply to this\r
+     License.\r
+\r
+12. RESPONSIBILITY FOR CLAIMS.\r
+\r
+     As between Initial Developer and the Contributors, each party is\r
+     responsible for claims and damages arising, directly or indirectly,\r
+     out of its utilization of rights under this License and You agree to\r
+     work with Initial Developer and Contributors to distribute such\r
+     responsibility on an equitable basis. Nothing herein is intended or\r
+     shall be deemed to constitute any admission of liability.\r
+\r
+13. MULTIPLE-LICENSED CODE.\r
+\r
+     Initial Developer may designate portions of the Covered Code as\r
+     &quot;Multiple-Licensed&quot;.  &quot;Multiple-Licensed&quot; means that the Initial\r
+     Developer permits you to utilize portions of the Covered Code under\r
+     Your choice of the NPL or the alternative licenses, if any, specified\r
+     by the Initial Developer in the file described in Exhibit A.\r
+\r
+EXHIBIT A -Mozilla Public License.\r
+\r
+     ``The contents of this file are subject to the Mozilla Public License\r
+     Version 1.1 (the &quot;License&quot;); you may not use this file except in\r
+     compliance with the License. You may obtain a copy of the License at\r
+     http://www.mozilla.org/MPL/\r
+\r
+     Software distributed under the License is distributed on an &quot;AS IS&quot;\r
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\r
+     License for the specific language governing rights and limitations\r
+     under the License.\r
+\r
+     The Original Code is ______________________________________.\r
+\r
+     The Initial Developer of the Original Code is ________________________.\r
+     Portions created by ______________________ are Copyright (C) ______\r
+     _______________________. All Rights Reserved.\r
+\r
+     Contributor(s): ______________________________________.\r
+\r
+     Alternatively, the contents of this file may be used under the terms\r
+     of the _____ license (the  &quot;[___] License&quot;), in which case the\r
+     provisions of [______] License are applicable instead of those\r
+     above.  If you wish to allow use of your version of this file only\r
+     under the terms of the [____] License and not to allow others to use\r
+     your version of this file under the MPL, indicate your decision by\r
+     deleting  the provisions above and replace  them with the notice and\r
+     other provisions required by the [___] License.  If you do not delete\r
+     the provisions above, a recipient may use your version of this file\r
+     under either the MPL or the [___] License.&quot;\r
+\r
+     [NOTE: The text of this Exhibit A may differ slightly from the text of\r
+     the notices in the Source Code files of the Original Code. You should\r
+     use the text of this Exhibit A rather than the text found in the\r
+     Original Code Source Code for Your Modifications.]\r
+   </license>\r
+\r
+   <plugin\r
+         id="com.lowagie.text"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.bouncycastle.bcmail-jdk14"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"/>\r
+\r
+   <plugin\r
+         id="org.bouncycastle.bcprov-jdk14"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"/>\r
+\r
+   <plugin\r
+         id="org.bouncycastle.bctsp-jdk14"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"/>\r
+\r
+</feature>\r
diff --git a/features/org.apache.lucene4.feature/.gitignore b/features/org.apache.lucene4.feature/.gitignore
new file mode 100644 (file)
index 0000000..46281dc
--- /dev/null
@@ -0,0 +1 @@
+/target/**\r
diff --git a/features/org.apache.lucene4.feature/.project b/features/org.apache.lucene4.feature/.project
new file mode 100644 (file)
index 0000000..14d6d13
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.apache.lucene4.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/features/org.apache.lucene4.feature/build.properties b/features/org.apache.lucene4.feature/build.properties
new file mode 100644 (file)
index 0000000..82ab19c
--- /dev/null
@@ -0,0 +1 @@
+bin.includes = feature.xml\r
diff --git a/features/org.apache.lucene4.feature/feature.xml b/features/org.apache.lucene4.feature/feature.xml
new file mode 100644 (file)
index 0000000..3dd2c50
--- /dev/null
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<feature\r
+      id="org.apache.lucene4"\r
+      label="Apache Lucene v4"\r
+      version="4.9.0"\r
+      provider-name="The Apache Software Foundation">\r
+\r
+   <description url="http://lucene.apache.org/java/">\r
+      Apache Lucene is a high-performance, full-featured text search engine library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform.\r
+   </description>\r
+\r
+   <copyright url="http://lucene.apache.org/java/">\r
+      Copyright © 2006 The Apache Software Foundation.\r
+   </copyright>\r
+\r
+   <license url="http://www.apache.org/licenses/LICENSE-2.0">\r
+      Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      &quot;License&quot; shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      &quot;Licensor&quot; shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      &quot;Legal Entity&quot; shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      &quot;control&quot; means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      &quot;You&quot; (or &quot;Your&quot;) shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      &quot;Source&quot; form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      &quot;Object&quot; form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      &quot;Work&quot; shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      &quot;Derivative Works&quot; shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      &quot;Contribution&quot; shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, &quot;submitted&quot;\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as &quot;Not a Contribution.&quot;\r
+\r
+      &quot;Contributor&quot; shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a &quot;NOTICE&quot; text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an &quot;AS IS&quot; BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets &quot;[]&quot;\r
+      replaced with your own identifying information. (Don&apos;t include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same &quot;printed page&quot; as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an &quot;AS IS&quot; BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+   </license>\r
+\r
+   <plugin\r
+         id="org.apache.lucene4.core"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.apache.lucene4.queries"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.apache.lucene4.sandbox"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.apache.lucene4.queryparser"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.apache.lucene4.analyzers-common"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+</feature>\r
diff --git a/features/org.simantics.eclipsec.launcher.feature/.project b/features/org.simantics.eclipsec.launcher.feature/.project
new file mode 100644 (file)
index 0000000..31de9e1
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.eclipsec.launcher.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/features/org.simantics.eclipsec.launcher.feature/build.properties b/features/org.simantics.eclipsec.launcher.feature/build.properties
new file mode 100644 (file)
index 0000000..b91d19e
--- /dev/null
@@ -0,0 +1,15 @@
+###############################################################################\r
+# Copyright (c) 2007, 2015 Association for Decentralized Information Management\r
+# in Industry THTH ry.\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Eclipse Public License v1.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.eclipse.org/legal/epl-v10.html\r
+#\r
+# Contributors:\r
+#     VTT Technical Research Centre of Finland - initial API and implementation\r
+#     Semantum Oy - update to Eclipse Mars.1 (4.5.1)\r
+###############################################################################\r
+bin.includes=features.xml\r
+root.win32.win32.x86=bin/win32/win32/x86\r
+root.win32.win32.x86_64=bin/win32/win32/x86_64
\ No newline at end of file
diff --git a/features/org.simantics.eclipsec.launcher.feature/feature.xml b/features/org.simantics.eclipsec.launcher.feature/feature.xml
new file mode 100644 (file)
index 0000000..3c5005e
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--
+    Copyright (c) 2007, 2010 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:
+        VTT Technical Research Centre of Finland - initial API and implementation
+ -->\r
+<feature\r
+      id="org.simantics.eclipsec.launcher"\r
+      label="eclipsec launcher includer"\r
+      version="3.6.200.v20150602-1417"\r
+      provider-name="VTT Technical Research Centre of Finland">\r
+\r
+   <description>\r
+      This is a build-time feature that only includes standard eclipsec launcher executables for platforms where available since the standard org.eclipse.equinox.launcher feature does not include these. The eclipsec executables are valuable for debugging purposes where native code crashes the whole program. With the normal launcher all your possible debug information will be lost forever. Using eclipsec you will see everything put in standard output and standard error in the same very console where you launched eclipsec.\r
+   </description>\r
+\r
+   <copyright url="http://www.example.com/copyright">\r
+      [Enter Copyright Description here.]\r
+   </copyright>\r
+\r
+   <license url="http://www.example.com/license">\r
+      [Enter License Description here.]\r
+   </license>\r
+\r
+</feature>\r
index ed5ed345cf7c7b964612a7716c1eaad263b07cb7..41c08423a25f697be346a3d5d50a45837dc27211 100644 (file)
 \r
    <includes\r
          id="org.simantics.eclipsec.launcher"\r
-         version="0.0.0"\r
-         optional="true"\r
-         os="win32"\r
-         ws="win32,wpf"\r
-         arch="x86,x86_64"/>\r
+         version="0.0.0"/>\r
 \r
    <includes\r
          id="org.simantics.help"\r
index 6352e97154b3a95d50eb4bde670665abc9d03533..87b3ea7af5dbeee97085add6c4109ce5c677f5c3 100644 (file)
@@ -31,7 +31,6 @@
    <requires>\r
       <import feature="org.simantics.layer0" version="1.2.0" match="compatible"/>\r
       <import feature="org.simantics.rcp" version="1.25.0" match="compatible"/>\r
-      <import feature="org.simantics.platform.ui" version="1.25.0" match="compatible"/>\r
    </requires>\r
 \r
    <plugin\r
index daafeeca0e5fd754d890b4764b8185b2b34582ed..9a61e3cc056ed3188f20d65d87f5751c1e8f96fc 100644 (file)
@@ -14,6 +14,8 @@
     </parent>\r
 \r
     <modules>\r
+        <module>com.lowagie.text.feature</module>\r
+        <module>org.apache.lucene4.feature</module>\r
         <module>org.simantics.browsing.ui.feature</module>\r
         <module>org.simantics.charts.feature</module>\r
         <module>org.simantics.data.feature</module>\r
@@ -22,6 +24,7 @@
         <module>org.simantics.document.base.feature</module>\r
         <module>org.simantics.document.linking.feature</module>\r
         <module>org.simantics.document.swt.feature</module>\r
+        <module>org.simantics.eclipsec.launcher.feature</module>\r
         <module>org.simantics.event.feature</module>\r
         <module>org.simantics.export.feature</module>\r
         <module>org.simantics.g2d.feature</module>\r