git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'pure11-0.9' into pure11
commitf8cc12262fef6499ba9b2db40a8871ee00aab2e5 authorAndy Arvanitis <andyarvanitis@gmail.com> dateMon 15 Aug 2016, 21:19 (10 years ago) parent8732859f0e52a5
619 files changed+10258−10511
.gitignore+1 .gitmodules−3 .travis.yml+72−59 CONTRIBUTORS.md+6−3 LICENSE+270−10 appveyor.yml+2−8 appveyor/cache-buster.txt+8 bundle/build-stack.sh → bundle/build.sh+4−2 core-tests/.gitignore+1 core-tests/bower.json+60 core-tests/test-everything.sh+6−52 core-tests/tests/GenericDeriving.purs+30 core-tests/tests/Main.purs+9 core-tests/tests/generic-deriving/Main.purs−27 examples/docs/src/Clash.purs−28 examples/docs/src/Clash1.purs+3 examples/docs/src/Clash1a.purs+9 examples/docs/src/Clash2.purs+3 examples/docs/src/Clash2a.purs+9 examples/docs/src/ImportedTwice.purs+4−18 examples/docs/src/ImportedTwiceA.purs+8 examples/docs/src/ImportedTwiceB.purs+4 examples/docs/src/MultiVirtual.purs−21 examples/docs/src/MultiVirtual1.purs+4 examples/docs/src/MultiVirtual2.purs+9 examples/docs/src/MultiVirtual3.purs+4 examples/docs/src/NewOperators.purs−7 examples/docs/src/NewOperators2.purs+6 examples/docs/src/OldOperators.purs−10 examples/docs/src/TypeClassWithoutMembers.purs+2−8 examples/docs/src/TypeClassWithoutMembersIntermediate.purs+5 examples/failing/1733.purs+1−8 examples/failing/1733/Thingy.purs+4 examples/failing/1825.purs+4−4 examples/failing/1881.purs+6 examples/manual/failing/ArgLengthMismatch.purs → examples/failing/ArgLengthMismatch.purs+7−6 examples/failing/Arrays.purs+2−4 examples/failing/ConflictingExports.purs−10 examples/failing/ConflictingExports/A.purs+4 examples/failing/ConflictingExports/B.purs+4 examples/failing/ConflictingImports.purs+5−15 examples/failing/ConflictingImports/A.purs+4 examples/failing/ConflictingImports/B.purs+4 examples/failing/ConflictingImports2.purs+6−16 examples/failing/ConflictingImports2/A.purs+4 examples/failing/ConflictingImports2/B.purs+4 examples/failing/ConflictingQualifiedImports.purs+3−13 examples/failing/ConflictingQualifiedImports/A.purs+4 examples/failing/ConflictingQualifiedImports/B.purs+4 examples/failing/ConflictingQualifiedImports2.purs+2−12 examples/failing/ConflictingQualifiedImports2/A.purs+4 examples/failing/ConflictingQualifiedImports2/B.purs+4 examples/failing/DeclConflictClassCtor.purs+6 examples/failing/DeclConflictClassSynonym.purs+8 examples/failing/DeclConflictClassType.purs+6 examples/failing/DeclConflictCtorClass.purs+6 examples/failing/DeclConflictCtorCtor.purs+6 examples/failing/DeclConflictSynonymClass.purs+8 examples/failing/DeclConflictSynonymType.purs+8 examples/failing/DeclConflictTypeClass.purs+6 examples/failing/DeclConflictTypeSynonym.purs+8 examples/failing/DeclConflictTypeType.purs+6 examples/failing/Do.purs+2−2 examples/failing/ExportConflictClass.purs+5 examples/failing/ExportConflictClass/A.purs+3 examples/failing/ExportConflictClass/B.purs+3 examples/failing/ExportConflictCtor.purs+5 examples/failing/ExportConflictCtor/A.purs+3 examples/failing/ExportConflictCtor/B.purs+3 examples/failing/ExportConflictType.purs+5 examples/failing/ExportConflictType/A.purs+3 examples/failing/ExportConflictType/B.purs+3 examples/failing/ExportConflictTypeOp.purs+5 examples/failing/ExportConflictTypeOp/A.purs+5 examples/failing/ExportConflictTypeOp/B.purs+5 examples/failing/ExportConflictValue.purs+5 examples/failing/ExportConflictValue/A.purs+4 examples/failing/ExportConflictValue/B.purs+4 examples/failing/ExportConflictValueOp.purs+5 examples/failing/ExportConflictValueOp/A.purs+6 examples/failing/ExportConflictValueOp/B.purs+6 examples/manual/failing/ExportExplicit.purs → examples/failing/ExportExplicit.purs+8−7 examples/failing/ExportExplicit1.purs+12 examples/failing/ExportExplicit1/M1.purs+3 examples/manual/failing/ExportExplicit2.purs → examples/failing/ExportExplicit2.purs+8−7 examples/failing/ExportExplicit3.purs+10 examples/failing/ExportExplicit3/M1.purs+4 examples/failing/ImportExplicit.purs+4 examples/failing/ImportExplicit/M1.purs+3 examples/failing/ImportExplicit2.purs+4 examples/failing/ImportExplicit2/M1.purs+3 examples/failing/ImportHidingModule.purs+4−10 examples/failing/ImportHidingModule/A.purs+2 examples/failing/ImportHidingModule/B.purs+3 examples/failing/ImportModule.purs+4 examples/failing/ImportModule/M2.purs+3 examples/failing/InstanceExport.purs+7−19 examples/failing/InstanceExport/InstanceExport.purs+11 examples/failing/MissingClassMemberExport.purs+1−1 examples/failing/MultipleErrors2.purs+2−2 examples/failing/MultipleTypeOpFixities.purs+9 examples/failing/MultipleValueOpFixities.purs+9 examples/failing/OrphanInstance.purs+7−12 examples/failing/OrphanInstance/Class.purs+4 examples/manual/failing/OrphanTypeDecl.purs → examples/failing/OrphanTypeDecl.purs+4−3 examples/failing/OverlappingReExport.purs−10 examples/failing/ProgrammableTypeErrors.purs+16 examples/manual/failing/RequiredHiddenType.purs → examples/failing/RequiredHiddenType.purs+9−8 examples/failing/RowConstructors1.purs+2−2 examples/failing/RowConstructors2.purs+2−2 examples/failing/RowConstructors3.purs+2−2 examples/failing/SkolemEscape2.purs+1−1 examples/failing/SuggestComposition.purs+1−1 examples/failing/Superclasses5.purs+2−1 examples/failing/TypeError.purs+1−1 examples/failing/TypedBinders.purs+3−3 examples/failing/TypedBinders2.purs+3−3 examples/failing/TypedBinders3.purs+2−1 examples/failing/UnderscoreModuleName.purs+2−2 examples/failing/UnknownType.purs+1−1 examples/manual/QualifiedNames.purs−13 examples/manual/failing/ExportExplicit1.purs−14 examples/manual/failing/ExportExplicit3.purs−13 examples/manual/failing/ImportExplicit.purs−7 examples/manual/failing/ImportExplicit2.purs−7 examples/manual/failing/ImportModule.purs−7 examples/manual/failing/RedefinedFixity.purs−8 examples/manual/passing/ExportExplicit.purs−20 examples/manual/passing/ExportExplicit2.purs−15 examples/manual/passing/Import.purs−19 examples/manual/passing/ImportExplicit.purs−14 examples/manual/passing/ImportQualified.purs−12 examples/manual/passing/Module.purs−28 examples/manual/passing/ModuleDeps.purs−17 examples/manual/passing/RedefinedFixity.purs−24 examples/manual/passing/TransitiveImport.purs−24 examples/passing/1185.purs+3−1 examples/passing/1335.purs+14−12 examples/passing/1570.purs+3−1 examples/passing/1664.purs+1−1 examples/passing/1697.purs+2−1 examples/passing/1881.purs+19 examples/passing/1991.purs+4−2 examples/passing/2018.purs−13 examples/passing/2018/A.purs+7 examples/passing/2018/B.purs+3 examples/passing/2049.purs+14 examples/passing/2138.purs+7 examples/passing/2138/Lib.purs+3 examples/passing/2172.js+5 examples/passing/2172.purs+10 examples/passing/2252.purs+15 examples/passing/652.purs+2−1 examples/passing/810.purs+2−1 examples/passing/Applicative.purs+2−2 examples/passing/ArrayType.purs+2−1 examples/passing/Auto.purs+2−1 examples/passing/AutoPrelude.purs+11−9 examples/passing/AutoPrelude2.purs+1−1 examples/passing/BindersInFunctions.purs+8−3 examples/passing/BindingGroups.purs+2−1 examples/passing/BlockString.purs+2−1 examples/passing/CaseInDo.purs+4−2 examples/passing/CaseMultipleExpressions.purs+4−2 examples/passing/CaseStatement.purs+2−1 examples/passing/CheckFunction.purs+2−1 examples/passing/CheckSynonymBug.purs+2−1 examples/passing/CheckTypeClass.purs+2−2 examples/passing/Church.purs+2−2 examples/passing/ClassRefSyntax.purs+5−9 examples/passing/ClassRefSyntax/Lib.purs+4 examples/passing/Collatz.purs+5−2 examples/passing/Comparisons.purs+15−15 examples/passing/Conditional.purs+2−2 examples/passing/Console.purs+4−2 examples/passing/ConstraintInference.purs+5−2 examples/passing/ContextSimplification.purs+5−3 examples/passing/DataAndType.purs+2−1 examples/passing/DctorOperatorAlias.purs+2−8 examples/passing/DctorOperatorAlias/List.purs+5 examples/passing/DeepArrayBinder.purs+2−1 examples/passing/DeepCase.purs+4−4 examples/passing/Deriving.purs+5−2 examples/passing/Do.purs+3−2 examples/passing/Dollar.purs+5−5 examples/passing/Eff.purs+4−3 examples/passing/EmptyDataDecls.purs+2−1 examples/passing/EmptyRow.purs+2−1 examples/passing/EmptyTypeClass.purs+5−6 examples/passing/EqOrd.purs+4−1 examples/passing/ExplicitImportReExport.purs+11−16 examples/passing/ExplicitImportReExport/Bar.purs+3 examples/passing/ExplicitImportReExport/Foo.purs+4 examples/passing/ExplicitOperatorSections.purs+2−1 examples/passing/ExportExplicit.purs+10 examples/passing/ExportExplicit/M1.purs+10 examples/passing/ExportExplicit2.purs+8 examples/passing/ExportExplicit2/M1.purs+7 examples/manual/passing/ExportedInstanceDeclarations.purs → examples/passing/ExportedInstanceDeclarations.purs+7−5 examples/passing/ExtendedInfixOperators.purs+5−2 examples/passing/Fib.purs+14−11 examples/passing/FieldConsPuns.purs+13−10 examples/passing/FieldPuns.purs+10−8 examples/passing/FinalTagless.purs+4−1 examples/passing/FunctionScope.purs+2−1 examples/passing/Functions.purs+2−5 examples/passing/Functions2.purs+2−1 examples/passing/Generalization1.purs+4−3 examples/passing/Guards.purs+2−1 examples/passing/IfThenElseMaybe.purs+2−1 examples/passing/ImplicitEmptyImport.purs+4−3 examples/passing/Import.purs+6 examples/passing/Import/M1.purs+8 examples/passing/Import/M2.purs+6 examples/passing/ImportExplicit.purs+10 examples/passing/ImportExplicit/M1.purs+4 examples/passing/ImportHiding.purs+3−2 examples/passing/ImportQualified.purs+8 examples/passing/ImportQualified/M1.purs+3 examples/passing/InferRecFunWithConstrainedArgument.purs+4−1 examples/passing/InstanceBeforeClass.purs+2−1 examples/passing/IntAndChar.purs+2−1 examples/passing/JSReserved.purs+2−1 examples/passing/KindedType.purs+2−1 examples/passing/LargeSumType.purs+4−2 examples/passing/Let.purs+14−9 examples/passing/Let2.purs+4−1 examples/passing/LetInInstance.purs+2−1 examples/passing/LiberalTypeSynonyms.purs+4−3 examples/passing/MPTCs.purs+3−2 examples/passing/Match.purs+2−1 examples/passing/Module.purs+7 examples/passing/Module/M1.purs+14 examples/passing/Module/M2.purs+10 examples/passing/ModuleDeps.purs+6 examples/passing/ModuleDeps/M1.purs+5 examples/passing/ModuleDeps/M2.purs+5 examples/passing/ModuleDeps/M3.purs+3 examples/passing/ModuleExport.purs+6−7 examples/passing/ModuleExport/A.purs+3 examples/passing/ModuleExportDupes.purs+3−11 examples/passing/ModuleExportDupes/A.purs+3 examples/passing/ModuleExportDupes/B.purs+3 examples/passing/ModuleExportDupes/C.purs+4 examples/passing/ModuleExportExcluded.purs+8−11 examples/passing/ModuleExportExcluded/A.purs+6 examples/passing/ModuleExportQualified.purs+7−7 examples/passing/ModuleExportQualified/A.purs+3 examples/passing/ModuleExportSelf.purs+8−11 examples/passing/ModuleExportSelf/A.purs+5 examples/passing/Monad.purs+2−2 examples/passing/MonadState.purs+3−1 examples/passing/MultiArgFunctions.purs+3−3 examples/passing/MutRec.purs+2−1 examples/passing/MutRec2.purs+2−1 examples/passing/MutRec3.purs+2−1 examples/passing/NamedPatterns.purs+3−2 examples/passing/NegativeBinder.purs+2−1 examples/passing/NegativeIntInRange.purs+2−1 examples/passing/Nested.purs+2−1 examples/passing/NestedTypeSynonyms.purs+2−1 examples/passing/NestedWhere.purs+2−1 examples/passing/Newtype.purs+5−5 examples/passing/NewtypeWithRecordUpdate.purs+2−2 examples/passing/NonConflictingExports.purs+5−9 examples/passing/NonConflictingExports/A.purs+4 examples/passing/NumberLiterals.purs+39 examples/passing/ObjectGetter.purs+5−4 examples/passing/ObjectSynonym.purs+2−1 examples/passing/ObjectUpdate.purs+23−20 examples/passing/ObjectUpdate2.purs+2−1 examples/passing/ObjectUpdater.purs+3−1 examples/passing/ObjectWildcards.purs+4−4 examples/passing/Objects.purs+3−2 examples/passing/OneConstructor.purs+2−1 examples/passing/OperatorAliasElsewhere.purs−5 examples/passing/OperatorAliasElsewhere/Def.purs+4 examples/passing/OperatorAssociativity.purs+25−25 examples/passing/OperatorInlining.purs+23−22 examples/passing/OperatorSections.purs+11−10 examples/passing/Operators.purs+22−30 examples/passing/Operators/Other.purs+7 examples/passing/OptimizerBug.purs+2−1 examples/passing/OptionalQualified.purs+2−3 examples/passing/OverlappingInstances.purs+17−13 examples/passing/OverlappingInstances2.purs+27−23 examples/passing/OverlappingInstances3.purs+20−16 examples/passing/ParensInTypedBinder.purs+20 examples/passing/PartialFunction.purs+4−3 examples/passing/Patterns.purs+5−4 examples/passing/PendingConflictingImports.purs+5−14 examples/passing/PendingConflictingImports/A.purs+4 examples/passing/PendingConflictingImports/B.purs+4 examples/passing/PendingConflictingImports2.purs+6−10 examples/passing/PendingConflictingImports2/A.purs+4 examples/passing/Person.purs+3−2 examples/passing/PrimedTypeName.purs+20 examples/passing/QualifiedNames.purs+11 examples/passing/QualifiedNames/Either.purs+5 examples/passing/QualifiedQualifiedImports.purs+2−2 examples/passing/Rank2Data.purs+30−29 examples/passing/Rank2Object.purs+1−1 examples/passing/Rank2TypeSynonym.purs+3−2 examples/passing/Rank2Types.purs+2−1 examples/passing/ReExportQualified.purs+4−13 examples/passing/ReExportQualified/A.purs+3 examples/passing/ReExportQualified/B.purs+3 examples/passing/ReExportQualified/C.purs+4 examples/passing/RebindableSyntax.purs+43−39 examples/passing/Recursion.purs+2−1 examples/passing/RedefinedFixity.purs+6 examples/passing/RedefinedFixity/M1.purs+6 examples/passing/RedefinedFixity/M2.purs+5 examples/passing/RedefinedFixity/M3.purs+6 examples/passing/ReservedWords.purs+6−2 examples/passing/ResolvableScopeConflict.purs+9−21 examples/passing/ResolvableScopeConflict/A.purs+4 examples/passing/ResolvableScopeConflict/B.purs+7 examples/passing/ResolvableScopeConflict2.purs+10−17 examples/passing/ResolvableScopeConflict2/A.purs+7 examples/passing/ResolvableScopeConflict3.purs+5−11 examples/passing/ResolvableScopeConflict3/A.purs+4 examples/passing/RowConstructors.purs+3−2 examples/passing/RowPolyInstanceContext.purs+4−3 examples/passing/RuntimeScopeIssue.purs+4−1 examples/passing/ScopedTypeVariables.purs+2−1 examples/passing/Sequence.purs+2−1 examples/passing/SequenceDesugared.purs+5−4 examples/passing/ShadowedModuleName.purs+4−11 examples/passing/ShadowedModuleName/Test.purs+6 examples/manual/passing/ShadowedName.purs → examples/passing/ShadowedName.purs+11−10 examples/passing/ShadowedTCO.purs+21−18 examples/passing/ShadowedTCOLet.purs+15−9 examples/passing/SignedNumericLiterals.purs+2−1 examples/passing/StringEscapes.purs+17−15 examples/passing/Superclasses1.purs+4−1 examples/passing/Superclasses3.purs+1−1 examples/passing/TCO.purs+7−7 examples/passing/TCOCase.purs+2−1 examples/passing/TailCall.purs+4−1 examples/passing/Tick.purs+2−1 examples/passing/TopLevelCase.purs+2−1 examples/passing/TransitiveImport.purs+9 examples/passing/TransitiveImport/Middle.purs+5 examples/passing/TransitiveImport/Test.purs+9 examples/passing/TypeClassMemberOrderChange.purs+16−13 examples/passing/TypeClasses.purs+11−9 examples/passing/TypeClassesInOrder.purs+2−1 examples/passing/TypeClassesWithOverlappingTypeVariables.purs+3−2 examples/passing/TypeDecl.purs+2−1 examples/passing/TypeOperators.purs+13−27 examples/passing/TypeOperators/A.purs+22 examples/passing/TypeSynonymInData.purs+2−1 examples/passing/TypeSynonyms.purs+2−1 examples/passing/TypeWildcards.purs+2−1 examples/passing/TypeWildcardsRecordExtension.purs+2−1 examples/passing/TypeWithoutParens.purs+7−11 examples/passing/TypeWithoutParens/Lib.purs+4 examples/passing/TypedBinders.purs+8−7 examples/passing/TypedWhere.purs+2−1 examples/passing/UTF8Sourcefile.purs+8−10 examples/passing/UnderscoreIdent.purs+3−1 examples/passing/UnicodeIdentifier.purs+3−1 examples/passing/UnicodeOperators.purs+3−1 examples/passing/UnicodeType.purs+8−9 examples/passing/Unit.purs+4−2 examples/passing/UnknownInTypeClassLookup.purs+2−1 examples/passing/UntupledConstraints.purs+1−1 examples/passing/Where.purs+11−11 examples/manual/passing/WildcardType.purs → examples/passing/WildcardType.purs+12−13 examples/passing/iota.purs+3−1 examples/passing/s.purs+2−1 examples/warning/DuplicateExportRef.purs+30 examples/warning/DuplicateImport.purs+10 examples/warning/DuplicateImportRef.purs+18 examples/warning/DuplicateSelectiveImport.purs+10 examples/warning/HidingImport.purs+9 examples/warning/ImplicitImport.purs+9 examples/warning/ImplicitQualifiedImport.purs+11 examples/warning/MissingTypeDeclaration.purs+4 examples/warning/OverlappingInstances.purs+17 examples/warning/OverlappingPattern.purs+15 examples/warning/ScopeShadowing.purs+13 examples/warning/ShadowedTypeVar.purs+5 examples/warning/UnnecessaryFFIModule.js+1 examples/warning/UnnecessaryFFIModule.purs+5 examples/warning/UnusedDctorExplicitImport.purs+8 examples/warning/UnusedDctorImportAll.purs+7 examples/warning/UnusedDctorImportExplicit.purs+7 examples/warning/UnusedExplicitImport.purs+8 examples/warning/UnusedFFIImplementations.js+2 examples/warning/UnusedFFIImplementations.purs+4 examples/warning/UnusedImport.purs+14 examples/warning/UnusedTypeVar.purs+5 examples/warning/WildcardInferredType.purs+23 hierarchy/Main.hs+2−3 pcc/Main.hs+86−75 pcc/Make.hs+4−7 pcc/Makefile+1−1 pcc/Makefile.hs+1−1 pcc/TestMain.hs+15−8 pcc/include/purescript.cc+2−2 pcc/include/purescript.hh+14−29 psc-bundle/Main.hs+2−20 psc-docs/Main.hs+1−1 psc-ide-client/Main.hs+6−16 psc-ide-server/Main.hs+39−56 psc-ide-server/PROTOCOL.md+52−25 psc-ide-server/README.md+5−1 psc/Main.hs+27−53 psci/Main.hs+364 psci/PSCi.hs−372 psci/PSCi/Message.hs−53 psci/PSCi/Module.hs−107 psci/PSCi/Option.hs−57 psci/PSCi/Types.hs−218 psci/main/Main.hs−6 psci/static/index.html+10 psci/static/index.js+63 purescript.cabal+280−126 src/Control/Monad/Logger.hs+7−20 src/Control/Monad/Supply.hs+5−18 src/Control/Monad/Supply/Class.hs+6−6 src/Language/PureScript.hs+5−17 src/Language/PureScript/AST/Binders.hs+4−2 src/Language/PureScript/AST/Declarations.hs+227−92 src/Language/PureScript/AST/Exported.hs+12−15 src/Language/PureScript/AST/Literals.hs+3−3 src/Language/PureScript/AST/Operators.hs+4−2 src/Language/PureScript/AST/SourcePos.hs+2−5 src/Language/PureScript/AST/Traversals.hs+8−25 src/Language/PureScript/Bundle.hs+72−56 src/Language/PureScript/CodeGen.hs+8−20 src/Language/PureScript/CodeGen/Cpp.hs+17−18 src/Language/PureScript/CodeGen/Cpp/AST.hs+22−21 src/Language/PureScript/CodeGen/Cpp/Common.hs+4−2 src/Language/PureScript/CodeGen/Cpp/File.hs+16−6 src/Language/PureScript/CodeGen/Cpp/Optimizer.hs+3−1 src/Language/PureScript/CodeGen/Cpp/Optimizer/Blocks.hs+12−10 src/Language/PureScript/CodeGen/Cpp/Optimizer/Common.hs+16 src/Language/PureScript/CodeGen/Cpp/Optimizer/Inliner.hs+197−142 src/Language/PureScript/CodeGen/Cpp/Optimizer/MagicDo.hs+77−42 src/Language/PureScript/CodeGen/Cpp/Optimizer/TCO.hs+2 src/Language/PureScript/CodeGen/Cpp/Optimizer/Unused.hs+2 src/Language/PureScript/CodeGen/Cpp/Types.hs+12−1 src/Language/PureScript/CodeGen/JS.hs+20−23 src/Language/PureScript/CodeGen/JS/AST.hs+4−5 src/Language/PureScript/CodeGen/JS/Common.hs+3−2 src/Language/PureScript/CodeGen/JS/Optimizer.hs+7−11 src/Language/PureScript/CodeGen/JS/Optimizer/Blocks.hs+2−12 src/Language/PureScript/CodeGen/JS/Optimizer/Common.hs+6−5 src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+105−108 src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+4−2 src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+2−12 src/Language/PureScript/CodeGen/JS/Optimizer/Unused.hs+2−13 src/Language/PureScript/Comments.hs+3−1 src/Language/PureScript/Constants.hs+33−8 src/Language/PureScript/CoreFn.hs+1−1 src/Language/PureScript/CoreFn/Ann.hs+25−37 src/Language/PureScript/CoreFn/Binders.hs+3−3 src/Language/PureScript/CoreFn/Desugar.hs+17−25 src/Language/PureScript/CoreFn/Expr.hs+6−6 src/Language/PureScript/CoreFn/Meta.hs+4−2 src/Language/PureScript/CoreFn/Module.hs+6−15 src/Language/PureScript/CoreFn/Traversals.hs+3−1 src/Language/PureScript/Crash.hs+11−9 src/Language/PureScript/Docs.hs+4−4 src/Language/PureScript/Docs/AsMarkdown.hs+18−24 src/Language/PureScript/Docs/Convert.hs+12−14 src/Language/PureScript/Docs/Convert/ReExports.hs+81−67 src/Language/PureScript/Docs/Convert/Single.hs+16−52 src/Language/PureScript/Docs/ParseAndBookmark.hs+7−11 src/Language/PureScript/Docs/Render.hs+26−19 src/Language/PureScript/Docs/RenderedCode.hs+8−11 src/Language/PureScript/Docs/RenderedCode/Render.hs+29−28 src/Language/PureScript/Docs/RenderedCode/Types.hs+3−3 src/Language/PureScript/Docs/Types.hs+24−26 src/Language/PureScript/Environment.hs+28−24 src/Language/PureScript/Errors.hs+410−554 src/Language/PureScript/Errors/JSON.hs+15−22 src/Language/PureScript/Externs.hs+45−27 src/Language/PureScript/Ide.hs+134−183 src/Language/PureScript/Ide/CaseSplit.hs+24−36 src/Language/PureScript/Ide/Command.hs+62−72 src/Language/PureScript/Ide/Completion.hs+17−17 src/Language/PureScript/Ide/Conversions.hs+35 src/Language/PureScript/Ide/Error.hs+8−11 src/Language/PureScript/Ide/Externs.hs+81−72 src/Language/PureScript/Ide/Filter.hs+17−51 src/Language/PureScript/Ide/Imports.hs+44−67 src/Language/PureScript/Ide/Matcher.hs+26−33 src/Language/PureScript/Ide/Pursuit.hs+10−14 src/Language/PureScript/Ide/Rebuild.hs+124−45 src/Language/PureScript/Ide/Reexports.hs+93−66 src/Language/PureScript/Ide/SourceFile.hs+72−90 src/Language/PureScript/Ide/State.hs+186−71 src/Language/PureScript/Ide/Types.hs+98−76 src/Language/PureScript/Ide/Util.hs+64−34 src/Language/PureScript/Ide/Watcher.hs+25−31 src/Language/PureScript/Interactive.hs+289 psci/PSCi/Completion.hs → src/Language/PureScript/Interactive/Completion.hs+77−81 psci/PSCi/Directive.hs → src/Language/PureScript/Interactive/Directive.hs+2−21 psci/PSCi/IO.hs → src/Language/PureScript/Interactive/IO.hs+4−31 src/Language/PureScript/Interactive/Message.hs+52 src/Language/PureScript/Interactive/Module.hs+99 psci/PSCi/Parser.hs → src/Language/PureScript/Interactive/Parser.hs+9−27 psci/PSCi/Printer.hs → src/Language/PureScript/Interactive/Printer.hs+16−20 src/Language/PureScript/Interactive/Types.hs+145 src/Language/PureScript/Kinds.hs+9−20 src/Language/PureScript/Linter.hs+6−23 src/Language/PureScript/Linter/Exhaustive.hs+110−79 src/Language/PureScript/Linter/Imports.hs+172−152 src/Language/PureScript/Make.hs+79−84 src/Language/PureScript/ModuleDependencies.hs+16−12 src/Language/PureScript/Names.hs+82−20 src/Language/PureScript/Options.hs+3−16 src/Language/PureScript/Parser.hs+23−36 src/Language/PureScript/Parser/Common.hs+29−7 src/Language/PureScript/Parser/Declarations.hs+116−112 src/Language/PureScript/Parser/JS.hs−60 src/Language/PureScript/Parser/Kinds.hs+6−16 src/Language/PureScript/Parser/Lexer.hs+42−36 src/Language/PureScript/Parser/State.hs+2−14 src/Language/PureScript/Parser/Types.hs+25−15 src/Language/PureScript/Pretty.hs+2−14 src/Language/PureScript/Pretty/Common.hs+9−17 src/Language/PureScript/Pretty/Cpp.hs+22−18 src/Language/PureScript/Pretty/JS.hs+10−25 src/Language/PureScript/Pretty/Kinds.hs+11−18 src/Language/PureScript/Pretty/Types.hs+22−13 src/Language/PureScript/Pretty/Values.hs+13−14 src/Language/PureScript/Publish.hs+28−26 src/Language/PureScript/Publish/BoxesHelpers.hs+3 src/Language/PureScript/Publish/ErrorsWarnings.hs+31−27 src/Language/PureScript/Publish/Utils.hs+41−38 src/Language/PureScript/Renamer.hs−6 src/Language/PureScript/Sugar.hs+16−27 src/Language/PureScript/Sugar/BindingGroups.hs+19−25 src/Language/PureScript/Sugar/CaseDeclarations.hs+18−21 src/Language/PureScript/Sugar/DoNotation.hs+14−16 src/Language/PureScript/Sugar/Names.hs+115−190 src/Language/PureScript/Sugar/Names/Common.hs+68 src/Language/PureScript/Sugar/Names/Env.hs+209−88 src/Language/PureScript/Sugar/Names/Exports.hs+157−156 src/Language/PureScript/Sugar/Names/Imports.hs+91−180 src/Language/PureScript/Sugar/ObjectWildcards.hs+7−10 src/Language/PureScript/Sugar/Operators.hs+211−128 src/Language/PureScript/Sugar/Operators/Binders.hs+4−5 src/Language/PureScript/Sugar/Operators/Common.hs+11−16 src/Language/PureScript/Sugar/Operators/Expr.hs+6−10 src/Language/PureScript/Sugar/Operators/Types.hs+4−5 src/Language/PureScript/Sugar/TypeClasses.hs+12−17 src/Language/PureScript/Sugar/TypeClasses/Deriving.hs+38−35 src/Language/PureScript/Sugar/TypeDeclarations.hs+28−38 src/Language/PureScript/Traversals.hs+27−42 src/Language/PureScript/TypeChecker.hs+67−116 src/Language/PureScript/TypeChecker/Entailment.hs+38−37 src/Language/PureScript/TypeChecker/Kinds.hs+10−14 src/Language/PureScript/TypeChecker/Monad.hs+72−35 src/Language/PureScript/TypeChecker/Rows.hs+8−27 src/Language/PureScript/TypeChecker/Skolems.hs+15−30 src/Language/PureScript/TypeChecker/Subsumption.hs+12−27 src/Language/PureScript/TypeChecker/Synonyms.hs+8−24 src/Language/PureScript/TypeChecker/Types.hs+90−96 src/Language/PureScript/TypeChecker/Unify.hs+38−50 src/Language/PureScript/TypeClassDictionaries.hs+4−2 src/Language/PureScript/Types.hs+63−76 src/System/IO/UTF8.hs+2−2 stack-ghc-8.0.yaml+7 stack-lts-5.yaml−7 stack-nightly.yaml−6 stack.yaml+9−1 tests/Language/PureScript/Ide/FilterSpec.hs+21−32 tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+17−35 tests/Language/PureScript/Ide/ImportsSpec.hs+13−8 tests/Language/PureScript/Ide/Integration.hs+113−80 tests/Language/PureScript/Ide/MatcherSpec.hs+18−27 tests/Language/PureScript/Ide/RebuildSpec.hs+18−23 tests/Language/PureScript/Ide/ReexportsSpec.hs+54−68 tests/Language/PureScript/Ide/SourceFile/IntegrationSpec.hs+36 tests/Language/PureScript/Ide/SourceFileSpec.hs+46 tests/Language/PureScript/IdeSpec.hs−35 tests/Main.hs+4−1 tests/TestCompiler.hs+187−95 tests/TestDocs.hs+3−8 tests/TestPscIde.hs+9−2 tests/TestPscPublish.hs+2−2 tests/TestPsci.hs+24−46 tests/TestUtils.hs+53−19 tests/support/bower.json+7−6 tests/support/flattened/Control-Monad-Eff-Class.purs−24 tests/support/flattened/Control-Monad-Eff-Console.js−18 tests/support/flattened/Control-Monad-Eff-Console.purs−18 tests/support/flattened/Control-Monad-Eff-Unsafe.js−8 tests/support/flattened/Control-Monad-Eff-Unsafe.purs−10 tests/support/flattened/Control-Monad-Eff.js−62 tests/support/flattened/Control-Monad-Eff.purs−67 tests/support/flattened/Control-Monad-ST.js−38 tests/support/flattened/Control-Monad-ST.purs−42 tests/support/flattened/Data-Function.js−233 tests/support/flattened/Data-Function.purs−113 tests/support/flattened/Prelude.js−228 tests/support/flattened/Prelude.purs−872 tests/support/flattened/Test-Assert.js−27 tests/support/flattened/Test-Assert.purs−46 tests/support/package.json+2−1 tests/support/prelude−1 tests/support/pscide/src/ImportsSpec.purs+1−3 tests/support/pscide/src/Main.purs → tests/support/pscide/src/MatcherSpec.purs+1−1 tests/support/pscide/src/RebuildSpecSingleModule.purs+1−1 tests/support/pscide/src/RebuildSpecWithForeign.js−2 tests/support/pscide/src/RebuildSpecWithHiddenIdent.purs+6 tests/support/pscide/src/SourceFileSpec.purs+10 tests/support/setup.js−22 travis/after.sh−13 travis/build.sh+59 travis/configure.sh−17 travis/convert-os-name.sh+14 travis/test-install.sh−18
.gitignore+1
@@ -17,3 +17,4 @@ tmp/
1717output
1818examples/docs/docs/
1919core-tests/full-core-docs.md
20+.psc-ide-port
.gitmodulesdeleted−3
@@ -1,3 +0,0 @@
1−[submodule "tests/support/prelude"]
2− path = tests/support/prelude
3− url = https://github.com/purescript/purescript-prelude
.travis.yml+72−59
@@ -1,73 +1,86 @@
11language: c
2−dist: trusty
2+dist: trusty # because of perf issues
33sudo: required
44matrix:
55 include:
6− - env: GHCVER=7.10.3 CABALVER=1.22 STACKAGE=lts-5.4 RUNSDISTTESTS=YES
7− compiler: ": #GHC 7.10.3 lts-5.4"
8− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
9− - env: GHCVER=7.10.3 CABALVER=1.22 STACKAGE=nightly-2016-02-25
10− compiler: ": #GHC 7.10.3 nightly-2016-02-25"
11− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
12− - env: GHCVER=7.10.3 CABALVER=1.22 DEPLOY=yes
13− compiler: ": #GHC 7.10.3"
14− addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.4], sources: [hvr-ghc]}}
15−before_install:
16− - unset CC
17− - export PATH="/opt/ghc/$GHCVER/bin:$PATH"
18− - export PATH="/opt/cabal/$CABALVER/bin:$PATH"
19− - export PATH="$HOME/.cabal/bin:$PATH"
20− - export PATH="/opt/happy/1.19.5/bin:/$PATH"
21− - export PATH="/opt/alex/3.1.4/bin:/$PATH"
22− - export PATH="$HOME/build/purescript/purescript/dist/build/psc:/$PATH"
23− - export PATH="$HOME/build/purescript/purescript/dist/build/psc-ide-server:/$PATH"
24− - export PATH="$HOME/build/purescript/purescript/dist/build/psc-ide-client:/$PATH"
6+ # The 'compiler' key is a hack to get Travis to use different caches for
7+ # each job in a build, in order to avoid the separate jobs stomping on each
8+ # other's caches. See https://github.com/travis-ci/travis-ci/issues/4393
9+ #
10+ # We use trusty boxes because they seem to be a bit faster.
11+ - compiler: cc-linux-lts-normal
12+ os: linux
13+ dist: trusty
14+ sudo: required
15+ env: BUILD_TYPE=normal DEPLOY=true
16+
17+ # - compiler: cc-linux-nightly-normal
18+ # os: linux
19+ # dist: trusty
20+ # sudo: required
21+ # env: BUILD_TYPE=normal STACKAGE_NIGHTLY=true
22+ # allow_failures: true
23+
24+ - compiler: cc-linux-ghc8.0-normal
25+ os: linux
26+ dist: trusty
27+ sudo: required
28+ env: BUILD_TYPE=normal STACK_YAML=stack-ghc-8.0.yaml
29+
30+ - compiler: cc-linux-lts-sdist
31+ os: linux
32+ dist: trusty
33+ sudo: required
34+ env: BUILD_TYPE=sdist COVERAGE=true
35+
36+ - compiler: cc-linux-lts-haddock
37+ os: linux
38+ dist: trusty
39+ sudo: required
40+ env: BUILD_TYPE=haddock
41+
42+ - compiler: cc-osx-lts-normal
43+ os: osx
44+ env: BUILD_TYPE=normal DEPLOY=true
45+
46+ - compiler: cc-osx-lts-sdist
47+ os: osx
48+ env: BUILD_TYPE=sdist
49+addons:
50+ apt:
51+ packages:
52+ - libgmp-dev
53+cache:
54+ directories:
55+ - $HOME/.local/bin
56+ - $HOME/.stack
2557install:
26− - cabal --version
27− - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
28− - travis_retry cabal update
29− # Run sequentially
30− # Travis container infrastructure seems to expose all host CPUs (16?), thus
31− # cabal and ghc tries to use them all. Which is bad idea on a shared box.
32− # See also: https://ghc.haskell.org/trac/ghc/ticket/9221
33− - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
34− # Cache sandboxes in ~/cabal-sandboxes
35− # Move right sandbox to .cabal-sandbox if exists
36− - if [ -d ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none} ]; then
37− mv ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none} .cabal-sandbox;
38− fi
39− - mkdir -p .cabal-sandbox
40− - cabal sandbox init --sandbox .cabal-sandbox
41− # Download stackage cabal.config. Filter this package and 'extra deps'
42− - if [ -n "$STACKAGE" ]; then curl https://www.stackage.org/$STACKAGE/cabal.config | egrep -v 'purescript|language-javascript|bower-json' > cabal.config; fi
43− - cabal install --only-dependencies --enable-tests
44− - cabal install hpc-coveralls
45− # Snapshot state of the sandbox now, so we don't need to make new one for test install
46− - rm -rf ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none}
47− - cp -r .cabal-sandbox ~/cabal-sandboxes/$GHCVER-${STACKAGE:-none}
48− # Install bower globally (for psc-docs/psc-publish tests)
49− - npm install -g bower
58+- | # Install stack.
59+ if test ! -f "$HOME/.local/bin/stack"
60+ then
61+ URL="https://www.stackage.org/stack/$TRAVIS_OS_NAME-x86_64"
62+ curl --location "$URL" > stack.tar.gz
63+ gunzip stack.tar.gz
64+ tar -x -f stack.tar --strip-components 1
65+ mkdir -p "$HOME/.local/bin"
66+ mv stack "$HOME/.local/bin/"
67+ fi
68+- npm install -g bower # for psc-docs / psc-publish tests
69+# Fix the CC environment variable, because Travis changes it
70+- export CC=gcc
71+- export OS_NAME=$(./travis/convert-os-name.sh)
5072script:
51− - ./travis/configure.sh
52− - cabal build --ghc-options="-Werror"
53− - cabal test
54− - ./travis/test-install.sh
55−after_script:
56− - ./travis/after.sh
57−notifications:
58− email: true
59−before_deploy: "./bundle/build.sh linux64"
73+- travis/build.sh
74+before_deploy:
75+- ./bundle/build.sh $OS_NAME
6076deploy:
6177 provider: releases
6278 api_key: $RELEASE_KEY
6379 file:
64− - bundle/linux64.tar.gz
65− - bundle/linux64.sha
80+ - bundle/$OS_NAME.tar.gz
81+ - bundle/$OS_NAME.sha
6682 skip_cleanup: true
6783 on:
6884 all_branches: true
6985 tags: true
70− condition: "$DEPLOY = yes"
71−cache:
72− directories:
73− - ~/cabal-sandboxes
86+ condition: "$DEPLOY = true"
CONTRIBUTORS.md+6−3
@@ -12,7 +12,9 @@ This file lists the contributors to the PureScript compiler project, and the ter
1212- [@bagl](https://github.com/bagl) (Petr Vapenka) My existing contributions and all future contributions until further notice are Copyright Petr Vapenka, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
1313- [@balajirrao](https://github.com/balajirrao) (Balaji Rao) - My existing contributions and all future contributions until further notice are Copyright Balaji Rao, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
1414- [@bergmark](https://github.com/bergmark) (Adam Bergmark) - My existing contributions and all future contributions until further notice are Copyright Adam Bergmark, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
15+- [@bmjames](https://github.com/bmjames) (Ben James) My existing contributions and all future contributions until further notice are Copyright Ben James, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
1516- [@Bogdanp](https://github.com/Bogdanp) (Bogdan Paul Popa) My existing contributions and all future contributions until further notice are Copyright Bogdan Paul Popa, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
17+- [@bsermons](https://github.com/bsermons) (Brian Sermons) My existing contributions and all future contributions until further notice are Copyright Brian Sermons, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
1618- [@cdepillabout](https://github.com/cdepillabout) (Dennis Gosnell) My existing contributions and all future contributions until further notice are Copyright Dennis Gosnell, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
1719- [@chrissmoak](https://github.com/chrissmoak) (Chris Smoak) My existing contributions to the PureScript compiler and all future contributions to the PureScript compiler until further notice, are Copyright Chris Smoak, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
1820- [@codedmart](https://github.com/codedmart) (Brandon Martin) My existing contributions and all future contributions until further notice are Copyright Brandon Martin, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -25,8 +27,10 @@ This file lists the contributors to the PureScript compiler project, and the ter
2527- [@erdeszt](https://github.com/erdeszt) (Tibor Erdesz) My existing contributions and all future contributions until further notice are Copyright Tibor Erdesz, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
2628- [@etrepum](https://github.com/etrepum) (Bob Ippolito) My existing contributions and all future contributions until further notice are Copyright Bob Ippolito, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
2729- [@faineance](https://github.com/faineance) My existing contributions and all future contributions until further notice are Copyright faineance, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
30+- [@felixSchl](https://github.com/felixSchl) (Felix Schlitter) My existing contributions and all future contributions until further notice are Copyright Felix Schlitter, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
2831- [@garyb](https://github.com/garyb) (Gary Burgess) My existing contributions and all future contributions until further notice are Copyright Gary Burgess, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
2932- [@hdgarrood](https://github.com/hdgarrood) (Harry Garrood) My existing contributions and all future contributions until further notice are Copyright Harry Garrood, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
33+- [@ilovezfs](https://github.com/ilovezfs) - My existing contributions and all future contributions until further notice are Copyright ilovezfs, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license
3034- [@izgzhen](https://github.com/izgzhen) (Zhen Zhang) My existing contributions and all future contributions until further notice are Copyright Zhen Zhang, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
3135- [@jacereda](https://github.com/jacereda) (Jorge Acereda) My existing contributions and all future contributions until further notice are Copyright Jorge Acereda, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
3236- [@japesinator](https://github.com/japesinator) (JP Smith) My existing contributions and all future contributions until further notice are Copyright JP Smith, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -35,6 +39,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
3539- [@kRITZCREEK](https://github.com/kRITZCREEK) (Christoph Hegemann) - My existing contributions and all future contributions until further notice are Copyright Christoph Hegemann, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
3640- [@L8D](https://github.com/L8D) (Tenor Biel) My existing contributions and all future contributions until further notice are Copyright Tenor Biel, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
3741- [@leighman](http://github.com/leighman) (Jack Leigh) My existing contributions and all future contributions until further notice are Copyright Jack Leigh, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
42+- [@LiamGoodacre](https://github.com/LiamGoodacre) (Liam Goodacre) My existing contributions and all future contributions until further notice are Copyright Liam Goodacre, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
3843- [@lukerandall](https://github.com/lukerandall) (Luke Randall) My existing contributions and all future contributions until further notice are Copyright Luke Randall, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
3944- [@mgmeier](https://github.com/mgmeier) (Michael Karg) My existing contributions and all future contributions until further notice are Copyright Michael Gilliland, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
4045- [@michaelficarra](https://github.com/michaelficarra) (Michael Ficarra) My existing contributions and all future contributions until further notice are Copyright Michael Ficarra, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -58,6 +63,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
5863- [@puffnfresh](https://github.com/puffnfresh) (Brian McKenna) All contributions I made during June 2015 were during employment at [SlamData, Inc.](#companies) who owns the copyright. I assign copyright of all my personal contributions before June 2015 to the owners of the PureScript compiler.
5964- [@robdaemon](https://github.com/robdaemon) (Robert Roland) My existing contributions and all future contributions until further notice are Copyright Robert Roland, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
6065- [@RossMeikleham](https://github.com/RossMeikleham) (Ross Meikleham) My existing contributions and all future contributions until further notice are Copyright Ross Meikleham, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
66+- [@rvion](https://github.com/rvion) (Rémi Vion) My existing contributions and all future contributions until further notice are Copyright Rémi Vion, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
6167- [@sebastiaanvisser](https://github.com/sebastiaanvisser) (Sebastiaan Visser) - My existing contributions and all future contributions until further notice are Copyright Sebastiaan Visser, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
6268- [@senju](https://github.com/senju) - My existing contributions and all future contributions until further notice are Copyright senju, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
6369- [@sharkdp](https://github.com/sharkdp) (David Peter) My existing contributions and all future contributions until further notice are Copyright David Peter, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -69,9 +75,6 @@ This file lists the contributors to the PureScript compiler project, and the ter
6975- [@utkarshkukreti](https://github.com/utkarshkukreti) (Utkarsh Kukreti) My existing contributions and all future contributions until further notice are Copyright Utkarsh Kukreti, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
7076- [@vkorablin](https://github.com/vkorablin) (Vladimir Korablin) - My existing contributions and all future contributions until further notice are Copyright Vladimir Korablin, and are licensed to the owners and users of the PureScript compiler project under the terms of the MIT license.
7177- [@zudov](https://github.com/zudov) (Konstantin Zudov) My existing contributions and all future contributions until further notice are Copyright Konstantin Zudov, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
72−- [@LiamGoodacre](https://github.com/LiamGoodacre) (Liam Goodacre) My existing contributions and all future contributions until further notice are Copyright Liam Goodacre, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
73−- [@bsermons](https://github.com/bsermons) (Brian Sermons) My existing contributions and all future contributions until further notice are Copyright Brian Sermons, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
74−- [@bmjames](https://github.com/bmjames) (Ben James) My existing contributions and all future contributions until further notice are Copyright Ben James, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
7578
7679### Companies
7780
LICENSE+270−10
@@ -46,6 +46,7 @@ PureScript uses the following Haskell library packages. Their license files foll
4646 bytestring-builder
4747 case-insensitive
4848 cereal
49+ clock
4950 conduit
5051 conduit-extra
5152 connection
@@ -56,8 +57,10 @@ PureScript uses the following Haskell library packages. Their license files foll
5657 deepseq
5758 directory
5859 dlist
60+ easy-file
5961 edit-distance
6062 exceptions
63+ fail
6164 fast-logger
6265 filepath
6366 fsnotify
@@ -82,6 +85,7 @@ PureScript uses the following Haskell library packages. Their license files foll
8285 network
8386 network-uri
8487 old-locale
88+ old-time
8589 optparse-applicative
8690 parallel
8791 parsec
@@ -91,6 +95,7 @@ PureScript uses the following Haskell library packages. Their license files foll
9195 pipes-http
9296 primitive
9397 process
98+ protolude
9499 random
95100 regex-base
96101 regex-tdfa
@@ -105,6 +110,7 @@ PureScript uses the following Haskell library packages. Their license files foll
105110 stm
106111 stm-chans
107112 streaming-commons
113+ string-conv
108114 syb
109115 tagged
110116 template-haskell
@@ -117,6 +123,7 @@ PureScript uses the following Haskell library packages. Their license files foll
117123 transformers-compat
118124 unix
119125 unix-compat
126+ unix-time
120127 unordered-containers
121128 utf8-string
122129 vector
@@ -955,6 +962,41 @@ cereal LICENSE file:
955962 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
956963 POSSIBILITY OF SUCH DAMAGE.
957964
965+clock LICENSE file:
966+
967+ Copyright (c) 2009-2012, Cetin Sert
968+ Copyright (c) 2010, Eugene Kirpichov
969+
970+ All rights reserved.
971+
972+ Redistribution and use in source and binary forms, with or without
973+ modification, are permitted provided that the following conditions are
974+ met:
975+
976+ * Redistributions of source code must retain the above copyright
977+ notice, this list of conditions and the following disclaimer.
978+
979+ * Redistributions in binary form must reproduce the above
980+ copyright notice, this list of conditions and the following
981+ disclaimer in the documentation and/or other materials provided
982+ with the distribution.
983+
984+ * The names of contributors may not be used to endorse or promote
985+ products derived from this software without specific prior
986+ written permission.
987+
988+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
989+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
990+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
991+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
992+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
993+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
994+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
995+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
996+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
997+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
998+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
999+
9581000conduit LICENSE file:
9591001
9601002 Copyright (c) 2012 Michael Snoyman, http://www.yesodweb.com/
@@ -1142,16 +1184,16 @@ data-default-class LICENSE file:
11421184 may be used to endorse or promote products derived from this software
11431185 without specific prior written permission.
11441186
1145− THIS SOFTWARE IS PROVIDED BY LUKAS MAI AND CONTRIBUTORS "AS IS" AND ANY
1146− EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1187+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1188+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11471189 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1148− DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
1149− DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1150− (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1151− LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1152− ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1153− (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1154− SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1190+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
1191+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1192+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1193+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1194+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1195+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1196+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11551197
11561198deepseq LICENSE file:
11571199
@@ -1295,6 +1337,38 @@ dlist LICENSE file:
12951337 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
12961338 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12971339
1340+easy-file LICENSE file:
1341+
1342+ Copyright (c) 2009, IIJ Innovation Institute Inc.
1343+ All rights reserved.
1344+
1345+ Redistribution and use in source and binary forms, with or without
1346+ modification, are permitted provided that the following conditions
1347+ are met:
1348+
1349+ * Redistributions of source code must retain the above copyright
1350+ notice, this list of conditions and the following disclaimer.
1351+ * Redistributions in binary form must reproduce the above copyright
1352+ notice, this list of conditions and the following disclaimer in
1353+ the documentation and/or other materials provided with the
1354+ distribution.
1355+ * Neither the name of the copyright holders nor the names of its
1356+ contributors may be used to endorse or promote products derived
1357+ from this software without specific prior written permission.
1358+
1359+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1360+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1361+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1362+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1363+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
1364+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1365+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1366+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1367+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1368+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
1369+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1370+ POSSIBILITY OF SUCH DAMAGE.
1371+
12981372edit-distance LICENSE file:
12991373
13001374 Copyright (c) 2008-2013 Maximilian Bolingbroke
@@ -1354,6 +1428,39 @@ exceptions LICENSE file:
13541428 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
13551429 POSSIBILITY OF SUCH DAMAGE.
13561430
1431+fail LICENSE file:
1432+
1433+ Copyright (c) 2015, David Luposchainsky & Herbert Valerio Riedel
1434+
1435+ All rights reserved.
1436+
1437+ Redistribution and use in source and binary forms, with or without
1438+ modification, are permitted provided that the following conditions are met:
1439+
1440+ * Redistributions of source code must retain the above copyright
1441+ notice, this list of conditions and the following disclaimer.
1442+
1443+ * Redistributions in binary form must reproduce the above
1444+ copyright notice, this list of conditions and the following
1445+ disclaimer in the documentation and/or other materials provided
1446+ with the distribution.
1447+
1448+ * Neither the name of Herbert Valerio Riedel nor the names of other
1449+ contributors may be used to endorse or promote products derived
1450+ from this software without specific prior written permission.
1451+
1452+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1453+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1454+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1455+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1456+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1457+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1458+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1459+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1460+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1461+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1462+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1463+
13571464fast-logger LICENSE file:
13581465
13591466 Copyright (c) 2009, IIJ Innovation Institute Inc.
@@ -2122,6 +2229,72 @@ old-locale LICENSE file:
21222229
21232230 -----------------------------------------------------------------------------
21242231
2232+old-time LICENSE file:
2233+
2234+ This library (libraries/base) is derived from code from two
2235+ sources:
2236+
2237+ * Code from the GHC project which is largely (c) The University of
2238+ Glasgow, and distributable under a BSD-style license (see below),
2239+
2240+ * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
2241+ and freely redistributable (but see the full license for
2242+ restrictions).
2243+
2244+ The full text of these licenses is reproduced below. Both of the
2245+ licenses are BSD-style or compatible.
2246+
2247+ -----------------------------------------------------------------------------
2248+
2249+ The Glasgow Haskell Compiler License
2250+
2251+ Copyright 2004, The University Court of the University of Glasgow.
2252+ All rights reserved.
2253+
2254+ Redistribution and use in source and binary forms, with or without
2255+ modification, are permitted provided that the following conditions are met:
2256+
2257+ - Redistributions of source code must retain the above copyright notice,
2258+ this list of conditions and the following disclaimer.
2259+
2260+ - Redistributions in binary form must reproduce the above copyright notice,
2261+ this list of conditions and the following disclaimer in the documentation
2262+ and/or other materials provided with the distribution.
2263+
2264+ - Neither name of the University nor the names of its contributors may be
2265+ used to endorse or promote products derived from this software without
2266+ specific prior written permission.
2267+
2268+ THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
2269+ GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
2270+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2271+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2272+ UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
2273+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2274+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2275+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2276+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2277+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2278+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2279+ DAMAGE.
2280+
2281+ -----------------------------------------------------------------------------
2282+
2283+ Code derived from the document "Report on the Programming Language
2284+ Haskell 98", is distributed under the following license:
2285+
2286+ Copyright (c) 2002 Simon Peyton Jones
2287+
2288+ The authors intend this Report to belong to the entire Haskell
2289+ community, and so we grant permission to copy and distribute it for
2290+ any purpose, provided that it is reproduced in its entirety,
2291+ including this Notice. Modified versions of this Report may also be
2292+ copied and distributed for any purpose, provided that the modified
2293+ version is clearly presented as such, and that it does not claim to
2294+ be a definition of the Haskell 98 Language.
2295+
2296+ -----------------------------------------------------------------------------
2297+
21252298optparse-applicative LICENSE file:
21262299
21272300 Copyright (c) 2012, Paolo Capriotti
@@ -2276,7 +2449,7 @@ pem LICENSE file:
22762449
22772450pipes LICENSE file:
22782451
2279− Copyright (c) 2012-2014 Gabriel Gonzalez
2452+ Copyright (c) 2012-2016 Gabriel Gonzalez
22802453 All rights reserved.
22812454
22822455 Redistribution and use in source and binary forms, with or without modification,
@@ -2427,6 +2600,28 @@ process LICENSE file:
24272600
24282601 -----------------------------------------------------------------------------
24292602
2603+protolude LICENSE file:
2604+
2605+ Copyright (c) 2016, Stephen Diehl
2606+
2607+ Permission is hereby granted, free of charge, to any person obtaining a copy
2608+ of this software and associated documentation files (the "Software"), to
2609+ deal in the Software without restriction, including without limitation the
2610+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
2611+ sell copies of the Software, and to permit persons to whom the Software is
2612+ furnished to do so, subject to the following conditions:
2613+
2614+ The above copyright notice and this permission notice shall be included in
2615+ all copies or substantial portions of the Software.
2616+
2617+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2618+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2619+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2620+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2621+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2622+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2623+ IN THE SOFTWARE.
2624+
24302625random LICENSE file:
24312626
24322627 This library (libraries/base) is derived from code from two
@@ -2873,6 +3068,39 @@ streaming-commons LICENSE file:
28733068 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28743069 SOFTWARE.
28753070
3071+string-conv LICENSE file:
3072+
3073+ Copyright (c) 2012, Ozgun Ataman
3074+
3075+ All rights reserved.
3076+
3077+ Redistribution and use in source and binary forms, with or without
3078+ modification, are permitted provided that the following conditions are met:
3079+
3080+ * Redistributions of source code must retain the above copyright
3081+ notice, this list of conditions and the following disclaimer.
3082+
3083+ * Redistributions in binary form must reproduce the above
3084+ copyright notice, this list of conditions and the following
3085+ disclaimer in the documentation and/or other materials provided
3086+ with the distribution.
3087+
3088+ * Neither the name of Ozgun Ataman nor the names of other
3089+ contributors may be used to endorse or promote products derived
3090+ from this software without specific prior written permission.
3091+
3092+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3093+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3094+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3095+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3096+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3097+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3098+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3099+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3100+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3101+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3102+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3103+
28763104syb LICENSE file:
28773105
28783106 This library (libraries/syb) is derived from code from several
@@ -3289,6 +3517,38 @@ unix-compat LICENSE file:
32893517 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32903518 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32913519
3520+unix-time LICENSE file:
3521+
3522+ Copyright (c) 2009, IIJ Innovation Institute Inc.
3523+ All rights reserved.
3524+
3525+ Redistribution and use in source and binary forms, with or without
3526+ modification, are permitted provided that the following conditions
3527+ are met:
3528+
3529+ * Redistributions of source code must retain the above copyright
3530+ notice, this list of conditions and the following disclaimer.
3531+ * Redistributions in binary form must reproduce the above copyright
3532+ notice, this list of conditions and the following disclaimer in
3533+ the documentation and/or other materials provided with the
3534+ distribution.
3535+ * Neither the name of the copyright holders nor the names of its
3536+ contributors may be used to endorse or promote products derived
3537+ from this software without specific prior written permission.
3538+
3539+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3540+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3541+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
3542+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
3543+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
3544+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3545+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3546+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3547+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3548+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
3549+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3550+ POSSIBILITY OF SUCH DAMAGE.
3551+
32923552unordered-containers LICENSE file:
32933553
32943554 Copyright (c) 2010, Johan Tibell
appveyor.yml+2−8
@@ -3,13 +3,10 @@ version: '{build}'
33environment:
44 # Keep the path as short as possible, just in case.
55 STACK_ROOT: c:\s
6− # Appveyor does not seem to be able to cope with the symbolic link
7− # stack.yaml, so this is a workaround.
8− STACK_YAML: stack-lts-5.yaml
96 RELEASE_USER: purescript
107 RELEASE_REPO: purescript
118cache:
12−- c:\s
9+- c:\s -> appveyor/cache-buster.txt
1310install:
1411- git submodule update --init
1512- ps: Install-Product node 5
@@ -31,9 +28,6 @@ build_script:
3128test_script:
3229- stack -j1 --no-terminal test --pedantic
3330on_success:
34−# this seems to be necessary; if omitted, the bash script fails to find the
35−# tool 'strip'.
36−- copy C:\MinGW\bin\strip.exe C:\tools\strip.exe
3731- ps: |
3832 function UploadFile
3933 {
@@ -42,7 +36,7 @@ on_success:
4236
4337 if ($env:APPVEYOR_REPO_TAG_NAME)
4438 {
45− bash ./bundle/build-stack.sh win64
39+ bash ./bundle/build.sh win64
4640
4741 (New-Object Net.WebClient).DownloadFile('https://github.com/aktau/github-release/releases/download/v0.6.2/windows-amd64-github-release.zip', 'c:\tools\github-release.zip')
4842 pushd c:\tools
appveyor/cache-buster.txtnew file+8
@@ -0,0 +1,8 @@
1+This file acts as a cache buster for the AppVeyor (Windows CI) build
2+cache. In order to invalidate the AppVeyor build cache, simply make a
3+change to the number at the end of this file and commit.
4+
5+See http://www.appveyor.com/docs/build-cache#cache-dependencies for more
6+information.
7+
8+Increment me to invalidate the cache: 0
bundle/build-stack.sh → bundle/build.shrenamed+4−2
@@ -29,8 +29,10 @@ mkdir -p bundle/build/purescript
2929for BIN in psc psci psc-docs psc-publish psc-bundle psc-ide-server psc-ide-client
3030do
3131 FULL_BIN="$LOCAL_INSTALL_ROOT/bin/${BIN}${BIN_EXT}"
32− strip "$FULL_BIN" || true # not the end of the world if this fails, and
33− # AppVeyor can't seem to handle it for some reason
32+ if [ "$OS" != "win64" ]
33+ then
34+ strip "$FULL_BIN"
35+ fi
3436 cp "$FULL_BIN" bundle/build/purescript
3537done
3638
core-tests/.gitignore+1
@@ -1,2 +1,3 @@
1+core-docs.md
12bower_components/
23output/
core-tests/bower.jsonnew file+60
@@ -0,0 +1,60 @@
1+{
2+ "name": "core-tests",
3+ "homepage": "https://github.com/purescript/purescript",
4+ "authors": [
5+ "Phil Freeman <paf31@cantab.net>"
6+ ],
7+ "ignore": [
8+ "**/.*",
9+ "node_modules",
10+ "bower_components",
11+ "test",
12+ "tests"
13+ ],
14+ "dependencies": {
15+ "purescript-arrays": "#8c9ada5762",
16+ "purescript-bifunctors": "#9e3b2864ce",
17+ "purescript-console": "#db29da9aca",
18+ "purescript-const": "#cf538a65d8",
19+ "purescript-contravariant": "#9ae6d7c99c",
20+ "purescript-control": "#97096c7e26",
21+ "purescript-distributive": "#ba81c64ffd",
22+ "purescript-eff": "#dbd6c4a415",
23+ "purescript-either": "#54f4efd423",
24+ "purescript-enums": "#9332412e52",
25+ "purescript-exceptions": "#522a0cea50",
26+ "purescript-exists": "#e828c8341e",
27+ "purescript-foldable-traversable": "#df37787855",
28+ "purescript-foreign": "#64890cbbdb",
29+ "purescript-free": "#f8ab7c5f05",
30+ "purescript-functions": "#e417541936",
31+ "purescript-functor-coproducts": "#7654d9dea4",
32+ "purescript-generics": "#d09cb16ca3",
33+ "purescript-globals": "#113ee398be",
34+ "purescript-graphs": "#0b7089afa2",
35+ "purescript-identity": "#204ac5f46a",
36+ "purescript-inject": "#3ae4880bad",
37+ "purescript-integers": "#58d7605dd5",
38+ "purescript-lazy": "#bf4b34d673",
39+ "purescript-maps": "#d9e4c6599a",
40+ "purescript-math": "#99797b6494",
41+ "purescript-maybe": "#1b60a07038",
42+ "purescript-monoid": "#a8c8bb9d73",
43+ "purescript-parallel": "#c7296ab008",
44+ "purescript-prelude": "#318ee857bd",
45+ "purescript-profunctor": "#a649126cea",
46+ "purescript-proxy": "#c494b11bd7",
47+ "purescript-quickcheck": "#4a15c93f12",
48+ "purescript-random": "#68314c21e2",
49+ "purescript-refs": "#f47e1059a3",
50+ "purescript-semirings": "#c40efda15f",
51+ "purescript-sets": "#1eaabf177f",
52+ "purescript-st": "#077d9a2d7e",
53+ "purescript-strings": "#87dd5f1694",
54+ "purescript-tailrec": "#3c11db00ba",
55+ "purescript-transformers": "#2d0a471ce4",
56+ "purescript-tuples": "#4fe689ef93",
57+ "purescript-unfoldable": "#e2382f30d8",
58+ "purescript-validation": "#f43ff0fbdd"
59+ }
60+}
core-tests/test-everything.sh+6−52
@@ -18,62 +18,16 @@ if [ "$force_reinstall" = "true" ] && [ -d "bower_components" ]; then
1818 rm -r bower_components
1919fi
2020
21−bower i \
22− purescript-prelude \
23− purescript-eff \
24− purescript-st \
25− purescript-integers \
26− purescript-functions \
27− purescript-console \
28− purescript-profunctor \
29− purescript-contravariant \
30− purescript-parallel \
31− purescript-control \
32− purescript-tailrec \
33− purescript-maps \
34− purescript-free \
35− purescript-transformers \
36− purescript-exists \
37− purescript-monoid \
38− purescript-either \
39− purescript-maybe \
40− purescript-inject \
41− purescript-graphs \
42− purescript-enums \
43− purescript-unfoldable \
44− purescript-coproducts \
45− purescript-lazy \
46− purescript-distributive \
47− purescript-identity \
48− purescript-bifunctors \
49− purescript-const \
50− purescript-sets \
51− purescript-quickcheck \
52− purescript-foreign \
53− purescript-foldable-traversable \
54− purescript-tuples \
55− purescript-strings \
56− purescript-arrays \
57− purescript-random \
58− purescript-refs \
59− purescript-globals \
60− purescript-exceptions \
61− purescript-validation \
62− purescript-parallel \
63− purescript-proxy \
64− purescript-semirings \
65− purescript-math \
66− purescript-generics
21+# todo : fix this once core libraries reach 1.0
22+yes 1 | bower i
6723
6824if [ "$force_recompile" = "true" ] && [ -d "output" ]; then
6925 echo "Recompiling..."
7026 rm -r output
7127fi
7228
73−../dist/build/psc/psc tests/*/*.purs \
74− 'bower_components/purescript-*/src/**/*.purs' \
75− --ffi 'bower_components/purescript-*/src/**/*.js'
29+stack exec psc 'tests/**/*.purs' 'bower_components/purescript-*/src/**/*.purs'
7630
77−../dist/build/psc-docs/psc-docs tests/*/*.purs \
78− 'bower_components/purescript-*/src/**/*.purs' \
79− > full-core-docs.md
31+stack exec psc-docs 'bower_components/purescript-*/src/**/*.purs' > core-docs.md
32+
33+NODE_PATH=output node -e "require('Test.Main').main()"
core-tests/tests/GenericDeriving.pursnew file+30
@@ -0,0 +1,30 @@
1+module Test.GenericDeriving where
2+
3+import Prelude
4+
5+import Control.Monad.Eff (Eff)
6+import Control.Monad.Eff.Console (CONSOLE, log, logShow)
7+import Data.Generic (class Generic, gShow, gEq)
8+import Partial.Unsafe (unsafePartial)
9+
10+data Empty
11+
12+derive instance genericEmpty :: Partial => Generic Empty
13+
14+data A a
15+ = A Number String
16+ | B Int
17+ | C (Array (A a))
18+ | D { "asgård" :: a }
19+ | E Empty
20+
21+derive instance genericA :: (Partial, Generic b) => Generic (A b)
22+
23+newtype X b = X b
24+
25+derive instance genericX :: Generic (X String)
26+
27+main :: forall eff. Eff (console :: CONSOLE | eff) Unit
28+main = unsafePartial do
29+ log $ gShow (D { "asgård": C [ A 1.0 "test", B 42, D { "asgård": true } ] })
30+ logShow $ gEq (C [B 0]) (C [B 0] :: A Empty)
core-tests/tests/Main.pursnew file+9
@@ -0,0 +1,9 @@
1+module Test.Main where
2+
3+import Prelude
4+import Control.Monad.Eff (Eff)
5+import Control.Monad.Eff.Console (CONSOLE)
6+import Test.GenericDeriving as GenericDeriving
7+
8+main :: forall eff. Eff (console :: CONSOLE | eff) Unit
9+main = GenericDeriving.main
core-tests/tests/generic-deriving/Main.pursdeleted−27
@@ -1,27 +0,0 @@
1−module GenericDeriving where
2−
3−import Prelude
4−
5−import Control.Monad.Eff (Eff())
6−import Control.Monad.Eff.Console (CONSOLE())
7−import Data.Generic
8−
9−data Void
10−
11−derive instance genericVoid :: Generic Void
12−
13−data A a
14− = A Number String
15− | B Int
16− | C (Array (A a))
17− | D { "asgård" :: a }
18− | E Void
19−
20−derive instance genericA :: (Generic b) => Generic (A b)
21−
22−newtype X b = X b
23−
24−derive instance genericX :: Generic (X String)
25−
26−main :: forall eff. Eff (console :: CONSOLE | eff) Unit
27−main = Control.Monad.Eff.Console.log (gShow (D { "asgård": C [ A 1.0 "test", B 42, D { "asgård": true } ] }))
examples/docs/src/Clash.purs−28
@@ -2,31 +2,3 @@ module Clash (module Clash1) where
22
33import Clash1 as Clash1
44import Clash2 as Clash2
5−
6−module Clash1 (module Clash1a) where
7−
8−import Clash1a
9−
10−module Clash1a where
11−
12−value :: Int
13−value = 0
14−
15−type Type = Int
16−
17−class TypeClass a where
18− typeClassMember :: a
19−
20−module Clash2 (module Clash2a) where
21−
22−import Clash2a
23−
24−module Clash2a where
25−
26−value :: String
27−value = "hello"
28−
29−type Type = String
30−
31−class TypeClass a b where
32− typeClassMember :: a -> b
examples/docs/src/Clash1.pursnew file+3
@@ -0,0 +1,3 @@
1+module Clash1 (module Clash1a) where
2+
3+import Clash1a
examples/docs/src/Clash1a.pursnew file+9
@@ -0,0 +1,9 @@
1+module Clash1a where
2+
3+value :: Int
4+value = 0
5+
6+type Type = Int
7+
8+class TypeClass a where
9+ typeClassMember :: a
examples/docs/src/Clash2.pursnew file+3
@@ -0,0 +1,3 @@
1+module Clash2 (module Clash2a) where
2+
3+import Clash2a
examples/docs/src/Clash2a.pursnew file+9
@@ -0,0 +1,9 @@
1+module Clash2a where
2+
3+value :: String
4+value = "hello"
5+
6+type Type = String
7+
8+class TypeClass a b where
9+ typeClassMember :: a -> b
examples/docs/src/ImportedTwice.purs+4−18
@@ -4,24 +4,10 @@
44-- re-exports it from Control.Monad.Trans).
55
66module ImportedTwice
7− ( module A
8− , module B
7+ ( module ImportedTwiceA
8+ , module ImportedTwiceB
99 )
1010 where
1111
12−import A
13−import B
14−
15−module A
16− ( module B )
17− where
18−
19−import B
20−
21−bar :: Int
22−bar = 1
23−
24−module B where
25−
26−foo :: Int
27−foo = 0
12+import ImportedTwiceA
13+import ImportedTwiceB
examples/docs/src/ImportedTwiceA.pursnew file+8
@@ -0,0 +1,8 @@
1+module ImportedTwiceA
2+ ( module ImportedTwiceB )
3+ where
4+
5+import ImportedTwiceB
6+
7+bar :: Int
8+bar = 1
examples/docs/src/ImportedTwiceB.pursnew file+4
@@ -0,0 +1,4 @@
1+module ImportedTwiceB where
2+
3+foo :: Int
4+foo = 0
examples/docs/src/MultiVirtual.purs−21
@@ -4,24 +4,3 @@ module MultiVirtual
44
55import MultiVirtual1 as X
66import MultiVirtual2 as X
7−
8−
9−module MultiVirtual1 where
10−
11−foo :: Int
12−foo = 1
13−
14−module MultiVirtual2
15− ( module MultiVirtual2
16− , module MultiVirtual3
17− ) where
18−
19−import MultiVirtual3
20−
21−bar :: Int
22−bar = 2
23−
24−module MultiVirtual3 where
25−
26−baz :: Int
27−baz = 3
examples/docs/src/MultiVirtual1.pursnew file+4
@@ -0,0 +1,4 @@
1+module MultiVirtual1 where
2+
3+foo :: Int
4+foo = 1
examples/docs/src/MultiVirtual2.pursnew file+9
@@ -0,0 +1,9 @@
1+module MultiVirtual2
2+ ( module MultiVirtual2
3+ , module MultiVirtual3
4+ ) where
5+
6+import MultiVirtual3
7+
8+bar :: Int
9+bar = 2
examples/docs/src/MultiVirtual3.pursnew file+4
@@ -0,0 +1,4 @@
1+module MultiVirtual3 where
2+
3+baz :: Int
4+baz = 3
examples/docs/src/NewOperators.purs−7
@@ -3,10 +3,3 @@ module NewOperators
33 where
44
55import NewOperators2
6−
7−module NewOperators2 where
8−
9−infixl 8 _compose as >>>
10−
11−_compose :: forall a b c. (b -> c) -> (a -> b) -> (a -> c)
12−_compose f g x = f (g x)
examples/docs/src/NewOperators2.pursnew file+6
@@ -0,0 +1,6 @@
1+module NewOperators2 where
2+
3+infixl 8 _compose as >>>
4+
5+_compose :: forall a b c. (b -> c) -> (a -> b) -> (a -> c)
6+_compose f g x = f (g x)
examples/docs/src/OldOperators.pursdeleted−10
@@ -1,10 +0,0 @@
1−
2−-- Remove this after 0.9.
3−module OldOperators (module OldOperators2) where
4−
5−import OldOperators2
6−
7−module OldOperators2 where
8−
9−(>>) :: forall a. a -> a -> a
10−(>>) a b = b
examples/docs/src/TypeClassWithoutMembers.purs+2−8
@@ -1,11 +1,5 @@
11module TypeClassWithoutMembers
2− ( module Intermediate )
2+ ( module TypeClassWithoutMembersIntermediate )
33 where
44
5−import Intermediate
6−
7−module Intermediate
8− ( module SomeTypeClass )
9− where
10−
11−import SomeTypeClass (SomeClass)
5+import TypeClassWithoutMembersIntermediate
examples/docs/src/TypeClassWithoutMembersIntermediate.pursnew file+5
@@ -0,0 +1,5 @@
1+module TypeClassWithoutMembersIntermediate
2+ ( module SomeTypeClass )
3+ where
4+
5+import SomeTypeClass (class SomeClass)
examples/failing/1733.purs+1−8
@@ -1,13 +1,6 @@
1−-- @shouldFailWith UnknownValue
2−
1+-- @shouldFailWith UnknownName
32module Main where
43
54import Thingy as Thing
65
76main = Thing.doesntExist "hi"
8−
9−module Thingy where
10−
11−foo :: Int
12−foo = 1
13−
examples/failing/1733/Thingy.pursnew file+4
@@ -0,0 +1,4 @@
1+module Thingy where
2+
3+foo :: Int
4+foo = 1
examples/failing/1825.purs+4−4
@@ -1,9 +1,9 @@
1−-- @shouldFailWith UnknownValue
1+-- @shouldFailWith UnknownName
22
33module Main where
44
55data W = X | Y | Z
66
7−bad X a = a
8−bad Y _ = a
9−bad Z a = a
7+bad X a = a
8+bad Y _ = a
9+bad Z a = a
examples/failing/1881.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith ErrorParsingModule
2+module Main where
3+
4+foo =
5+bar :: Int
6+bar = 3
examples/manual/failing/ArgLengthMismatch.purs → examples/failing/ArgLengthMismatch.pursrenamed+7−6
@@ -1,6 +1,7 @@
1−module ArgLengthMismatch where
2−
3−import Prelude
4−
5−f x y = true
6−f = false
1+-- @shouldFailWith ArgListLengthsDiffer
2+module ArgLengthMismatch where
3+
4+import Prelude
5+
6+f x y = true
7+f = false
examples/failing/Arrays.purs+2−4
@@ -1,8 +1,6 @@
11-- @shouldFailWith TypesDoNotUnify
22module Main where
33
4−import Prelude
4+foreign import ix :: forall a. Array a -> Int -> a
55
6−foreign import (!!) :: forall a. Array a -> Int -> a
7−
8−test = \arr -> arr !! (0 !! 0)
6+test = \arr -> arr `ix` (0 `ix` 0)
examples/failing/ConflictingExports.purs−10
@@ -1,14 +1,4 @@
11-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
122-- Fails here because re-exporting forces any scope conflicts to be resolved
133module Main (module A, module B) where
144
examples/failing/ConflictingExports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingExports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingImports.purs+5−15
@@ -1,19 +1,9 @@
11-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
122module Main where
133
14− import A
15− import B
4+import A
5+import B
166
17− -- Error due to referencing `thing` which is in scope as A.thing and B.thing
18− what :: Int
19− what = thing
7+-- Error due to referencing `thing` which is in scope as A.thing and B.thing
8+what :: Int
9+what = thing
examples/failing/ConflictingImports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingImports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingImports2.purs+6−16
@@ -1,20 +1,10 @@
11-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
122module Main where
133
14− import A (thing)
15− import B (thing)
4+import A (thing)
5+import B (thing)
166
17− -- Error due to referencing `thing` which is explicitly in scope as A.thing
18− -- and B.thing
19− what :: Int
20− what = thing
7+-- Error due to referencing `thing` which is explicitly in scope as A.thing
8+-- and B.thing
9+what :: Int
10+what = thing
examples/failing/ConflictingImports2/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingImports2/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingQualifiedImports.purs+3−13
@@ -1,17 +1,7 @@
11-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
122module Main where
133
14− import A as X
15− import B as X
4+import A as X
5+import B as X
166
17− foo = X.thing
7+foo = X.thing
examples/failing/ConflictingQualifiedImports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingQualifiedImports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/ConflictingQualifiedImports2.purs+2−12
@@ -1,15 +1,5 @@
11-- @shouldFailWith ScopeConflict
2−module A where
3−
4− thing :: Int
5− thing = 1
6−
7−module B where
8−
9− thing :: Int
10− thing = 2
11−
122module Main (module X) where
133
14− import A as X
15− import B as X
4+import A as X
5+import B as X
examples/failing/ConflictingQualifiedImports2/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/failing/ConflictingQualifiedImports2/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/failing/DeclConflictClassCtor.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+data T = Fail
5+
6+class Fail
examples/failing/DeclConflictClassSynonym.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+type Fail = Unit
7+
8+class Fail
examples/failing/DeclConflictClassType.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+class Fail
5+
6+data Fail
examples/failing/DeclConflictCtorClass.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+class Fail
5+
6+data T = Fail
examples/failing/DeclConflictCtorCtor.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+data T1 = Fail
5+
6+data T2 = Fail
examples/failing/DeclConflictSynonymClass.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+class Fail
7+
8+type Fail = Unit
examples/failing/DeclConflictSynonymType.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+data Fail
7+
8+type Fail = Unit
examples/failing/DeclConflictTypeClass.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+class Fail
5+
6+data Fail
examples/failing/DeclConflictTypeSynonym.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+import Prelude
5+
6+type Fail = Unit
7+
8+data Fail
examples/failing/DeclConflictTypeType.pursnew file+6
@@ -0,0 +1,6 @@
1+-- @shouldFailWith DeclConflict
2+module Main where
3+
4+data Fail
5+
6+data Fail
examples/failing/Do.purs+2−2
@@ -8,5 +8,5 @@ test1 = do let x = 1
88
99test2 y = do x <- y
1010
11−test3 = do return 1
12− return 2
11+test3 = do pure 1
12+ pure 2
examples/failing/ExportConflictClass.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictClass/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+class X
examples/failing/ExportConflictClass/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+class X
examples/failing/ExportConflictCtor.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictCtor/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+data T1 = X
examples/failing/ExportConflictCtor/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+data T2 = X
examples/failing/ExportConflictType.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictType/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+data T
examples/failing/ExportConflictType/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+data T
examples/failing/ExportConflictTypeOp.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictTypeOp/A.pursnew file+5
@@ -0,0 +1,5 @@
1+module A where
2+
3+type T1 a b = a -> b
4+
5+infixr 4 type T1 as ??
examples/failing/ExportConflictTypeOp/B.pursnew file+5
@@ -0,0 +1,5 @@
1+module B where
2+
3+type T2 a b = a -> b
4+
5+infixr 4 type T2 as ??
examples/failing/ExportConflictValue.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictValue/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+x :: Boolean
4+x = true
examples/failing/ExportConflictValue/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+x :: Boolean
4+x = false
examples/failing/ExportConflictValueOp.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldFailWith ExportConflict
2+module C (module A, module B) where
3+
4+import A as A
5+import B as B
examples/failing/ExportConflictValueOp/A.pursnew file+6
@@ -0,0 +1,6 @@
1+module A where
2+
3+f1 :: forall a b. a -> b -> a
4+f1 x _ = x
5+
6+infix 0 f1 as !!
examples/failing/ExportConflictValueOp/B.pursnew file+6
@@ -0,0 +1,6 @@
1+module B where
2+
3+f2 :: forall a b. a -> b -> a
4+f2 x _ = x
5+
6+infix 0 f2 as !!
examples/manual/failing/ExportExplicit.purs → examples/failing/ExportExplicit.pursrenamed+8−7
@@ -1,7 +1,8 @@
1−-- should fail as z does not exist in the module
2−module M1 (x, y, z) where
3−
4−import Prelude
5−
6−x = 1
7−y = 2
1+-- @shouldFailWith UnknownExport
2+-- should fail as z does not exist in the module
3+module M1 (x, y, z) where
4+
5+import Prelude
6+
7+x = 1
8+y = 2
examples/failing/ExportExplicit1.pursnew file+12
@@ -0,0 +1,12 @@
1+-- @shouldFailWith UnknownName
2+module Main where
3+
4+import M1
5+import Control.Monad.Eff.Console (log)
6+
7+testX = X
8+
9+-- should fail as Y constructor is not exported from M1
10+testY = Y
11+
12+main = log "Done"
examples/failing/ExportExplicit1/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 (X(X)) where
2+
3+data X = X | Y
examples/manual/failing/ExportExplicit2.purs → examples/failing/ExportExplicit2.pursrenamed+8−7
@@ -1,7 +1,8 @@
1−-- should fail as Y is not a data constructor for X
2−module M1 (X(Y)) where
3−
4−import Prelude
5−
6−data X = X
7−data Y = Y
1+-- @shouldFailWith UnknownExportDataConstructor
2+-- should fail as Y is not a data constructor for X
3+module M1 (X(Y)) where
4+
5+import Prelude
6+
7+data X = X
8+data Y = Y
examples/failing/ExportExplicit3.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldFailWith UnknownName
2+module Main where
3+
4+import M1 as M
5+import Control.Monad.Eff.Console (log)
6+
7+-- should fail as Z is not exported from M1
8+testZ = M.Z
9+
10+main = log "Done"
examples/failing/ExportExplicit3/M1.pursnew file+4
@@ -0,0 +1,4 @@
1+module M1 (X(..)) where
2+
3+data X = X | Y
4+data Z = Z
examples/failing/ImportExplicit.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldFailWith UnknownImport
2+module Main where
3+
4+import M1 (X(..))
examples/failing/ImportExplicit/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 where
2+
3+foo = "foo"
examples/failing/ImportExplicit2.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldFailWith UnknownImportDataConstructor
2+module Main where
3+
4+import M1 (X(Z, Q))
examples/failing/ImportExplicit2/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 where
2+
3+data X = Y
examples/failing/ImportHidingModule.purs+4−10
@@ -1,10 +1,4 @@
1−-- @shouldFailWith ImportHidingModule
2−module A where
3− x = 1
4−
5−module B (module B, module A) where
6− import A
7− y = 1
8−
9−module C where
10− import B hiding (module A)
1+-- @shouldFailWith ImportHidingModule
2+module Main where
3+
4+import B hiding (module A)
examples/failing/ImportHidingModule/A.pursnew file+2
@@ -0,0 +1,2 @@
1+module A where
2+x = 1
examples/failing/ImportHidingModule/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B (module B, module A) where
2+import A
3+y = 1
examples/failing/ImportModule.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldFailWith UnknownName
2+module Main where
3+
4+import M1
examples/failing/ImportModule/M2.pursnew file+3
@@ -0,0 +1,3 @@
1+module M2 where
2+
3+data X = X
examples/failing/InstanceExport.purs+7−19
@@ -1,19 +1,7 @@
1−-- @shouldFailWith TransitiveExportError
2−module InstanceExport (S(..), f) where
3−
4−import Prelude
5−
6−newtype S = S String
7−
8−class F a where
9− f :: a -> String
10−
11−instance fs :: F S where
12− f (S s) = s
13−
14−module Test where
15−
16−import InstanceExport
17−import Prelude
18−
19−test = f $ S "Test"
1+-- @shouldFailWith TransitiveExportError
2+module Test where
3+
4+import InstanceExport
5+import Prelude
6+
7+test = f $ S "Test"
examples/failing/InstanceExport/InstanceExport.pursnew file+11
@@ -0,0 +1,11 @@
1+module InstanceExport (S(..), f) where
2+
3+import Prelude
4+
5+newtype S = S String
6+
7+class F a where
8+ f :: a -> String
9+
10+instance fs :: F S where
11+ f (S s) = s
examples/failing/MissingClassMemberExport.purs+1−1
@@ -1,5 +1,5 @@
11-- @shouldFailWith TransitiveExportError
2−module Test (Foo) where
2+module Test (class Foo) where
33
44import Prelude
55
examples/failing/MultipleErrors2.purs+2−2
@@ -1,5 +1,5 @@
1−-- @shouldFailWith UnknownValue
2−-- @shouldFailWith UnknownValue
1+-- @shouldFailWith UnknownName
2+-- @shouldFailWith UnknownName
33module MultipleErrors2 where
44
55import Prelude
examples/failing/MultipleTypeOpFixities.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldFailWith MultipleTypeOpFixities
2+module MultipleTypeOpFixities where
3+
4+import Prelude
5+
6+type Op x y = Op x y
7+
8+infix 2 type Op as !?
9+infix 2 type Op as !?
examples/failing/MultipleValueOpFixities.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldFailWith MultipleValueOpFixities
2+module MultipleValueOpFixities where
3+
4+import Prelude
5+
6+add x y = x + y
7+
8+infix 2 add as !?
9+infix 2 add as !?
examples/failing/OrphanInstance.purs+7−12
@@ -1,12 +1,7 @@
1−-- @shouldFailWith OrphanInstance
2−module Class where
3−
4− class C a where
5− op :: a -> a
6−
7−module Test where
8−
9− import Class
10−
11− instance cBoolean :: C Boolean where
12− op a = a
1+-- @shouldFailWith OrphanInstance
2+module Test where
3+
4+import Class
5+
6+instance cBoolean :: C Boolean where
7+ op a = a
examples/failing/OrphanInstance/Class.pursnew file+4
@@ -0,0 +1,4 @@
1+module Class where
2+
3+class C a where
4+ op :: a -> a
examples/manual/failing/OrphanTypeDecl.purs → examples/failing/OrphanTypeDecl.pursrenamed+4−3
@@ -1,3 +1,4 @@
1−module OrphanTypeDecl where
2−
3−fn :: Number -> Boolean
1+-- @shouldFailWith OrphanTypeDeclaration
2+module OrphanTypeDecl where
3+
4+fn :: Number -> Boolean
examples/failing/OverlappingReExport.pursdeleted−10
@@ -1,10 +0,0 @@
1−-- @shouldFailWith DuplicateValueExport
2−module A where
3− x = true
4−
5−module B where
6− x = false
7−
8−module C (module A, module M2) where
9− import A
10− import qualified B as M2
examples/failing/ProgrammableTypeErrors.pursnew file+16
@@ -0,0 +1,16 @@
1+-- @shouldFailWith NoInstanceFound
2+
3+module Main where
4+
5+import Prelude
6+import Control.Monad.Eff (Eff)
7+import Control.Monad.Eff.Console (log)
8+
9+class MyShow a where
10+ myShow :: a -> String
11+
12+instance cannotShowFunctions :: Fail "Cannot show functions" => MyShow (a -> b) where
13+ myShow _ = "unreachable"
14+
15+main :: Eff _ _
16+main = log (myShow (_ + 1))
examples/manual/failing/RequiredHiddenType.purs → examples/failing/RequiredHiddenType.pursrenamed+9−8
@@ -1,8 +1,9 @@
1−-- exporting `a` should fail as `A` is hidden
2−module Foo (B(..), a, b) where
3−
4−data A = A
5−data B = B
6−
7−a = A
8−b = B
1+-- @shouldFailWith TransitiveExportError
2+-- exporting `a` should fail as `A` is hidden
3+module Foo (B(..), a, b) where
4+
5+data A = A
6+data B = B
7+
8+a = A
9+b = B
examples/failing/RowConstructors1.purs+2−2
@@ -1,9 +1,9 @@
11-- @shouldFailWith KindsDoNotUnify
22module Main where
33
4−import Prelude
4+import Control.Monad.Eff.Console (log)
55
66data Foo = Bar
77type Baz = { | Foo }
88
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/failing/RowConstructors2.purs+2−2
@@ -1,9 +1,9 @@
11-- @shouldFailWith KindsDoNotUnify
22module Main where
33
4−import Prelude
4+import Control.Monad.Eff.Console (log)
55
66type Foo r = (x :: Number | r)
77type Bar = { | Foo }
88
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/failing/RowConstructors3.purs+2−2
@@ -1,9 +1,9 @@
11-- @shouldFailWith KindsDoNotUnify
22module Main where
33
4−import Prelude
4+import Control.Monad.Eff.Console (log)
55
66type Foo = { x :: Number }
77type Bar = { | Foo }
88
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/failing/SkolemEscape2.purs+1−1
@@ -7,4 +7,4 @@ import Control.Monad.ST
77
88test _ = do
99 r <- runST (newSTRef 0)
10− return 0
10+ pure 0
examples/failing/SuggestComposition.purs+1−1
@@ -4,4 +4,4 @@ module SuggestComposition where
44
55import Prelude
66
7−f = g . g where g = (+1)
7+f = g . g where g = (_ + 1)
examples/failing/Superclasses5.purs+2−1
@@ -3,6 +3,7 @@
33module Main where
44
55import Prelude
6+import Control.Monad.Eff.Console (logShow)
67
78class Su a where
89 su :: a -> a
@@ -22,4 +23,4 @@ instance clNumber :: Cl Number where
2223test :: forall a. (Cl a) => a -> Array a
2324test x = su [cl x x]
2425
25−main = Control.Monad.Eff.Console.print $ test 10.0
26+main = logShow $ test 10.0
examples/failing/TypeError.purs+1−1
@@ -3,4 +3,4 @@ module Main where
33
44import Prelude
55
6−test = 1 ++ "A"
6+test = 1 <> "A"
examples/failing/TypedBinders.purs+3−3
@@ -1,10 +1,10 @@
1−-- @shouldFailWith ErrorParsingModule
1+-- @shouldFailWith ErrorParsingModule
22module Main where
33
4−import Prelude
4+import Control.Monad.Eff.Console (log)
55
66test = (\f :: Int -> Int -> f 10) id
77
88main = do
99 let t1 = test
10− Control.Monad.Eff.Console.log "Done"
10+ log "Done"
examples/failing/TypedBinders2.purs+3−3
@@ -2,8 +2,8 @@
22module Main where
33
44import Prelude
5+import Control.Monad.Eff.Console (log)
56
67main = do
7− s :: String <- Control.Monad.Eff.Console.log "Foo"
8− Control.Monad.Eff.Console.log "Done"
9−
8+ s :: String <- log "Foo"
9+ log "Done"
examples/failing/TypedBinders3.purs+2−1
@@ -2,6 +2,7 @@
22module Main where
33
44import Prelude
5+import Control.Monad.Eff.Console (log)
56
67test = case 1 of
78 (0 :: String) -> true
@@ -9,4 +10,4 @@ test = case 1 of
910
1011main = do
1112 let t = test
12− Control.Monad.Eff.Console.log "Done"
13+ log "Done"
examples/failing/UnderscoreModuleName.purs+2−2
@@ -1,6 +1,6 @@
11-- @shouldFailWith ErrorParsingModule
22module Bad_Module where
33
4−import Prelude
4+import Control.Monad.Eff.Console (log)
55
6−main = Control.Monad.Eff.Console.log "Done"
6+main = log "Done"
examples/failing/UnknownType.purs+1−1
@@ -1,4 +1,4 @@
1−-- @shouldFailWith UnknownType
1+-- @shouldFailWith UnknownName
22module Main where
33
44import Prelude
examples/manual/QualifiedNames.pursdeleted−13
@@ -1,13 +0,0 @@
1−module Data.Either where
2−
3−import Prelude
4−
5−data Either a b = Left a | Right b
6−
7−module Main where
8−
9−either :: forall a b c. (a -> c) -> (b -> c) -> Data.Either.Either a b -> c
10−either f _ (Data.Either.Left x) = f x
11−either _ g (Data.Either.Right y) = g y
12−
13−main = Control.Monad.Eff.Console.log (either id id (Data.Either.Left "Done"))
examples/manual/failing/ExportExplicit1.pursdeleted−14
@@ -1,14 +0,0 @@
1−module M1 (X(X)) where
2−
3− data X = X | Y
4−
5−module Main where
6−
7− import M1
8−
9− testX = X
10−
11− -- should fail as Y constructor is not exported from M1
12− testY = Y
13−
14− main = Control.Monad.Eff.Console.log "Done"
examples/manual/failing/ExportExplicit3.pursdeleted−13
@@ -1,13 +0,0 @@
1−module M1 (X(..)) where
2−
3− data X = X | Y
4− data Z = Z
5−
6−module Main where
7−
8− import M1
9−
10− -- should fail as Z is not exported from M1
11− testZ = M1.Z
12−
13− main = Control.Monad.Eff.Console.log "Done"
examples/manual/failing/ImportExplicit.pursdeleted−7
@@ -1,7 +0,0 @@
1−module M1 where
2−
3− foo = "foo"
4−
5−module Main where
6−
7− import M1 (X(..))
examples/manual/failing/ImportExplicit2.pursdeleted−7
@@ -1,7 +0,0 @@
1−module M1 where
2−
3− data X = Y
4−
5−module Main where
6−
7− import M1 (X(Z, Q))
examples/manual/failing/ImportModule.pursdeleted−7
@@ -1,7 +0,0 @@
1−module M2 where
2−
3− data X = X
4−
5−module Main where
6−
7− import M1
examples/manual/failing/RedefinedFixity.pursdeleted−8
@@ -1,8 +0,0 @@
1−module RedefinedFixity where
2−
3−import Prelude
4−
5−(!?) x y = x + y
6−
7−infix 2 !?
8−infix 2 !?
examples/manual/passing/ExportExplicit.pursdeleted−20
@@ -1,20 +0,0 @@
1−module M1 (X(X), Z(..), foo) where
2−
3− data X = X | Y
4− data Z = Z
5−
6− foo :: Number
7− foo = 0
8−
9− bar :: Number
10− bar = 1
11−
12−module Main where
13−
14− import M1
15−
16− testX = X
17− testZ = Z
18− testFoo = foo
19−
20− main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ExportExplicit2.pursdeleted−15
@@ -1,15 +0,0 @@
1−module M1 (bar) where
2−
3− foo :: Number
4− foo = 0
5−
6− bar :: Number
7− bar = foo
8−
9−module Main where
10−
11− import M1
12−
13− testBar = bar
14−
15− main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/Import.pursdeleted−19
@@ -1,19 +0,0 @@
1−module M1 where
2−
3− import Prelude ()
4−
5− id :: forall a. a -> a
6− id = \x -> x
7−
8− foo = id
9−
10−module M2 where
11−
12− import Prelude ()
13− import M1
14−
15− main = \_ -> foo 42
16−
17−module Main where
18−
19−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ImportExplicit.pursdeleted−14
@@ -1,14 +0,0 @@
1−module M1 where
2−
3− data X = X | Y
4− data Z = Z
5−
6−module Main where
7−
8− import M1 (X(..))
9−
10− testX :: X
11− testX = X
12− testY = Y
13−
14− main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ImportQualified.pursdeleted−12
@@ -1,12 +0,0 @@
1−module M1 where
2−
3− log x = x
4−
5−module Main where
6−
7− import Prelude
8− import Control.Monad.Eff
9− import M1
10− import qualified Control.Monad.Eff.Console as C
11−
12− main = C.log (log "Done")
examples/manual/passing/Module.pursdeleted−28
@@ -1,28 +0,0 @@
1−module M1 where
2−
3− import Prelude
4−
5− data Foo = Foo String
6−
7− foo :: M1.Foo -> String
8− foo = \f -> case f of Foo s -> s ++ "foo"
9−
10− bar :: Foo -> String
11− bar = foo
12−
13− incr :: Number -> Number
14− incr x = x + 1
15−
16−module M2 where
17−
18− import Prelude
19−
20− baz :: M1.Foo -> String
21− baz = M1.foo
22−
23− match :: M1.Foo -> String
24− match = \f -> case f of M1.Foo s -> s ++ "foo"
25−
26−module Main where
27−
28−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/ModuleDeps.pursdeleted−17
@@ -1,17 +0,0 @@
1−module M1 where
2−
3−import M2
4−
5−foo = M3.baz
6−
7−module M2 where
8−
9−bar = M3.baz
10−
11−module M3 where
12−
13−baz = 1
14−
15−module Main where
16−
17−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/RedefinedFixity.pursdeleted−24
@@ -1,24 +0,0 @@
1−module M1 where
2−
3−import Prelude ()
4−
5−($) f a = f a
6−
7−infixr 1000 $
8−
9−module M2 where
10−
11−import Prelude ()
12−
13−import M1
14−
15−module M3 where
16−
17−import Prelude ()
18−
19−import M1
20−import M2
21−
22−module Main where
23−
24−main = Control.Monad.Eff.Console.log "Done"
examples/manual/passing/TransitiveImport.pursdeleted−24
@@ -1,24 +0,0 @@
1−module Test where
2−
3− import Prelude
4−
5− class TestCls a where
6− test :: a -> a
7−
8− instance unitTestCls :: TestCls Unit where
9− test _ = unit
10−
11−module Middle where
12−
13− middle = Test.test
14−
15−module Main where
16−
17− import Prelude
18− import Middle
19− import Control.Monad.Eff.Console
20−
21− main = do
22− print (middle unit)
23− trace "Done"
24− return unit
examples/passing/1185.purs+3−1
@@ -1,5 +1,7 @@
11module Main where
22
3+import Control.Monad.Eff.Console (log)
4+
35data Person = Person String Boolean
46
57getName :: Person -> String
@@ -10,4 +12,4 @@ getName p = case p of
1012name :: String
1113name = getName (Person "John Smith" true)
1214
13−main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/1335.purs+14−12
@@ -1,12 +1,14 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console (log)
5−
6−x :: forall a. a -> String
7−x a = y "Done"
8− where
9− y :: forall a. (Show a) => a -> String
10− y a = show (a :: a)
11−
12−main = log (x 0)
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+x :: forall a. a -> String
7+x a = y "Test"
8+ where
9+ y :: forall a. (Show a) => a -> String
10+ y a = show (a :: a)
11+
12+main = do
13+ log (x 0)
14+ log "Done"
examples/passing/1570.purs+3−1
@@ -1,6 +1,8 @@
11module Main where
22
3+import Control.Monad.Eff.Console (log)
4+
35test :: forall a. a -> a
46test = \(x :: a) -> x
57
6−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/1664.purs+1−1
@@ -11,6 +11,6 @@ newtype IdentityEff e a = IdentityEff (Eff e (Identity a))
1111test :: forall e a. IdentityEff e a -> IdentityEff e Unit
1212test (IdentityEff action) = IdentityEff $ do
1313 (Identity x :: Identity _) <- action
14− return $ Identity unit
14+ pure $ Identity unit
1515
1616main = log "Done"
examples/passing/1697.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56_2 :: forall a. a -> a
67_2 a = a
@@ -21,4 +22,4 @@ wtf = do
2122 let tmp = _2 1
2223 pure unit
2324
24−main = Control.Monad.Eff.Console.log "Done"
25+main = log "Done"
examples/passing/1881.pursnew file+19
@@ -0,0 +1,19 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+foo =
6+ 1
7+
8+bar
9+ = 2
10+
11+baz
12+ =
13+ 3
14+
15+qux
16+ =
17+ 3
18+
19+main = log "Done"
examples/passing/1991.purs+4−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56singleton :: forall a. a -> Array a
67singleton x = [x]
@@ -10,11 +11,12 @@ empty = []
1011
1112foldMap :: forall a m. (Semigroup m) => (a -> m) -> Array a -> m
1213foldMap f [a, b, c, d, e] = f a <> f b <> f c <> f d <> f e
14+foldMap f xs = foldMap f xs -- spin, not used
1315
1416regression :: Array Int
1517regression =
1618 let as = [1,2,3,4,5]
1719 as' = foldMap (\x -> if 1 < x && x < 4 then singleton x else empty) as
1820 in as'
19−
20−main = Control.Monad.Eff.Console.log "Done"
21+
22+main = log "Done"
examples/passing/2018.purs−13
@@ -1,15 +1,3 @@
1−module B where
2−
3− data Foo = X | Y
4−
5−module A where
6−
7− import B as Main
8−
9− -- Prior to the 2018 fix this would be detected as a cycle between A and Main.
10− foo ∷ Main.Foo → Main.Foo
11− foo x = x
12−
131module Main where
142
153import Prelude
@@ -22,4 +10,3 @@ main :: forall e. Eff (console :: CONSOLE | e) Unit
2210main = do
2311 let tmp = foo X
2412 log "Done"
25−
examples/passing/2018/A.pursnew file+7
@@ -0,0 +1,7 @@
1+module A where
2+
3+import B as Main
4+
5+-- Prior to the 2018 fix this would be detected as a cycle between A and Main.
6+foo ∷ Main.Foo → Main.Foo
7+foo x = x
examples/passing/2018/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+data Foo = X | Y
examples/passing/2049.pursnew file+14
@@ -0,0 +1,14 @@
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+data List a = Cons a (List a) | Nil
7+
8+infixr 6 Cons as :
9+
10+f :: List { x :: Int, y :: Int } -> Int
11+f ( r@{ x } : _) = x + r.y
12+f _ = 0
13+
14+main = log "Done"
examples/passing/2138.pursnew file+7
@@ -0,0 +1,7 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+import Lib (A(B,C))
6+
7+main = log "Done"
examples/passing/2138/Lib.pursnew file+3
@@ -0,0 +1,3 @@
1+module Lib (A(..), A) where
2+
3+data A = B | C
examples/passing/2172.jsnew file+5
@@ -0,0 +1,5 @@
1+exports['a\''] = 0;
2+exports["\x62\x27"] = 1;
3+// NOTE: I wanted to use "\c'" here, but langauge-javascript doesn't support it...
4+exports["c'"] = 2;
5+exports["\u0064\u0027"] = 3;
examples/passing/2172.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+foreign import a' :: Number
6+foreign import b' :: Number
7+foreign import c' :: Number
8+foreign import d' :: Number
9+
10+main = log "Done"
examples/passing/2252.pursnew file+15
@@ -0,0 +1,15 @@
1+module Main where
2+
3+import Control.Monad.Eff.Console (log)
4+
5+data T a = T
6+
7+ti :: T Int
8+ti = T
9+
10+t :: forall a. T a
11+t = T
12+
13+xs = [ti, t, t]
14+
15+main = log "Done"
examples/passing/652.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class Foo a b
67
@@ -14,4 +15,4 @@ instance bar :: Bar (a -> b) b
1415
1516instance baz :: (Eq a) => Baz (a -> b) a b
1617
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/810.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Maybe a = Nothing | Just a
67
@@ -10,4 +11,4 @@ test m = o.x
1011 o = case m of Nothing -> { x : Nothing }
1112 Just a -> { x : Just a }
1213
13−main = Control.Monad.Eff.Console.log "Done"
14+main = log "Done"
examples/passing/Applicative.purs+2−2
@@ -1,6 +1,6 @@
11module Main where
22
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
44
55class Applicative f where
66 pure :: forall a. a -> f a
@@ -13,4 +13,4 @@ instance applicativeMaybe :: Applicative Maybe where
1313 apply (Just f) (Just a) = Just (f a)
1414 apply _ _ = Nothing
1515
16−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/ArrayType.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class Pointed p where
67 point :: forall a. a -> p a
@@ -8,4 +9,4 @@ class Pointed p where
89instance pointedArray :: Pointed Array where
910 point a = [a]
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/Auto.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Auto s i o = Auto { state :: s, step :: s -> i -> o }
67
@@ -12,4 +13,4 @@ exists = \state step f -> f (Auto { state: state, step: step })
1213run :: forall i o. SomeAuto i o -> i -> o
1314run = \s i -> s (\a -> case a of Auto a -> a.step a.state i)
1415
15−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/AutoPrelude.purs+11−9
@@ -1,9 +1,11 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−f x = x * 10.0
7−g y = y - 10.0
8−
9−main = log $ show $ (f <<< g) 100.0
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+f x = x * 10.0
7+g y = y - 10.0
8+
9+main = do
10+ log $ show $ (f <<< g) 100.0
11+ log "Done"
examples/passing/AutoPrelude2.purs+1−1
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import qualified Prelude as P
4+import Prelude as P
55import Control.Monad.Eff.Console
66
77f :: forall a. a -> a
examples/passing/BindersInFunctions.purs+8−3
@@ -1,11 +1,16 @@
11module Main where
22
33import Prelude
4−import Test.Assert
4+import Partial.Unsafe (unsafePartial)
5+import Test.Assert (assert')
6+import Control.Monad.Eff (Eff)
7+import Control.Monad.Eff.Console (log)
58
9+snd :: forall a. Partial => Array a -> a
610snd = \[_, y] -> y
711
12+main :: Eff _ _
813main = do
9− let ts = snd [1.0, 2.0]
14+ let ts = unsafePartial (snd [1.0, 2.0])
1015 assert' "Incorrect result from 'snd'." (ts == 2.0)
11− Control.Monad.Eff.Console.log "Done"
16+ log "Done"
examples/passing/BindingGroups.purs+2−1
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56foo = bar
67 where bar r = r + 1.0
78
89r = foo 2.0
910
10−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/BlockString.purs+2−1
@@ -1,8 +1,9 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56foo :: String
67foo = """foo"""
78
8−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/CaseInDo.purs+4−2
@@ -1,19 +1,21 @@
11module Main where
22
33import Prelude
4+import Partial.Unsafe (unsafeCrashWith)
45import Control.Monad.Eff.Console
56import Control.Monad.Eff
67
78doIt :: forall eff. Eff eff Boolean
8−doIt = return true
9+doIt = pure true
910
1011set = do
1112 log "Testing..."
1213 case 0 of
1314 0 -> doIt
14− _ -> return false
15+ _ -> pure false
1516
1617main = do
1718 b <- set
1819 case b of
1920 true -> log "Done"
21+ false -> unsafeCrashWith "Failed"
examples/passing/CaseMultipleExpressions.purs+4−2
@@ -1,19 +1,21 @@
11module Main where
22
33import Prelude
4+import Partial.Unsafe (unsafeCrashWith)
45import Control.Monad.Eff.Console
56import Control.Monad.Eff
67
78doIt :: forall eff. Eff eff Boolean
8−doIt = return true
9+doIt = pure true
910
1011set = do
1112 log "Testing..."
1213 case 42, 10 of
1314 42, 10 -> doIt
14− _ , _ -> return false
15+ _ , _ -> pure false
1516
1617main = do
1718 b <- set
1819 case b of
1920 true -> log "Done"
21+ false -> unsafeCrashWith "Failed"
examples/passing/CaseStatement.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data A = A | B | C
67
@@ -18,4 +19,4 @@ h f N a = a
1819h f a N = a
1920h f (J a) (J b) = J (f a b)
2021
21−main = Control.Monad.Eff.Console.log $ f "Done" "Failed" A
22+main = log $ f "Done" "Failed" A
examples/passing/CheckFunction.purs+2−1
@@ -1,7 +1,8 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test = ((\x -> x+1.0) >>> (\x -> x*2.0)) 4.0
67
7−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/CheckSynonymBug.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56length :: forall a. Array a -> Int
67length _ = 0
@@ -9,4 +10,4 @@ type Foo a = Array a
910
1011foo _ = length ([] :: Foo Number)
1112
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/CheckTypeClass.purs+2−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Bar a = Bar
67data Baz
@@ -14,5 +15,4 @@ foo_ x = foo ((mkBar :: forall a. (Foo a) => a -> Bar a) x)
1415mkBar :: forall a. a -> Bar a
1516mkBar _ = Bar
1617
17−main = Control.Monad.Eff.Console.log "Done"
18−
18+main = log "Done"
examples/passing/Church.purs+2−2
@@ -1,6 +1,6 @@
11module Main where
22
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
44
55type List a = forall r. r -> (a -> r -> r) -> r
66
@@ -15,4 +15,4 @@ append = \l1 l2 r f -> l2 (l1 r f) f
1515
1616test = append (cons 1 empty) (cons 2 empty)
1717
18−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/ClassRefSyntax.purs+5−9
@@ -1,13 +1,9 @@
1−module Lib (class X, go) where
2−
3− class X a where
4− go :: a -> a
5−
61module Main where
72
8− import Lib (class X, go)
3+import Lib (class X, go)
4+import Control.Monad.Eff.Console (log)
95
10− go' :: forall a. (X a) => a -> a
11− go' = go
6+go' :: forall a. (X a) => a -> a
7+go' = go
128
13− main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/ClassRefSyntax/Lib.pursnew file+4
@@ -0,0 +1,4 @@
1+module Lib (class X, go) where
2+
3+class X a where
4+ go :: a -> a
examples/passing/Collatz.purs+5−2
@@ -3,6 +3,7 @@ module Main where
33import Prelude
44import Control.Monad.Eff
55import Control.Monad.ST
6+import Control.Monad.Eff.Console (log, logShow)
67
78collatz :: Int -> Int
89collatz n = runPure (runST (do
@@ -12,7 +13,9 @@ collatz n = runPure (runST (do
1213 modifySTRef count $ (+) 1
1314 m <- readSTRef r
1415 writeSTRef r $ if m `mod` 2 == 0 then m / 2 else 3 * m + 1
15− return $ m == 1
16+ pure $ m == 1
1617 readSTRef count))
1718
18−main = Control.Monad.Eff.Console.print $ collatz 1000
19+main = do
20+ logShow $ collatz 1000
21+ log "Done"
examples/passing/Comparisons.purs+15−15
@@ -1,15 +1,15 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.Eff.Console
6−import Test.Assert
7−
8−main = do
9− assert (1.0 < 2.0)
10− assert (2.0 == 2.0)
11− assert (3.0 > 1.0)
12− assert ("a" < "b")
13− assert ("a" == "a")
14− assert ("z" > "a")
15− log "Done!"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
6+import Test.Assert
7+
8+main = do
9+ assert (1.0 < 2.0)
10+ assert (2.0 == 2.0)
11+ assert (3.0 > 1.0)
12+ assert ("a" < "b")
13+ assert ("a" == "a")
14+ assert ("z" > "a")
15+ log "Done"
examples/passing/Conditional.purs+2−2
@@ -1,9 +1,9 @@
11module Main where
22
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
44
55fns = \f -> if f true then f else \x -> x
66
77not = \x -> if x then false else true
88
9−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/Console.purs+4−2
@@ -5,9 +5,11 @@ import Control.Monad.Eff
55import Control.Monad.Eff.Console
66
77replicateM_ :: forall m a. (Monad m) => Number -> m a -> m {}
8−replicateM_ 0.0 _ = return {}
8+replicateM_ 0.0 _ = pure {}
99replicateM_ n act = do
1010 act
1111 replicateM_ (n - 1.0) act
1212
13−main = replicateM_ 10.0 (log "Hello World!")
13+main = do
14+ replicateM_ 10.0 (log "Hello World!")
15+ log "Done"
examples/passing/ConstraintInference.purs+5−2
@@ -1,7 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
5−shout = Control.Monad.Eff.Console.log <<< (<> "!") <<< show
6+shout = log <<< (_ <> "!") <<< show
67
7−main = shout "Done"
8+main = do
9+ shout "Test"
10+ log "Done"
examples/passing/ContextSimplification.purs+5−3
@@ -3,11 +3,13 @@ module Main where
33import Prelude
44import Control.Monad.Eff.Console
55
6−shout = log <<< (<> "!") <<< show
6+shout = log <<< (_ <> "!") <<< show
77
88-- Here, we should simplify the context so that only one Show
99-- constraint is added.
1010usesShowTwice true = shout
11−usesShowTwice false = print
11+usesShowTwice false = logShow
1212
13−main = usesShowTwice true "Done"
13+main = do
14+ usesShowTwice true "Test"
15+ log "Done"
examples/passing/DataAndType.purs+2−1
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data A = A B
67
78type B = A
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/DctorOperatorAlias.purs+2−8
@@ -1,17 +1,11 @@
1−module Data.List where
2−
3− data List a = Cons a (List a) | Nil
4−
5− infixr 6 Cons as :
6−
71module Main where
82
93 import Prelude (Unit, bind, (==))
104 import Control.Monad.Eff (Eff)
115 import Control.Monad.Eff.Console (CONSOLE, log)
126 import Test.Assert (ASSERT, assert')
13− import Data.List (List(..), (:))
14− import Data.List as L
7+ import List (List(..), (:))
8+ import List as L
159
1610 -- unqualified
1711 infixl 6 Cons as !
examples/passing/DctorOperatorAlias/List.pursnew file+5
@@ -0,0 +1,5 @@
1+module List where
2+
3+data List a = Cons a (List a) | Nil
4+
5+infixr 6 Cons as :
examples/passing/DeepArrayBinder.purs+2−1
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
56import Test.Assert
67
78data List a = Cons a (List a) | Nil
@@ -13,4 +14,4 @@ match2 _ = 0.0
1314main = do
1415 let result = match2 (Cons 1.0 (Cons 2.0 (Cons 3.0 (Cons 4.0 (Cons 5.0 (Cons 6.0 (Cons 7.0 (Cons 8.0 (Cons 9.0 Nil)))))))))
1516 assert' "Incorrect result!" (result == 100.0)
16− Control.Monad.Eff.Console.log "Done"
17+ log "Done"
examples/passing/DeepCase.purs+4−4
@@ -1,9 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
5−import Control.Monad.Eff
6−import Control.Monad.ST
4+import Control.Monad.Eff.Console (log, logShow)
75
86f x y =
97 let
@@ -12,4 +10,6 @@ f x y =
1210 x -> 1.0 + x * x
1311 in g + x + y
1412
15−main = print $ f 1.0 10.0
13+main = do
14+ logShow $ f 1.0 10.0
15+ log "Done"
examples/passing/Deriving.purs+5−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45import Test.Assert
56
67data V
@@ -27,5 +28,7 @@ main = do
2728 assert $ X 0 < X 1
2829 assert $ X 0 < Y "Foo"
2930 assert $ Y "Bar" < Y "Baz"
30− assert $ z == z where
31− z = Z { left: X 0, right: Y "Foo" }
31+ assert $ z == z
32+ log "Done"
33+ where
34+ z = Z { left: X 0, right: Y "Foo" }
examples/passing/Do.purs+3−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Maybe a = Nothing | Just a
67
@@ -19,7 +20,7 @@ instance bindMaybe :: Bind Maybe where
1920 bind Nothing _ = Nothing
2021 bind (Just a) f = f a
2122
22−instance monadMaybe :: Prelude.Monad Maybe
23+instance monadMaybe :: Monad Maybe
2324
2425test1 = \_ -> do
2526 Just "abc"
@@ -64,4 +65,4 @@ test10 _ = do
6465 g x = f x / 2.0
6566 Just (f 10.0)
6667
67−main = Control.Monad.Eff.Console.log "Done"
68+main = log "Done"
examples/passing/Dollar.purs+5−5
@@ -1,11 +1,11 @@
11module Main where
22
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
44
5−($) :: forall a b. (a -> b) -> a -> b
6−($) f x = f x
5+applyFn :: forall a b. (a -> b) -> a -> b
6+applyFn f x = f x
77
8−infixr 1000 $
8+infixr 1000 applyFn as $
99
1010id x = x
1111
@@ -13,4 +13,4 @@ test1 x = id $ id $ id $ id $ x
1313
1414test2 x = id id $ id x
1515
16−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/Eff.purs+4−3
@@ -3,7 +3,7 @@ module Main where
33import Prelude
44import Control.Monad.Eff
55import Control.Monad.ST
6−import Control.Monad.Eff.Console
6+import Control.Monad.Eff.Console (log, logShow)
77
88test1 = do
99 log "Line 1"
@@ -21,5 +21,6 @@ test3 = pureST (do
2121
2222main = do
2323 test1
24− Control.Monad.Eff.Console.print test2
25− Control.Monad.Eff.Console.print test3
24+ logShow test2
25+ logShow test3
26+ log "Done"
examples/passing/EmptyDataDecls.purs+2−1
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Test.Assert
5+import Control.Monad.Eff.Console (log)
56
67data Z
78data S n
@@ -15,5 +16,5 @@ cons' :: forall a n. a -> ArrayBox n a -> ArrayBox (S n) a
1516cons' x (ArrayBox xs) = ArrayBox $ append [x] xs
1617
1718main = case cons' 1 $ cons' 2 $ cons' 3 nil of
18− ArrayBox [1, 2, 3] -> Control.Monad.Eff.Console.log "Done"
19+ ArrayBox [1, 2, 3] -> log "Done"
1920 _ -> assert' "Failed" false
examples/passing/EmptyRow.purs+2−1
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Foo r = Foo { | r }
67
78test :: Foo ()
89test = Foo {}
910
10−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/EmptyTypeClass.purs+5−6
@@ -1,12 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
46
5−class PartialP
6−
7−head :: forall a. (PartialP) => Array a -> a
7+head :: forall a. Partial => Array a -> a
88head [x] = x
99
10−instance allowPartials :: PartialP
11−
12−main = Control.Monad.Eff.Console.log $ head ["Done"]
10+main :: Eff _ _
11+main = log "Done"
examples/passing/EqOrd.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56data Pair a b = Pair a b
67
@@ -12,4 +13,6 @@ instance ordPair :: (Ord a, Ord b) => Ord (Pair a b) where
1213instance eqPair :: (Eq a, Eq b) => Eq (Pair a b) where
1314 eq (Pair a1 b1) (Pair a2 b2) = a1 == a2 && b1 == b2
1415
15−main = Control.Monad.Eff.Console.print $ Pair 1.0 2.0 == Pair 1.0 2.0
16+main = do
17+ logShow $ Pair 1.0 2.0 == Pair 1.0 2.0
18+ log "Done"
examples/passing/ExplicitImportReExport.purs+11−16
@@ -1,16 +1,11 @@
1−-- from #1244
2−module Foo where
3−
4− foo :: Int
5− foo = 3
6−
7−module Bar (module Foo) where
8−
9− import Foo
10−
11−module Baz where
12−
13− import Bar (foo)
14−
15− baz :: Int
16− baz = foo
1+-- from #1244
2+module Main where
3+
4+import Prelude
5+import Control.Monad.Eff.Console (log)
6+import Bar (foo)
7+
8+baz :: Int
9+baz = foo
10+
11+main = log "Done"
examples/passing/ExplicitImportReExport/Bar.pursnew file+3
@@ -0,0 +1,3 @@
1+module Bar (module Foo) where
2+
3+import Foo
examples/passing/ExplicitImportReExport/Foo.pursnew file+4
@@ -0,0 +1,4 @@
1+module Foo where
2+
3+foo :: Int
4+foo = 3
examples/passing/ExplicitOperatorSections.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56subtractOne :: Int -> Int
67subtractOne = (_ - 1)
@@ -11,4 +12,4 @@ addOne = (1 + _)
1112named :: Int -> Int
1213named = (_ `sub` 1)
1314
14−main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/ExportExplicit.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import M1
4+import Control.Monad.Eff.Console (log)
5+
6+testX = X
7+testZ = Z
8+testFoo = foo
9+
10+main = log "Done"
examples/passing/ExportExplicit/M1.pursnew file+10
@@ -0,0 +1,10 @@
1+module M1 (X(X), Z(..), foo) where
2+
3+data X = X | Y
4+data Z = Z
5+
6+foo :: Int
7+foo = 0
8+
9+bar :: Int
10+bar = 1
examples/passing/ExportExplicit2.pursnew file+8
@@ -0,0 +1,8 @@
1+module Main where
2+
3+import M1
4+import Control.Monad.Eff.Console (log)
5+
6+testBar = bar
7+
8+main = log "Done"
examples/passing/ExportExplicit2/M1.pursnew file+7
@@ -0,0 +1,7 @@
1+module M1 (bar) where
2+
3+foo :: Int
4+foo = 0
5+
6+bar :: Int
7+bar = foo
examples/manual/passing/ExportedInstanceDeclarations.purs → examples/passing/ExportedInstanceDeclarations.pursrenamed+7−5
@@ -1,14 +1,14 @@
1−
21-- Tests that instances for non-exported classes / types do not appear in the
32-- result of `exportedDeclarations`.
4−
5−module ExportedInstanceDeclarations
3+module Main
64 ( Const(..)
7− , Foo
5+ , class Foo
86 , foo
7+ , main
98 ) where
109
1110import Prelude
11+import Control.Monad.Eff.Console (log)
1212
1313data Const a b = Const a
1414
@@ -35,9 +35,11 @@ instance nonExportedFoo2 :: (Foo NonexportedType) => Foo (a -> a) where
3535 foo = id
3636
3737-- Case 2: type class
38−instance nonExportedNonexportedType :: NonexportedClass (Const Number a) where
38+instance nonExportedNonexportedType :: NonexportedClass (Const Int a) where
3939 notExported = Const 0
4040
4141-- Case 3: instance types
4242instance constFoo :: Foo (Const NonexportedType b) where
4343 foo = Const NonexportedType
44+
45+main = log "Done"
examples/passing/ExtendedInfixOperators.purs+5−2
@@ -1,9 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import Data.Function (on)
46
57comparing :: forall a b. (Ord b) => (a -> b) -> a -> a -> Ordering
6−comparing f = compare `Data.Function.on` f
8+comparing f = compare `on` f
79
810null [] = true
911null _ = false
@@ -11,4 +13,5 @@ null _ = false
1113test = [1.0, 2.0, 3.0] `comparing null` [4.0, 5.0, 6.0]
1214
1315main = do
14− Control.Monad.Eff.Console.print test
16+ logShow test
17+ log "Done"
examples/passing/Fib.purs+14−11
@@ -1,15 +1,18 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.ST
4+import Control.Monad.Eff (whileE)
5+import Control.Monad.Eff.Console (log, logShow)
6+import Control.Monad.ST (runST, newSTRef, readSTRef, writeSTRef)
67
7−main = runST (do
8− n1 <- newSTRef 1.0
9− n2 <- newSTRef 1.0
10− whileE ((>) 1000.0 <$> readSTRef n1) $ do
11− n1' <- readSTRef n1
12− n2' <- readSTRef n2
13− writeSTRef n2 $ n1' + n2'
14− writeSTRef n1 n2'
15− Control.Monad.Eff.Console.print n2')
8+main = do
9+ runST do
10+ n1 <- newSTRef 1.0
11+ n2 <- newSTRef 1.0
12+ whileE ((>) 1000.0 <$> readSTRef n1) $ do
13+ n1' <- readSTRef n1
14+ n2' <- readSTRef n2
15+ writeSTRef n2 $ n1' + n2'
16+ writeSTRef n1 n2'
17+ logShow n2'
18+ log "Done"
examples/passing/FieldConsPuns.purs+13−10
@@ -1,10 +1,13 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7−
8−main = greet { greeting, name} where
9− greeting = "Hello"
10− name = "World"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+
6+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7+
8+main = do
9+ greet { greeting, name }
10+ log "Done"
11+ where
12+ greeting = "Hello"
13+ name = "World"
examples/passing/FieldPuns.purs+10−8
@@ -1,8 +1,10 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7−
8−main = greet { greeting: "Hello", name: "World" }
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console
5+
6+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
7+
8+main = do
9+ greet { greeting: "Hello", name: "World" }
10+ log "Done"
examples/passing/FinalTagless.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log, logShow)
45
56class E e where
67 num :: Number -> e Number
@@ -19,4 +20,6 @@ runId (Id a) = a
1920three :: Expr Number
2021three = add (num 1.0) (num 2.0)
2122
22−main = Control.Monad.Eff.Console.print $ runId three
23+main = do
24+ logShow $ runId three
25+ log "Done"
examples/passing/FunctionScope.purs+2−1
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Test.Assert
5+import Control.Monad.Eff.Console (log)
56
67mkValue :: Number -> Number
78mkValue id = id
@@ -9,4 +10,4 @@ mkValue id = id
910main = do
1011 let value = mkValue 1.0
1112 assert $ value == 1.0
12− Control.Monad.Eff.Console.log "Done"
13+ log "Done"
examples/passing/Functions.purs+2−5
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test1 = \_ -> 0.0
67
@@ -8,8 +9,4 @@ test2 = \a b -> a + b + 1.0
89
910test3 = \a -> a
1011
11−test4 = \(%%) -> 1.0 %% 2.0
12−
13−test5 = \(+++) (***) -> 1.0 +++ 2.0 *** 3.0
14−
15−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/Functions2.purs+2−1
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Test.Assert
5+import Control.Monad.Eff.Console (log)
56
67test :: forall a b. a -> b -> a
78test = \const _ -> const
@@ -9,4 +10,4 @@ test = \const _ -> const
910main = do
1011 let value = test "Done" {}
1112 assert' "Not done" $ value == "Done"
12− Control.Monad.Eff.Console.log "Done"
13+ log "Done"
examples/passing/Generalization1.purs+4−3
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console (print)
4+import Control.Monad.Eff.Console (logShow, log)
55
66main = do
7− print (sum 1.0 2.0)
8− print (sum 1 2)
7+ logShow (sum 1.0 2.0)
8+ logShow (sum 1 2)
9+ log "Done"
910
1011sum x y = x + y
examples/passing/Guards.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56collatz = \x -> case x of
67 y | y `mod` 2.0 == 0.0 -> y / 2.0
@@ -26,4 +27,4 @@ testIndentation x y | x > 0.0
2627 | otherwise
2728 = y - x
2829
29−main = Control.Monad.Eff.Console.log $ min "Done" "ZZZZ"
30+main = log $ min "Done" "ZZZZ"
examples/passing/IfThenElseMaybe.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Maybe a = Nothing | Just a
67
@@ -8,4 +9,4 @@ test1 = if true then Just 10 else Nothing
89
910test2 = if true then Nothing else Just 10
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/ImplicitEmptyImport.purs+4−3
@@ -1,8 +1,9 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56main = do
6− Control.Monad.Eff.Console.log "Hello"
7− Control.Monad.Eff.Console.log "Goodbye"
8− Control.Monad.Eff.Console.log "Done"
7+ log "Hello"
8+ log "Goodbye"
9+ log "Done"
examples/passing/Import.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+import M2
4+import Control.Monad.Eff.Console (log)
5+
6+main = log "Done"
examples/passing/Import/M1.pursnew file+8
@@ -0,0 +1,8 @@
1+module M1 where
2+
3+import Prelude ()
4+
5+id :: forall a. a -> a
6+id = \x -> x
7+
8+foo = id
examples/passing/Import/M2.pursnew file+6
@@ -0,0 +1,6 @@
1+module M2 where
2+
3+import Prelude ()
4+import M1
5+
6+main = \_ -> foo 42
examples/passing/ImportExplicit.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+import M1 (X(..))
4+import Control.Monad.Eff.Console (log)
5+
6+testX :: X
7+testX = X
8+testY = Y
9+
10+main = log "Done"
examples/passing/ImportExplicit/M1.pursnew file+4
@@ -0,0 +1,4 @@
1+module M1 where
2+
3+data X = X | Y
4+data Z = Z
examples/passing/ImportHiding.purs+3−2
@@ -3,7 +3,7 @@ module Main where
33import Control.Monad.Eff.Console
44import Prelude hiding (
55 show, -- a value
6− Show, -- a type class
6+ class Show, -- a type class
77 Unit(..) -- a constructor
88 )
99
@@ -15,4 +15,5 @@ class Show a where
1515data Unit = X | Y
1616
1717main = do
18− print show
18+ logShow show
19+ log "Done"
examples/passing/ImportQualified.pursnew file+8
@@ -0,0 +1,8 @@
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff
5+import M1
6+import Control.Monad.Eff.Console as C
7+
8+main = C.log (log "Done")
examples/passing/ImportQualified/M1.pursnew file+3
@@ -0,0 +1,3 @@
1+module M1 where
2+
3+log x = x
examples/passing/InferRecFunWithConstrainedArgument.purs+4−1
@@ -1,8 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56test 100 = 100
67test n = test(1 + n)
78
8−main = Control.Monad.Eff.Console.print $ test 0
9+main = do
10+ logShow (test 0)
11+ log "Done"
examples/passing/InstanceBeforeClass.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56instance fooNumber :: Foo Number where
67 foo = 0.0
@@ -8,4 +9,4 @@ instance fooNumber :: Foo Number where
89class Foo a where
910 foo :: a
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/IntAndChar.purs+2−1
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
56import Test.Assert
67
78f 1 = 1
@@ -15,4 +16,4 @@ main = do
1516 assert $ f 0 == 0
1617 assert $ g 'a' == 'a'
1718 assert $ g 'b' == 'b'
18− Control.Monad.Eff.Console.log "Done"
19+ log "Done"
examples/passing/JSReserved.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56yield = 0
67member = 1
@@ -9,4 +10,4 @@ public = \return -> return
910
1011this catch = catch
1112
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/KindedType.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type Star2Star f = f :: * -> *
67
@@ -30,4 +31,4 @@ class Clazz (a :: *) where
3031instance clazzString :: Clazz String where
3132 def = "test"
3233
33−main = Control.Monad.Eff.Console.log "Done"
34+main = log "Done"
examples/passing/LargeSumType.purs+4−2
@@ -1,5 +1,7 @@
11module Main where
2−
2+
3+import Control.Monad.Eff.Console (log)
4+
35data Large = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
46
57explode A A = "A"
@@ -30,4 +32,4 @@ explode Y Y = "Y"
3032explode Z Z = "Z"
3133explode _ _ = ""
3234
33−main = Control.Monad.Eff.Console.log "Done"
35+main = log "Done"
examples/passing/Let.purs+14−9
@@ -1,7 +1,9 @@
11module Main where
22
33import Prelude
4+import Partial.Unsafe (unsafePartial)
45import Control.Monad.Eff
6+import Control.Monad.Eff.Console (log, logShow)
57import Control.Monad.ST
68
79test1 x = let
@@ -17,8 +19,9 @@ test2 x y =
1719test3 = let f x y z = x + y + z in
1820 f 1.0 2.0 3.0
1921
20−test4 = let f x [y, z] = x y z in
21− f (+) [1.0, 2.0]
22+test4 = let
23+ f x [y, z] = x y z
24+ in f (+) [1.0, 2.0]
2225
2326test5 = let
2427 f x | x > 0.0 = g (x / 2.0) + 1.0
@@ -43,11 +46,13 @@ test10 _ =
4346 g x = f x / 2.0
4447 in f 10.0
4548
49+main :: Eff _ _
4650main = do
47− Control.Monad.Eff.Console.print (test1 1.0)
48− Control.Monad.Eff.Console.print (test2 1.0 2.0)
49− Control.Monad.Eff.Console.print test3
50− Control.Monad.Eff.Console.print test4
51− Control.Monad.Eff.Console.print test5
52− Control.Monad.Eff.Console.print test7
53− Control.Monad.Eff.Console.print (test8 100.0)
51+ logShow (test1 1.0)
52+ logShow (test2 1.0 2.0)
53+ logShow test3
54+ unsafePartial (logShow test4)
55+ logShow test5
56+ logShow test7
57+ logShow (test8 100.0)
58+ log "Done"
examples/passing/Let2.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56test =
67 let f :: Number -> Boolean
@@ -14,4 +15,6 @@ test =
1415 x = f 1.0
1516 in not x
1617
17−main = Control.Monad.Eff.Console.print test
18+main = do
19+ logShow test
20+ log "Done"
examples/passing/LetInInstance.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class Foo a where
67 foo :: a -> String
@@ -11,4 +12,4 @@ instance fooString :: Foo String where
1112 go :: String -> String
1213 go s = s
1314
14−main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/LiberalTypeSynonyms.purs+4−3
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type Reader = (->) String
67
@@ -9,13 +10,13 @@ foo s = s
910
1011type AndFoo r = (foo :: String | r)
1112
12−getFoo :: forall r. Prim.Object (AndFoo r) -> String
13+getFoo :: forall r. Prim.Record (AndFoo r) -> String
1314getFoo o = o.foo
1415
1516type F r = { | r } -> { | r }
1617
1718f :: (forall r. F r) -> String
1819f g = case g { x: "Hello" } of
19− { x = x } -> x
20+ { x: x } -> x
2021
21−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/MPTCs.purs+3−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class NullaryTypeClass where
67 greeting :: String
@@ -14,7 +15,7 @@ class Coerce a b where
1415instance coerceRefl :: Coerce a a where
1516 coerce a = a
1617
17−instance coerceShow :: (Prelude.Show a) => Coerce a String where
18+instance coerceShow :: Show a => Coerce a String where
1819 coerce = show
1920
20−main = Control.Monad.Eff.Console.log "Done"
21+main = log "Done"
examples/passing/Match.purs+2−1
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Foo a = Foo
67
78foo = \f -> case f of Foo -> "foo"
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/Module.pursnew file+7
@@ -0,0 +1,7 @@
1+module Main where
2+
3+import M1
4+import M2
5+import Control.Monad.Eff.Console (log)
6+
7+main = log "Done"
examples/passing/Module/M1.pursnew file+14
@@ -0,0 +1,14 @@
1+module M1 where
2+
3+import Prelude
4+
5+data Foo = Foo String
6+
7+foo :: Foo -> String
8+foo = \f -> case f of Foo s -> s <> "foo"
9+
10+bar :: Foo -> String
11+bar = foo
12+
13+incr :: Int -> Int
14+incr x = x + 1
examples/passing/Module/M2.pursnew file+10
@@ -0,0 +1,10 @@
1+module M2 where
2+
3+import Prelude
4+import M1 as M1
5+
6+baz :: M1.Foo -> String
7+baz = M1.foo
8+
9+match :: M1.Foo -> String
10+match = \f -> case f of M1.Foo s -> s <> "foo"
examples/passing/ModuleDeps.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+import M1
4+import Control.Monad.Eff.Console (log)
5+
6+main = log "Done"
examples/passing/ModuleDeps/M1.pursnew file+5
@@ -0,0 +1,5 @@
1+module M1 where
2+
3+import M2 as M2
4+
5+foo = M2.bar
examples/passing/ModuleDeps/M2.pursnew file+5
@@ -0,0 +1,5 @@
1+module M2 where
2+
3+import M3 as M3
4+
5+bar = M3.baz
examples/passing/ModuleDeps/M3.pursnew file+3
@@ -0,0 +1,3 @@
1+module M3 where
2+
3+baz = 1
examples/passing/ModuleExport.purs+6−7
@@ -1,9 +1,8 @@
1−module A (module Prelude) where
2− import Prelude
3−
41module Main where
5− import Control.Monad.Eff.Console
6− import A
72
8− main = do
9− print (show 1.0)
3+import Control.Monad.Eff.Console (log, logShow)
4+import A
5+
6+main = do
7+ logShow (show 1.0)
8+ log "Done"
examples/passing/ModuleExport/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportDupes.purs+3−11
@@ -1,14 +1,5 @@
1−module A (module Prelude) where
2− import Prelude
3−
4−module B (module Prelude) where
5− import Prelude
6−
7−module C (module Prelude, module A) where
8− import Prelude
9− import A
10−
111module Main where
2+
123 import Control.Monad.Eff.Console
134 import A
145 import B
@@ -16,4 +7,5 @@ module Main where
167 import Prelude
178
189 main = do
19− print (show 1.0)
10+ logShow (show 1.0)
11+ log "Done"
examples/passing/ModuleExportDupes/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportDupes/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportDupes/C.pursnew file+4
@@ -0,0 +1,4 @@
1+module C (module Prelude, module A) where
2+
3+import Prelude
4+import A
examples/passing/ModuleExportExcluded.purs+8−11
@@ -1,14 +1,11 @@
1−module A (module Prelude, foo) where
2− import Prelude
3−
4− foo :: Number -> Number
5− foo _ = 0.0
6−
71module Main where
8− import Control.Monad.Eff.Console
9− import A (foo)
102
11− otherwise = false
3+import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import A (foo)
6+
7+otherwise = false
128
13− main = do
14− print "1.0"
9+main = do
10+ logShow "1.0"
11+ log "Done"
examples/passing/ModuleExportExcluded/A.pursnew file+6
@@ -0,0 +1,6 @@
1+module A (module Prelude, foo) where
2+
3+import Prelude
4+
5+foo :: Number -> Number
6+foo _ = 0.0
examples/passing/ModuleExportQualified.purs+7−7
@@ -1,9 +1,9 @@
1−module A (module Prelude) where
2− import Prelude
3−
41module Main where
5− import Control.Monad.Eff.Console
6− import qualified A as B
72
8− main = do
9− print (B.show 1.0)
3+import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
5+import A as B
6+
7+main = do
8+ logShow (B.show 1.0)
9+ log "Done"
examples/passing/ModuleExportQualified/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A (module Prelude) where
2+
3+import Prelude
examples/passing/ModuleExportSelf.purs+8−11
@@ -1,14 +1,11 @@
1−module A (module A, module Prelude) where
2− import Prelude
3−
4− type Foo = Boolean
5−
61module Main where
7− import Control.Monad.Eff.Console
8− import A
92
10− bar :: Foo
11− bar = true
3+import Control.Monad.Eff.Console
4+import A
5+
6+bar :: Foo
7+bar = true
128
13− main = do
14− print (show bar)
9+main = do
10+ logShow (show bar)
11+ log "Done"
examples/passing/ModuleExportSelf/A.pursnew file+5
@@ -0,0 +1,5 @@
1+module A (module A, module Prelude) where
2+
3+import Prelude
4+
5+type Foo = Boolean
examples/passing/Monad.purs+2−2
@@ -1,6 +1,6 @@
11module Main where
22
3−import Prelude ()
3+import Control.Monad.Eff.Console (log)
44
55type Monad m = { return :: forall a. a -> m a
66 , bind :: forall a b. m a -> (a -> m b) -> m b }
@@ -29,4 +29,4 @@ test1 = test id
2929
3030test2 = test maybe
3131
32−main = Control.Monad.Eff.Console.log "Done"
32+main = log "Done"
examples/passing/MonadState.purs+3−1
@@ -58,4 +58,6 @@ modify f =
5858 same :: forall a. (a -> a) -> (a -> a)
5959 same = id
6060
61−main = print $ runState 0 (modify (+ 1))
61+main = do
62+ logShow $ runState 0 (modify (_ + 1))
63+ log "Done"
examples/passing/MultiArgFunctions.purs+3−3
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import Data.Function
4+import Data.Function.Uncurried
55import Control.Monad.Eff
66import Control.Monad.Eff.Console
77
@@ -23,5 +23,5 @@ main = do
2323 runFn8 (mkFn8 $ \a b c d e f g h -> log $ show [a, b, c, d, e, f, g, h]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2424 runFn9 (mkFn9 $ \a b c d e f g h i -> log $ show [a, b, c, d, e, f, g, h, i]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2525 runFn10 (mkFn10 $ \a b c d e f g h i j-> log $ show [a, b, c, d, e, f, g, h, i, j]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
26− print $ runFn2 g 0.0 0.0
27− log "Done!"
26+ logShow $ runFn2 g 0.0 0.0
27+ log "Done"
examples/passing/MutRec.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56f 0.0 = 0.0
67f x = g x + 0.0
@@ -16,4 +17,4 @@ evenToNumber (Even n) = oddToNumber n + 0.0
1617
1718oddToNumber (Odd n) = evenToNumber n + 0.0
1819
19−main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/MutRec2.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data A = A B
67
@@ -16,4 +17,4 @@ g b = case b of B a -> f a
1617showN :: A -> S
1718showN a = f a
1819
19−main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/MutRec3.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data A = A B
67
@@ -16,4 +17,4 @@ g b = case b of B a -> f a
1617showN :: A -> S
1718showN a = f a
1819
19−main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/NamedPatterns.purs+3−2
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56foo = \x -> case x of
6− y@{ foo = "Foo" } -> y
7+ y@{ foo: "Foo" } -> y
78 y -> y
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NegativeBinder.purs+2−1
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test :: Number -> Boolean
67test -1.0 = false
78test _ = true
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NegativeIntInRange.purs+2−1
@@ -1,8 +1,9 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56n :: Int
67n = -2147483648
78
8−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/Nested.purs+2−1
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Extend r a = Extend { prev :: r a, next :: a }
67
78data Matrix r a = Square (r (r a)) | Bigger (Matrix (Extend r) a)
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NestedTypeSynonyms.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type X = String
67type Y = X -> X
@@ -8,4 +9,4 @@ type Y = X -> X
89fn :: Y
910fn a = a
1011
11−main = Control.Monad.Eff.Console.print (fn "Done")
12+main = log (fn "Done")
examples/passing/NestedWhere.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56f x = g x
67 where
@@ -9,4 +10,4 @@ f x = g x
910 go x = go1 (x - 1.0)
1011 go1 x = go x
1112
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/Newtype.purs+5−5
@@ -7,17 +7,17 @@ import Control.Monad.Eff.Console
77newtype Thing = Thing String
88
99instance showThing :: Show Thing where
10− show (Thing x) = "Thing " ++ show x
10+ show (Thing x) = "Thing " <> show x
1111
1212newtype Box a = Box a
1313
1414instance showBox :: (Show a) => Show (Box a) where
15− show (Box x) = "Box " ++ show x
15+ show (Box x) = "Box " <> show x
1616
1717apply f x = f x
1818
1919main = do
20− print $ Thing "hello"
21− print $ Box 42.0
22− print $ apply Box 9000.0
20+ logShow $ Thing "hello"
21+ logShow $ Box 42.0
22+ logShow $ apply Box 9000.0
2323 log "Done"
examples/passing/NewtypeWithRecordUpdate.purs+2−2
@@ -5,9 +5,9 @@ module Main where
55import Prelude
66import Control.Monad.Eff.Console
77
8−newtype NewType a = NewType (Object a)
8+newtype NewType a = NewType (Record a)
99
10−rec1 :: Object (a :: Number, b :: Number, c:: Number)
10+rec1 :: Record (a :: Number, b :: Number, c:: Number)
1111rec1 = { a: 0.0, b: 0.0, c: 0.0 }
1212
1313rec2 :: NewType (a :: Number, b :: Number, c :: Number)
examples/passing/NonConflictingExports.purs+5−9
@@ -1,14 +1,10 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
61-- No failure here as the export `thing` only refers to Main.thing
72module Main (thing, main) where
83
9− import A
4+import A
5+import Control.Monad.Eff.Console (log)
106
11− thing :: Int
12− thing = 2
7+thing :: Int
8+thing = 2
139
14− main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/NonConflictingExports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/NumberLiterals.pursnew file+39
@@ -0,0 +1,39 @@
1+module Main where
2+
3+-- See issue #2115.
4+
5+import Prelude
6+import Test.Assert (assert')
7+import Control.Monad.Eff.Console (log)
8+
9+main = do
10+ test "0.17" 0.17
11+ test "0.25996181067141905" 0.25996181067141905
12+ test "0.3572019862807257" 0.3572019862807257
13+ test "0.46817723004874223" 0.46817723004874223
14+ test "0.9640035681058178" 0.9640035681058178
15+ test "4.23808622486133" 4.23808622486133
16+ test "4.540362294799751" 4.540362294799751
17+ test "5.212384849884261" 5.212384849884261
18+ test "13.958257048123212" 13.958257048123212
19+ test "32.96176575630599" 32.96176575630599
20+ test "38.47735512322269" 38.47735512322269
21+
22+ test "10000000000" 1e10
23+ test "10000000000" 1.0e10
24+ test "0.00001" 1e-5
25+ test "0.00001" 1.0e-5
26+ test "1.5339794352098402e-118" 1.5339794352098402e-118
27+ test "2.108934760892056e-59" 2.108934760892056e-59
28+ test "2.250634744599241e-19" 2.250634744599241e-19
29+ test "5.960464477539063e-8" 5.960464477539063e-8
30+ test "5e-324" 5e-324
31+ test "5e-324" 5.0e-324
32+
33+ log "Done"
34+
35+test str num =
36+ if (show num == str)
37+ then pure unit
38+ else flip assert' false $
39+ "Expected " <> show str <> ", got " <> show (show num) <> "."
examples/passing/ObjectGetter.purs+5−4
@@ -1,13 +1,14 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56getX = _.x
67
78point = { x: 1.0, y: 0.0 }
89
910main = do
10− Control.Monad.Eff.Console.print $ getX point
11− Control.Monad.Eff.Console.log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
12− Control.Monad.Eff.Console.log $ (_.x >>> _.y) { x: { y: "Nested" } }
13− Control.Monad.Eff.Console.log $ _.value { value: "Done!" }
11+ logShow $ getX point
12+ log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
13+ log $ (_.x >>> _.y) { x: { y: "Nested" } }
14+ log $ _.value { value: "Done" }
examples/passing/ObjectSynonym.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type Inner = Number
67
@@ -12,4 +13,4 @@ type Outer = { inner :: Inner }
1213outer :: Outer
1314outer = { inner: inner }
1415
15−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/ObjectUpdate.purs+23−20
@@ -1,20 +1,23 @@
1−module Main where
2−
3−import Prelude
4−
5−update1 = \o -> o { foo = "Foo" }
6−
7−update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
8−update2 = \o -> o { foo = "Foo" }
9−
10−replace = \o -> case o of
11− { foo = "Foo" } -> o { foo = "Bar" }
12− { foo = "Bar" } -> o { bar = "Baz" }
13− o -> o
14−
15−polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
16−polyUpdate = \o -> o { foo = "Foo" }
17−
18−inferPolyUpdate = \o -> o { foo = "Foo" }
19−
20−main = Control.Monad.Eff.Console.log ((update1 {foo: ""}).foo)
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+update1 = \o -> o { foo = "Foo" }
7+
8+update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
9+update2 = \o -> o { foo = "Foo" }
10+
11+replace = \o -> case o of
12+ { foo: "Foo" } -> o { foo = "Bar" }
13+ { foo: "Bar" } -> o { bar = "Baz" }
14+ o -> o
15+
16+polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
17+polyUpdate = \o -> o { foo = "Foo" }
18+
19+inferPolyUpdate = \o -> o { foo = "Foo" }
20+
21+main = do
22+ log ((update1 {foo: ""}).foo)
23+ log "Done"
examples/passing/ObjectUpdate2.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type X r = { | r }
67
@@ -14,4 +15,4 @@ test = blah x
1415 { baz = "blah"
1516 }
1617
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/ObjectUpdater.purs+3−1
@@ -6,7 +6,7 @@ import Control.Monad.Eff.Console
66import Test.Assert
77
88getValue :: forall e. Eff (| e) Boolean
9−getValue = return true
9+getValue = pure true
1010
1111main = do
1212 let record = { value: false }
@@ -22,3 +22,5 @@ main = do
2222
2323 let record2 = (_ { x = _ }) { x: 0.0 } 10.0
2424 assert $ record2.x == 10.0
25+
26+ log "Done"
examples/passing/ObjectWildcards.purs+4−4
@@ -8,13 +8,13 @@ import Test.Assert
88mkRecord = { foo: _, bar: _, baz: "baz" }
99
1010getValue :: forall e. Eff (| e) Boolean
11−getValue = return true
11+getValue = pure true
1212
1313main = do
1414 obj <- { value: _ } <$> getValue
15− print obj.value
15+ logShow obj.value
1616 let x = 1.0
17− point <- { x: _, y: x } <$> return 2.0
17+ point <- { x: _, y: x } <$> pure 2.0
1818 assert $ point.x == 2.0
1919 assert $ point.y == 1.0
20− log (mkRecord 1.0 "Done!").bar
20+ log (mkRecord 1.0 "Done").bar
examples/passing/Objects.purs+3−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude hiding (append)
4+import Control.Monad.Eff.Console (log)
45
56test = \x -> x.foo + x.bar + 1.0
67
@@ -25,11 +26,11 @@ test4 = test2 weirdObj
2526 weirdObj = { "!@#": 1.0 }
2627
2728test5 = case { "***": 1.0 } of
28− { "***" = n } -> n
29+ { "***": n } -> n
2930
3031test6 = case { "***": 1.0 } of
3132 { "***": n } -> n
3233
3334test7 {a: snoog , b : blah } = blah
3435
35−main = Control.Monad.Eff.Console.log "Done"
36+main = log "Done"
examples/passing/OneConstructor.purs+2−1
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data One a = One a
67
78one' (One a) = a
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/OperatorAliasElsewhere.purs−5
@@ -1,8 +1,3 @@
1−module Def where
2−
3−what :: forall a b. a -> b -> a
4−what a _ = a
5−
61module Main where
72
83import Prelude
examples/passing/OperatorAliasElsewhere/Def.pursnew file+4
@@ -0,0 +1,4 @@
1+module Def where
2+
3+what :: forall a b. a -> b -> a
4+what a _ = a
examples/passing/OperatorAssociativity.purs+25−25
@@ -1,25 +1,25 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff
5−import Control.Monad.Eff.Console
6−import Test.Assert
7−
8−bug :: Number -> Number -> Number
9−bug a b = 0.0 - (a - b)
10−
11−main = do
12− assert (bug 0.0 2.0 == 2.0)
13− assert (0.0 - (0.0 - 2.0) == 2.0)
14− assert (0.0 - (0.0 + 2.0) == -2.0)
15− assert (6.0 / (3.0 * 2.0) == 1.0)
16− assert ((6.0 / 3.0) * 2.0 == 4.0)
17− assert (not (1.0 < 0.0) == true)
18− assert (not ((negate 1.0) < 0.0) == false)
19− assert (negate (1.0 + 10.0) == -11.0)
20− assert (2.0 * 3.0 / 4.0 == 1.5)
21− assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
22− assert (1.0 + 10.0 - 5.0 == 6.0)
23− assert (1.0 + 10.0 * 5.0 == 51.0)
24− assert (10.0 * 5.0 - 1.0 == 49.0)
25− log "Success!"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
6+import Test.Assert
7+
8+bug :: Number -> Number -> Number
9+bug a b = 0.0 - (a - b)
10+
11+main = do
12+ assert (bug 0.0 2.0 == 2.0)
13+ assert (0.0 - (0.0 - 2.0) == 2.0)
14+ assert (0.0 - (0.0 + 2.0) == -2.0)
15+ assert (6.0 / (3.0 * 2.0) == 1.0)
16+ assert ((6.0 / 3.0) * 2.0 == 4.0)
17+ assert (not (1.0 < 0.0) == true)
18+ assert (not ((negate 1.0) < 0.0) == false)
19+ assert (negate (1.0 + 10.0) == -11.0)
20+ assert (2.0 * 3.0 / 4.0 == 1.5)
21+ assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
22+ assert (1.0 + 10.0 - 5.0 == 6.0)
23+ assert (1.0 + 10.0 * 5.0 == 51.0)
24+ assert (10.0 * 5.0 - 1.0 == 49.0)
25+ log "Done"
examples/passing/OperatorInlining.purs+23−22
@@ -1,47 +1,48 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (logShow, log)
55
66main = do
77
88 -- semiringNumber
9− print (1.0 + 2.0)
10− print (1.0 * 2.0)
9+ logShow (1.0 + 2.0)
10+ logShow (1.0 * 2.0)
1111
1212 -- ringNumber
13− print (1.0 - 2.0)
14− print (negate 1.0)
13+ logShow (1.0 - 2.0)
14+ logShow (negate 1.0)
1515
1616 -- moduleSemiringNumber
17− print (1.0 / 2.0)
17+ logShow (1.0 / 2.0)
1818
1919 -- ordNumber
20− print (1.0 > 2.0)
21− print (1.0 < 2.0)
22− print (1.0 <= 2.0)
23− print (1.0 >= 2.0)
24− print (1.0 == 2.0)
20+ logShow (1.0 > 2.0)
21+ logShow (1.0 < 2.0)
22+ logShow (1.0 <= 2.0)
23+ logShow (1.0 >= 2.0)
24+ logShow (1.0 == 2.0)
2525
2626 -- eqNumber
27− print (1.0 == 2.0)
28− print (1.0 /= 2.0)
27+ logShow (1.0 == 2.0)
28+ logShow (1.0 /= 2.0)
2929
3030 -- eqString
31− print ("foo" == "bar")
32− print ("foo" /= "bar")
31+ logShow ("foo" == "bar")
32+ logShow ("foo" /= "bar")
3333
3434 -- eqBoolean
35− print (true == false)
36− print (true /= false)
35+ logShow (true == false)
36+ logShow (true /= false)
3737
3838 -- semigroupString
39− print ("foo" ++ "bar")
40− print ("foo" <> "bar")
39+ logShow ("foo" <> "bar")
4140
4241 -- latticeBoolean
43− print (top && true)
44− print (bottom || false)
42+ logShow (top && true)
43+ logShow (bottom || false)
4544
4645 -- complementedLatticeBoolean
47− print (not true)
46+ logShow (not true)
47+
48+ log "Done"
examples/passing/OperatorSections.purs+11−10
@@ -1,17 +1,18 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45import Test.Assert
56
67main = do
7− assert $ (/ 2.0) 4.0 == 2.0
8− assert $ (2.0 /) 4.0 == 0.5
9− assert $ (`const` 1.0) 2.0 == 2.0
10− assert $ (1.0 `const`) 2.0 == 1.0
8+ assert $ (_ / 2.0) 4.0 == 2.0
9+ assert $ (2.0 / _) 4.0 == 0.5
10+ assert $ (_ `const` 1.0) 2.0 == 2.0
11+ assert $ (1.0 `const` _) 2.0 == 1.0
1112 let foo = { x: 2.0 }
12− assert $ (/ foo.x) 4.0 == 2.0
13− assert $ (foo.x /) 4.0 == 0.5
14− let (//) x y = x.x / y.x
15− assert $ (// foo { x = 4.0 }) { x: 4.0 } == 1.0
16− assert $ (foo { x = 4.0 } //) { x: 4.0 } == 1.0
17− Control.Monad.Eff.Console.log "Done!"
13+ assert $ (_ / foo.x) 4.0 == 2.0
14+ assert $ (foo.x / _) 4.0 == 0.5
15+ let div x y = x.x / y.x
16+ assert $ (_ `div` foo { x = 4.0 }) { x: 4.0 } == 1.0
17+ assert $ (foo { x = 4.0 } `div` _) { x: 4.0 } == 1.0
18+ log "Done"
examples/passing/Operators.purs+22−30
@@ -1,16 +1,17 @@
11module Main where
22
33import Prelude
4+import Other (foo)
5+import Other as Other
46import Control.Monad.Eff
57import Control.Monad.Eff.Console
68
7−(?!) :: forall a. a -> a -> a
8−(?!) x _ = x
9+op1 :: forall a. a -> a -> a
10+op1 x _ = x
911
10−bar :: String -> String -> String
11−bar = \s1 s2 -> s1 ++ s2
12+infix 4 op1 as ?!
1213
13−test1 :: forall n. (Num n) => n -> n -> (n -> n -> n) -> n
14+test1 :: forall n. (Semiring n) => n -> n -> (n -> n -> n) -> n
1415test1 x y z = x * y + z x y
1516
1617test2 = (\x -> x.foo false) { foo : \_ -> 1.0 }
@@ -21,40 +22,39 @@ k = \x -> \y -> x
2122
2223test4 = 1 `k` 2
2324
24−infixl 5 %%
25+op2 :: Number -> Number -> Number
26+op2 x y = x * y + y
2527
26−(%%) :: Number -> Number -> Number
27−(%%) x y = x * y + y
28+infixl 5 op2 as %%
2829
2930test5 = 1.0 %% 2.0 %% 3.0
3031
3132test6 = ((\x -> x) `k` 2.0) 3.0
3233
33−(<+>) :: String -> String -> String
34−(<+>) = \s1 s2 -> s1 ++ s2
34+op3 :: String -> String -> String
35+op3 = \s1 s2 -> s1 <> s2
36+
37+infix 4 op3 as <+>
3538
3639test7 = "Hello" <+> "World!"
3740
38−(@@) :: forall a b. (a -> b) -> a -> b
39−(@@) = \f x -> f x
41+op4 :: forall a b. (a -> b) -> a -> b
42+op4 = \f x -> f x
4043
41−foo :: String -> String
42−foo = \s -> s
44+infix 4 op4 as @@
4345
4446test8 = foo @@ "Hello World"
4547
46−test9 = Main.foo @@ "Hello World"
47−
48−test10 = "Hello" `Main.bar` "World"
48+test9 = Other.foo @@ "Hello World"
4949
50−(...) :: forall a. Array a -> Array a -> Array a
51−(...) = \as -> \bs -> as
50+test10 = "Hello" `Other.baz` "World"
5251
53−test11 = [1.0, 2.0, 0.0] ... [4.0, 5.0, 6.0]
52+op5 :: forall a. Array a -> Array a -> Array a
53+op5 = \as -> \bs -> as
5454
55−test12 (<%>) a b = a <%> b
55+infix 4 op5 as ...
5656
57−test13 = \(<%>) a b -> a <%> b
57+test11 = [1.0, 2.0, 0.0] ... [4.0, 5.0, 6.0]
5858
5959test14 :: Number -> Number -> Boolean
6060test14 a b = a < b
@@ -71,11 +71,6 @@ test18 = negate $ negate 1.0
7171test19 :: Number
7272test19 = negate $ negate (-1.0)
7373
74−test20 :: Number
75−test20 = 1.0 @ 2.0
76− where
77− (@) x y = x + y * y
78−
7974main = do
8075 let t1 = test1 1.0 2.0 (\x y -> x + y)
8176 let t2 = test2
@@ -88,12 +83,9 @@ main = do
8883 let t9 = test9
8984 let t10 = test10
9085 let t11 = test11
91− let t12 = test12 k 1.0 2.0
92− let t13 = test13 k 1.0 2.0
9386 let t14 = test14 1.0 2.0
9487 let t15 = test15 1.0 2.0
9588 let t17 = test17
9689 let t18 = test18
9790 let t19 = test19
98− let t20 = test20
9991 log "Done"
examples/passing/Operators/Other.pursnew file+7
@@ -0,0 +1,7 @@
1+module Other where
2+
3+foo :: String -> String
4+foo s = s
5+
6+baz :: String -> String -> String
7+baz s _ = s
examples/passing/OptimizerBug.purs+2−1
@@ -1,9 +1,10 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56x a = 1.0 + y a
67
78y a = x a
89
9−main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/OptionalQualified.purs+2−3
@@ -1,7 +1,6 @@
11module Main where
22
3−-- qualified import with the "qualified" keyword
4−import qualified Prelude as P
3+import Prelude as P
54
65-- qualified import without the "qualified" keyword
76import Control.Monad.Eff.Console as Console
@@ -9,5 +8,5 @@ import Control.Monad.Eff.Console as Console
98bind = P.bind
109
1110main = do
12− message <- P.return "success!"
11+ message <- P.pure "Done"
1312 Console.log message
examples/passing/OverlappingInstances.purs+17−13
@@ -1,13 +1,17 @@
1−module Main where
2−
3−import Prelude
4−
5−data A = A
6−
7−instance showA1 :: Show A where
8− show A = "Instance 1"
9−
10−instance showA2 :: Show A where
11− show A = "Instance 2"
12−
13−main = Test.Assert.assert $ show A == "Instance 1"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
7+data A = A
8+
9+instance showA1 :: Show A where
10+ show A = "Instance 1"
11+
12+instance showA2 :: Show A where
13+ show A = "Instance 2"
14+
15+main = do
16+ assert $ show A == "Instance 1"
17+ log "Done"
examples/passing/OverlappingInstances2.purs+27−23
@@ -1,23 +1,27 @@
1−module Main where
2−
3−import Prelude
4−
5−data A = A | B
6−
7−instance eqA1 :: Eq A where
8− eq A A = true
9− eq B B = true
10− eq _ _ = false
11−
12−instance eqA2 :: Eq A where
13− eq _ _ = true
14−
15−instance ordA :: Ord A where
16− compare A B = LT
17− compare B A = GT
18− compare _ _ = EQ
19−
20−test :: forall a. (Ord a) => a -> a -> String
21−test x y = show $ x == y
22−
23−main = Test.Assert.assert $ test A B == "false"
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
7+data A = A | B
8+
9+instance eqA1 :: Eq A where
10+ eq A A = true
11+ eq B B = true
12+ eq _ _ = false
13+
14+instance eqA2 :: Eq A where
15+ eq _ _ = true
16+
17+instance ordA :: Ord A where
18+ compare A B = LT
19+ compare B A = GT
20+ compare _ _ = EQ
21+
22+test :: forall a. (Ord a) => a -> a -> String
23+test x y = show $ x == y
24+
25+main = do
26+ assert $ test A B == "false"
27+ log "Done"
examples/passing/OverlappingInstances3.purs+20−16
@@ -1,16 +1,20 @@
1−module Main where
2−
3−import Prelude
4−
5−class Foo a
6−
7−instance foo1 :: Foo Number
8−
9−instance foo2 :: Foo Number
10−
11−test :: forall a. (Foo a) => a -> a
12−test a = a
13−
14−test1 = test 0.0
15−
16−main = Test.Assert.assert (test1 == 0.0)
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+import Test.Assert (assert)
6+
7+class Foo a
8+
9+instance foo1 :: Foo Number
10+
11+instance foo2 :: Foo Number
12+
13+test :: forall a. (Foo a) => a -> a
14+test a = a
15+
16+test1 = test 0.0
17+
18+main = do
19+ assert (test1 == 0.0)
20+ log "Done"
examples/passing/ParensInTypedBinder.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff (Eff)
5+import Control.Monad.Eff.Console (CONSOLE, log)
6+
7+foo :: Array Int
8+foo = do
9+ xss :: Array (Array Int) <- [[[1,2,3], [4, 5]], [[6]]]
10+ xs :: Array Int <- xss
11+ xs
12+
13+main ::
14+ forall eff.
15+ Eff
16+ ( console :: CONSOLE
17+ | eff
18+ )
19+ Unit
20+main = log "Done"
examples/passing/PartialFunction.purs+4−3
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4−import Test.Assert
4+import Control.Monad.Eff
5+import Control.Monad.Eff.Console
56
6−fn :: Number -> Number
7+fn :: Partial => Number -> Number
78fn 0.0 = 0.0
89fn 1.0 = 2.0
910
10−main = assertThrows $ \_ -> fn 2.0
11+main = log "Done"
examples/passing/Patterns.purs+5−4
@@ -1,14 +1,15 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test = \x -> case x of
6− { str = "Foo", bool = true } -> true
7− { str = "Bar", bool = b } -> b
7+ { str: "Foo", bool: true } -> true
8+ { str: "Bar", bool: b } -> b
89 _ -> false
910
1011f = \o -> case o of
11− { foo = "Foo" } -> o.bar
12+ { foo: "Foo" } -> o.bar
1213 _ -> 0
1314
1415h = \o -> case o of
@@ -19,4 +20,4 @@ isDesc :: Array Number -> Boolean
1920isDesc [x, y] | x > y = true
2021isDesc _ = false
2122
22−main = Control.Monad.Eff.Console.log "Done"
23+main = log "Done"
examples/passing/PendingConflictingImports.purs+5−14
@@ -1,17 +1,8 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6−module B where
7−
8− thing :: Int
9− thing = 2
10−
111module Main where
122
13− -- No error as we never force `thing` to be resolved in `Main`
14− import A
15− import B
3+-- No error as we never force `thing` to be resolved in `Main`
4+import A
5+import B
6+import Control.Monad.Eff.Console (log)
167
17− main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/PendingConflictingImports/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/PendingConflictingImports/B.pursnew file+4
@@ -0,0 +1,4 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
examples/passing/PendingConflictingImports2.purs+6−10
@@ -1,14 +1,10 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
61module Main where
72
8− import A
3+import A
4+import Control.Monad.Eff.Console (log)
95
10− -- No error as we never force `thing` to be resolved in `Main`
11− thing :: Int
12− thing = 2
6+-- No error as we never force `thing` to be resolved in `Main`
7+thing :: Int
8+thing = 2
139
14− main = Control.Monad.Eff.Console.log "Done"
10+main = log "Done"
examples/passing/PendingConflictingImports2/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/Person.purs+3−2
@@ -1,11 +1,12 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Person = Person { name :: String, age :: Number }
67
78showPerson :: Person -> String
89showPerson = \p -> case p of
9− Person o -> o.name ++ ", aged " ++ show o.age
10+ Person o -> o.name <> ", aged " <> show o.age
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/PrimedTypeName.pursnew file+20
@@ -0,0 +1,20 @@
1+module Main (T, T', T'', T''', main) where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+data T a = T
7+type T' = T Unit
8+
9+data T'' = TP
10+
11+foreign import data T''' ∷ *
12+
13+instance eqT ∷ Eq T'' where
14+ eq _ _ = true
15+
16+type A' a b = b → a
17+
18+infixr 4 type A' as ↫
19+
20+main = log "Done"
examples/passing/QualifiedNames.pursnew file+11
@@ -0,0 +1,11 @@
1+module Main where
2+
3+import Prelude
4+import Either as Either
5+import Control.Monad.Eff.Console (log)
6+
7+either :: forall a b c. (a -> c) -> (b -> c) -> Either.Either a b -> c
8+either f _ (Either.Left x) = f x
9+either _ g (Either.Right y) = g y
10+
11+main = log (either id id (Either.Left "Done"))
examples/passing/QualifiedNames/Either.pursnew file+5
@@ -0,0 +1,5 @@
1+module Either where
2+
3+import Prelude
4+
5+data Either a b = Left a | Right b
examples/passing/QualifiedQualifiedImports.purs+2−2
@@ -1,6 +1,6 @@
11module Main where
22
33-- qualified import with qualified imported names
4−import qualified Control.Monad.Eff.Console (log) as Console
4+import Control.Monad.Eff.Console (log) as Console
55
6−main = Console.log "Success!"
6+main = Console.log "Done"
examples/passing/Rank2Data.purs+30−29
@@ -1,29 +1,30 @@
1−module Main where
2−
3−import Prelude hiding (add)
4−
5−data Id = Id forall a. a -> a
6−
7−runId = \id a -> case id of
8− Id f -> f a
9−
10−data Nat = Nat forall r. r -> (r -> r) -> r
11−
12−runNat = \nat -> case nat of
13− Nat f -> f 0.0 (\n -> n + 1.0)
14−
15−zero' = Nat (\zero' _ -> zero')
16−
17−succ = \n -> case n of
18− Nat f -> Nat (\zero' succ -> succ (f zero' succ))
19−
20−add = \n m -> case n of
21− Nat f -> case m of
22− Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
23−
24−one' = succ zero'
25−two = succ zero'
26−four = add two two
27−fourNumber = runNat four
28−
29−main = Control.Monad.Eff.Console.log "Done'"
1+module Main where
2+
3+import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log)
5+
6+data Id = Id forall a. a -> a
7+
8+runId = \id a -> case id of
9+ Id f -> f a
10+
11+data Nat = Nat forall r. r -> (r -> r) -> r
12+
13+runNat = \nat -> case nat of
14+ Nat f -> f 0.0 (\n -> n + 1.0)
15+
16+zero' = Nat (\zero' _ -> zero')
17+
18+succ = \n -> case n of
19+ Nat f -> Nat (\zero' succ -> succ (f zero' succ))
20+
21+add = \n m -> case n of
22+ Nat f -> case m of
23+ Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
24+
25+one' = succ zero'
26+two = succ zero'
27+four = add two two
28+fourNumber = runNat four
29+
30+main = log "Done"
examples/passing/Rank2Object.purs+1−1
@@ -6,6 +6,6 @@ import Control.Monad.Eff.Console
66data Foo = Foo { id :: forall a. a -> a }
77
88foo :: Foo -> Number
9−foo (Foo { id = f }) = f 0.0
9+foo (Foo { id: f }) = f 0.0
1010
1111main = log "Done"
examples/passing/Rank2TypeSynonym.purs+3−2
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff
4+import Control.Monad.Eff.Console (log, logShow)
55
66type Foo a = forall f. (Monad f) => f a
77
@@ -13,4 +13,5 @@ bar = foo 3.0
1313
1414main = do
1515 x <- bar
16− Control.Monad.Eff.Console.print x
16+ logShow x
17+ log "Done"
examples/passing/Rank2Types.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test1 :: (forall a. (a -> a)) -> Number
67test1 = \f -> f 0.0
@@ -8,4 +9,4 @@ test1 = \f -> f 0.0
89forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
910forever = \bind action -> bind action $ \_ -> forever bind action
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/ReExportQualified.purs+4−13
@@ -1,16 +1,7 @@
1−module A where
2− x = "Do"
3−
4−module B where
5− y = "ne"
6−
7−module C (module A, module M2) where
8− import A
9− import qualified B as M2
10−
111module Main where
122
13− import Prelude
14− import C
3+import Prelude
4+import C
5+import Control.Monad.Eff.Console (log)
156
16− main = Control.Monad.Eff.Console.log (x ++ y)
7+main = log (x <> y)
examples/passing/ReExportQualified/A.pursnew file+3
@@ -0,0 +1,3 @@
1+module A where
2+
3+x = "Do"
examples/passing/ReExportQualified/B.pursnew file+3
@@ -0,0 +1,3 @@
1+module B where
2+
3+y = "ne"
examples/passing/ReExportQualified/C.pursnew file+4
@@ -0,0 +1,4 @@
1+module C (module A, module M2) where
2+
3+import A
4+import B as M2
examples/passing/RebindableSyntax.purs+43−39
@@ -1,39 +1,43 @@
1−module Main where
2−
3−import Prelude
4−
5−example1 :: String
6−example1 = do
7− "Do"
8− " notation"
9− " for"
10− " Semigroup"
11− where
12− bind x f = x <> f unit
13−
14−(*>) :: forall f a b. (Apply f) => f a -> f b -> f b
15−(*>) fa fb = const id <$> fa <*> fb
16−
17−newtype Const a b = Const a
18−
19−runConst :: forall a b. Const a b -> a
20−runConst (Const a) = a
21−
22−instance functorConst :: Functor (Const a) where
23− map _ (Const a) = Const a
24−
25−instance applyConst :: (Semigroup a) => Apply (Const a) where
26− apply (Const a1) (Const a2) = Const (a1 <> a2)
27−
28−example2 :: Const String Unit
29−example2 = do
30− Const "Do"
31− Const " notation"
32− Const " for"
33− Const " Apply"
34− where
35− bind x f = x *> f unit
36−
37−main = do
38− Control.Monad.Eff.Console.log example1
39− Control.Monad.Eff.Console.log $ runConst example2
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+example1 :: String
7+example1 = do
8+ "Do"
9+ " notation"
10+ " for"
11+ " Semigroup"
12+ where
13+ bind x f = x <> f unit
14+
15+applySecond :: forall f a b. (Apply f) => f a -> f b -> f b
16+applySecond fa fb = const id <$> fa <*> fb
17+
18+infixl 4 applySecond as *>
19+
20+newtype Const a b = Const a
21+
22+runConst :: forall a b. Const a b -> a
23+runConst (Const a) = a
24+
25+instance functorConst :: Functor (Const a) where
26+ map _ (Const a) = Const a
27+
28+instance applyConst :: (Semigroup a) => Apply (Const a) where
29+ apply (Const a1) (Const a2) = Const (a1 <> a2)
30+
31+example2 :: Const String Unit
32+example2 = do
33+ Const "Do"
34+ Const " notation"
35+ Const " for"
36+ Const " Apply"
37+ where
38+ bind x f = x *> f unit
39+
40+main = do
41+ log example1
42+ log $ runConst example2
43+ log "Done"
examples/passing/Recursion.purs+2−1
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56fib = \n -> case n of
67 0.0 -> 1.0
78 1.0 -> 1.0
89 n -> fib (n - 1.0) + fib (n - 2.0)
910
10−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/RedefinedFixity.pursnew file+6
@@ -0,0 +1,6 @@
1+module Main where
2+
3+import M3
4+import Control.Monad.Eff.Console (log)
5+
6+main = log "Done"
examples/passing/RedefinedFixity/M1.pursnew file+6
@@ -0,0 +1,6 @@
1+module M1 where
2+
3+applyFn :: forall a b. (forall c d. c -> d) -> a -> b
4+applyFn f a = f a
5+
6+infixr 1000 applyFn as $
examples/passing/RedefinedFixity/M2.pursnew file+5
@@ -0,0 +1,5 @@
1+module M2 where
2+
3+import Prelude ()
4+
5+import M1
examples/passing/RedefinedFixity/M3.pursnew file+6
@@ -0,0 +1,6 @@
1+module M3 where
2+
3+import Prelude ()
4+
5+import M1
6+import M2
examples/passing/ReservedWords.purs+6−2
@@ -2,6 +2,8 @@
22module Main where
33
44import Prelude
5+import Control.Monad.Eff
6+import Control.Monad.Eff.Console (log)
57
68o :: { type :: String }
79o = { type: "o" }
@@ -10,6 +12,8 @@ p :: { type :: String }
1012p = o { type = "p" }
1113
1214f :: forall r. { type :: String | r } -> String
13−f { type = "p" } = "Done"
15+f { type: "p" } = "Done"
16+f _ = "Fail"
1417
15−main = Control.Monad.Eff.Console.log $ f { type: p.type, foo: "bar" }
18+main :: Eff _ _
19+main = log $ f { type: p.type, foo: "bar" }
examples/passing/ResolvableScopeConflict.purs+9−21
@@ -1,25 +1,13 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
6−module B where
7−
8− thing :: Int
9− thing = 2
10−
11− zing :: Int
12− zing = 3
13−
141module Main where
152
16− import A (thing)
17− import B
3+import A (thing)
4+import B
5+import Control.Monad.Eff.Console (log)
186
19− -- Not an error as although we have `thing` in scope from both A and B, it is
20− -- imported explicitly from A, giving it a resolvable solution.
21− what :: Boolean -> Int
22− what true = thing
23− what false = zing
7+-- Not an error as although we have `thing` in scope from both A and B, it is
8+-- imported explicitly from A, giving it a resolvable solution.
9+what :: Boolean -> Int
10+what true = thing
11+what false = zing
2412
25− main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/ResolvableScopeConflict/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/ResolvableScopeConflict/B.pursnew file+7
@@ -0,0 +1,7 @@
1+module B where
2+
3+thing :: Int
4+thing = 2
5+
6+zing :: Int
7+zing = 3
examples/passing/ResolvableScopeConflict2.purs+10−17
@@ -1,22 +1,15 @@
1−module A where
2−
3− thing :: Int
4− thing = 2
5−
6− zing :: Int
7− zing = 3
8−
91module Main where
102
11− import A
3+import A
4+import Control.Monad.Eff.Console (log)
125
13− thing :: Int
14− thing = 1
6+thing :: Int
7+thing = 1
158
16− -- Not an error as although we have `thing` in scope from both Main and A,
17− -- as the local declaration takes precedence over the implicit import
18− what :: Boolean -> Int
19− what true = thing
20− what false = zing
9+-- Not an error as although we have `thing` in scope from both Main and A,
10+-- as the local declaration takes precedence over the implicit import
11+what :: Boolean -> Int
12+what true = thing
13+what false = zing
2114
22− main = Control.Monad.Eff.Console.log "Done"
15+main = log "Done"
examples/passing/ResolvableScopeConflict2/A.pursnew file+7
@@ -0,0 +1,7 @@
1+module A where
2+
3+thing :: Int
4+thing = 2
5+
6+zing :: Int
7+zing = 3
examples/passing/ResolvableScopeConflict3.purs+5−11
@@ -1,15 +1,9 @@
1−module A where
2−
3− thing :: Int
4− thing = 1
5−
61module Main (thing, main, module A) where
72
8− import A
9−
10− thing :: Int
11− thing = 2
12−
13− main = Control.Monad.Eff.Console.log "Done"
3+import A
4+import Control.Monad.Eff.Console (log)
145
6+thing :: Int
7+thing = 2
158
9+main = log "Done"
examples/passing/ResolvableScopeConflict3/A.pursnew file+4
@@ -0,0 +1,4 @@
1+module A where
2+
3+thing :: Int
4+thing = 1
examples/passing/RowConstructors.purs+3−2
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type Foo = (x :: Number | (y :: Number | (z :: Number)))
67type Bar = (x :: Number, y :: Number, z :: Number)
@@ -12,7 +13,7 @@ foo = { x: 0.0, y: 0.0, z: 0.0 }
1213bar :: { | Bar }
1314bar = { x: 0.0, y: 0.0, z: 0.0 }
1415
15−id' :: Object Foo -> Object Bar
16+id' :: Record Foo -> Record Bar
1617id' = id
1718
1819foo' :: { | Foo }
@@ -39,4 +40,4 @@ wildcard { w: w } = { x: w, y: w, z: w, w: w }
3940wildcard' :: { | Quux _ } -> Number
4041wildcard' { q: q } = q
4142
42−main = Control.Monad.Eff.Console.log "Done"
43+main = log "Done"
examples/passing/RowPolyInstanceContext.purs+4−3
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class T s m where
67 state :: (s -> s) -> m Unit
@@ -11,12 +12,12 @@ instance st :: T s (S s) where
1112 state f = S $ \s -> { new: f s, ret: unit }
1213
1314test1 :: forall r . S { foo :: String | r } Unit
14−test1 = state $ \o -> o { foo = o.foo ++ "!" }
15+test1 = state $ \o -> o { foo = o.foo <> "!" }
1516
1617test2 :: forall m r . (T { foo :: String | r } m) => m Unit
17−test2 = state $ \o -> o { foo = o.foo ++ "!" }
18+test2 = state $ \o -> o { foo = o.foo <> "!" }
1819
1920main = do
2021 let t1 = test1
2122 let t2 = test2
22− Control.Monad.Eff.Console.log "Done"
23+ log "Done"
examples/passing/RuntimeScopeIssue.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56class A a where
67 a :: a -> Boolean
@@ -16,4 +17,6 @@ instance bNumber :: B Number where
1617 b 0.0 = false
1718 b n = a (n - 1.0)
1819
19−main = Control.Monad.Eff.Console.print $ a 10.0
20+main = do
21+ logShow $ a 10.0
22+ log "Done"
examples/passing/ScopedTypeVariables.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test1 :: forall a. (a -> a) -> a -> a
67test1 f x = g (g x)
@@ -33,4 +34,4 @@ test4 = h
3334 j x = x
3435
3536
36−main = Control.Monad.Eff.Console.log "Done"
37+main = log "Done"
examples/passing/Sequence.purs+2−1
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
56
67data List a = Cons a (List a) | Nil
78
@@ -12,4 +13,4 @@ instance sequenceList :: Sequence List where
1213 sequence Nil = pure Nil
1314 sequence (Cons x xs) = Cons <$> x <*> sequence xs
1415
15−main = sequence $ Cons (Control.Monad.Eff.Console.log "Done") Nil
16+main = sequence $ Cons (log "Done") Nil
examples/passing/SequenceDesugared.purs+5−4
@@ -2,6 +2,7 @@ module Main where
22
33import Prelude
44import Control.Monad.Eff
5+import Control.Monad.Eff.Console (log)
56
67data List a = Cons a (List a) | Nil
78
@@ -31,7 +32,7 @@ sequenceList''' = Sequence ((\val -> case val of
3132 Cons x xs -> Cons <$> x <*> sequence sequenceList''' xs) :: forall m a. (Monad m) => List (m a) -> m (List a))
3233
3334main = do
34− sequence sequenceList $ Cons (Control.Monad.Eff.Console.log "Done") Nil
35− sequence sequenceList' $ Cons (Control.Monad.Eff.Console.log "Done") Nil
36− sequence sequenceList'' $ Cons (Control.Monad.Eff.Console.log "Done") Nil
37− sequence sequenceList''' $ Cons (Control.Monad.Eff.Console.log "Done") Nil
35+ sequence sequenceList $ Cons (log "Done") Nil
36+ sequence sequenceList' $ Cons (log "Done") Nil
37+ sequence sequenceList'' $ Cons (log "Done") Nil
38+ sequence sequenceList''' $ Cons (log "Done") Nil
examples/passing/ShadowedModuleName.purs+4−11
@@ -1,15 +1,8 @@
1−module Test where
2−
3− data Z = Z String
4−
5− runZ :: Z -> String
6− runZ (Z s) = s
7−
81module Main where
92
10− import Test
11− import Control.Monad.Eff.Console
3+import Test
4+import Control.Monad.Eff.Console
125
13− data Test = Test
6+data Test = Test
147
15− main = log (runZ (Z "done"))
8+main = log (runZ (Z "Done"))
examples/passing/ShadowedModuleName/Test.pursnew file+6
@@ -0,0 +1,6 @@
1+module Test where
2+
3+data Z = Z String
4+
5+runZ :: Z -> String
6+runZ (Z s) = s
examples/manual/passing/ShadowedName.purs → examples/passing/ShadowedName.pursrenamed+11−10
@@ -1,10 +1,11 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−done :: String
7−done = let str = "Not yet done" in
8− let str = "Done" in str
9−
10−main = Control.Monad.Eff.Console.log done
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console
5+import Control.Monad.Eff.Console (log)
6+
7+done :: String
8+done = let str = "Not yet done" in
9+ let str = "Done" in str
10+
11+main = log done
examples/passing/ShadowedTCO.purs+21−18
@@ -1,18 +1,21 @@
1−module Main where
2−
3−import Prelude hiding (add)
4−
5−runNat f = f 0.0 (\n -> n + 1.0)
6−
7−zero' z _ = z
8−
9−succ f zero' succ = succ (f zero' succ)
10−
11−add f g zero' succ = g (f zero' succ) succ
12−
13−one' = succ zero'
14−two = succ one'
15−four = add two two
16−fourNumber = runNat four
17−
18−main = Control.Monad.Eff.Console.log $ show fourNumber
1+module Main where
2+
3+import Prelude hiding (add)
4+import Control.Monad.Eff.Console (log)
5+
6+runNat f = f 0.0 (\n -> n + 1.0)
7+
8+zero' z _ = z
9+
10+succ f zero' succ = succ (f zero' succ)
11+
12+add f g zero' succ = g (f zero' succ) succ
13+
14+one' = succ zero'
15+two = succ one'
16+four = add two two
17+fourNumber = runNat four
18+
19+main = do
20+ log $ show fourNumber
21+ log "Done"
examples/passing/ShadowedTCOLet.purs+15−9
@@ -1,9 +1,15 @@
1−module Main where
2−
3−import Prelude
4−
5−f x y z =
6− let f 1.0 2.0 3.0 = 1.0
7− in f x z y
8−
9−main = Control.Monad.Eff.Console.log $ show $ f 1.0 3.0 2.0
1+module Main where
2+
3+import Prelude
4+import Partial.Unsafe (unsafePartial)
5+import Control.Monad.Eff
6+import Control.Monad.Eff.Console (log)
7+
8+f x y z =
9+ let f 1.0 2.0 3.0 = 1.0
10+ in f x z y
11+
12+main :: Eff _ _
13+main = do
14+ log $ show $ unsafePartial f 1.0 3.0 2.0
15+ log "Done"
examples/passing/SignedNumericLiterals.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56p = 0.5
67q = 1.0
@@ -14,4 +15,4 @@ f x = -x
1415
1516test1 = 2.0 - 1.0
1617
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/StringEscapes.purs+17−15
@@ -1,15 +1,17 @@
1−module Main where
2−
3−import Prelude ((==), bind)
4−import Test.Assert (assert)
5−
6−singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
7−hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
8−decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
9−surrogatePair = "\xD834\xDF06" == "\x1D306"
10−
11−main = do
12− assert singleCharacter
13− assert hex
14− assert decimal
15− assert surrogatePair
1+module Main where
2+
3+import Prelude ((==), bind)
4+import Test.Assert (assert)
5+import Control.Monad.Eff.Console (log)
6+
7+singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
8+hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
9+decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
10+surrogatePair = "\xD834\xDF06" == "\x1D306"
11+
12+main = do
13+ assert singleCharacter
14+ assert hex
15+ assert decimal
16+ assert surrogatePair
17+ log "Done"
examples/passing/Superclasses1.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56class Su a where
67 su :: a -> a
@@ -17,4 +18,6 @@ instance clNumber :: Cl Number where
1718test :: forall a. (Cl a) => a -> a
1819test a = su (cl a a)
1920
20−main = Control.Monad.Eff.Console.print $ test 10.0
21+main = do
22+ logShow $ test 10.0
23+ log "Done"
examples/passing/Superclasses3.purs+1−1
@@ -28,7 +28,7 @@ instance applyMTrace :: Apply MTrace where
2828 apply = ap
2929
3030instance applicativeMTrace :: Applicative MTrace where
31− pure = MTrace <<< return
31+ pure = MTrace <<< pure
3232
3333instance bindMTrace :: Bind MTrace where
3434 bind m f = MTrace (runMTrace m >>= (runMTrace <<< f))
examples/passing/TCO.purs+7−7
@@ -1,20 +1,20 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console (print)
4+import Control.Monad.Eff.Console (log, logShow)
55
66main = do
77 let f x = x + 1
88 let v = 0
9− print (applyN 0 f v)
10− print (applyN 1 f v)
11− print (applyN 2 f v)
12− print (applyN 3 f v)
13− print (applyN 4 f v)
9+ logShow (applyN 0 f v)
10+ logShow (applyN 1 f v)
11+ logShow (applyN 2 f v)
12+ logShow (applyN 3 f v)
13+ logShow (applyN 4 f v)
14+ log "Done"
1415
1516applyN :: forall a. Int -> (a -> a) -> a -> a
1617applyN = go id
1718 where
1819 go f n _ | n <= 0 = f
1920 go f n g = go (f >>> g) (n - 1) g
20−
examples/passing/TCOCase.purs+2−1
@@ -1,10 +1,11 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Data = One | More Data
67
7−main = Control.Monad.Eff.Console.log (from (to 10000.0 One))
8+main = log (from (to 10000.0 One))
89 where
910 to 0.0 a = a
1011 to n a = to (n - 1.0) (More a)
examples/passing/TailCall.purs+4−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log, logShow)
45
56data L a = C a (L a) | N
67
@@ -14,4 +15,6 @@ loop x = loop (x + 1.0)
1415notATailCall = \x ->
1516 (\notATailCall -> notATailCall x) (\x -> x)
1617
17−main = Control.Monad.Eff.Console.print (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
18+main = do
19+ logShow (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
20+ log "Done"
examples/passing/Tick.purs+2−1
@@ -1,7 +1,8 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test' x = x
67
7−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/passing/TopLevelCase.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56gcd :: Number -> Number -> Number
67gcd 0.0 x = x
@@ -15,4 +16,4 @@ data A = A
1516
1617parseTest A 0.0 = 0.0
1718
18−main = Control.Monad.Eff.Console.log "Done"
19+main = log "Done"
examples/passing/TransitiveImport.pursnew file+9
@@ -0,0 +1,9 @@
1+module Main where
2+
3+ import Prelude
4+ import Middle
5+ import Control.Monad.Eff.Console
6+
7+ main = do
8+ logShow (middle unit)
9+ log "Done"
examples/passing/TransitiveImport/Middle.pursnew file+5
@@ -0,0 +1,5 @@
1+module Middle where
2+
3+import Test (test)
4+
5+middle = test
examples/passing/TransitiveImport/Test.pursnew file+9
@@ -0,0 +1,9 @@
1+module Test where
2+
3+import Prelude
4+
5+class TestCls a where
6+ test :: a -> a
7+
8+instance unitTestCls :: TestCls Unit where
9+ test _ = unit
examples/passing/TypeClassMemberOrderChange.purs+16−13
@@ -1,13 +1,16 @@
1−module Main where
2−
3−import Prelude
4−
5−class Test a where
6− fn :: a -> a -> a
7− val :: a
8−
9−instance testBoolean :: Test Boolean where
10− val = true
11− fn x y = y
12−
13−main = Control.Monad.Eff.Console.log (show (fn true val))
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+class Test a where
7+ fn :: a -> a -> a
8+ val :: a
9+
10+instance testBoolean :: Test Boolean where
11+ val = true
12+ fn x y = y
13+
14+main = do
15+ log (show (fn true val))
16+ log "Done"
examples/passing/TypeClasses.purs+11−9
@@ -1,23 +1,24 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56test1 = \_ -> show "testing"
67
7−f :: forall a. (Prelude.Show a) => a -> String
8+f :: forall a. (Show a) => a -> String
89f x = show x
910
1011test2 = \_ -> f "testing"
1112
12−test7 :: forall a. (Prelude.Show a) => a -> String
13+test7 :: forall a. (Show a) => a -> String
1314test7 = show
1415
1516test8 = \_ -> show $ "testing"
1617
1718data Data a = Data a
1819
19−instance showData :: (Prelude.Show a) => Prelude.Show (Data a) where
20− show (Data a) = "Data (" ++ show a ++ ")"
20+instance showData :: (Show a) => Show (Data a) where
21+ show (Data a) = "Data (" <> show a <> ")"
2122
2223test3 = \_ -> show (Data "testing")
2324
@@ -53,9 +54,9 @@ instance bindMaybe :: Bind Maybe where
5354instance monadMaybe :: Monad Maybe
5455
5556test4 :: forall a m. (Monad m) => a -> m Number
56−test4 = \_ -> return 1.0
57+test4 = \_ -> pure 1.0
5758
58−test5 = \_ -> Just 1.0 >>= \n -> return (n + 1.0)
59+test5 = \_ -> Just 1.0 >>= \n -> pure (n + 1.0)
5960
6061ask r = r
6162
@@ -63,7 +64,8 @@ runReader r f = f r
6364
6465test9 _ = runReader 0.0 $ do
6566 n <- ask
66− return $ n + 1.0
67−
68−main = Control.Monad.Eff.Console.log (test7 "Done")
67+ pure $ n + 1.0
6968
69+main = do
70+ log (test7 "Hello")
71+ log "Done"
examples/passing/TypeClassesInOrder.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class Foo a where
67 foo :: a -> String
@@ -8,4 +9,4 @@ class Foo a where
89instance fooString :: Foo String where
910 foo s = s
1011
11−main = Control.Monad.Eff.Console.log $ foo "Done"
12+main = log $ foo "Done"
examples/passing/TypeClassesWithOverlappingTypeVariables.purs+3−2
@@ -1,11 +1,12 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Either a b = Left a | Right b
67
7−instance functorEither :: Prelude.Functor (Either a) where
8+instance functorEither :: Functor (Either a) where
89 map _ (Left x) = Left x
910 map f (Right y) = Right (f y)
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/TypeDecl.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56k :: String -> Number -> String
67k x y = x
@@ -9,4 +10,4 @@ iterate :: forall a. Number -> (a -> a) -> a -> a
910iterate 0.0 f a = a
1011iterate n f a = iterate (n - 1.0) f (f a)
1112
12−main = Control.Monad.Eff.Console.log "Done"
13+main = log "Done"
examples/passing/TypeOperators.purs+13−27
@@ -1,34 +1,20 @@
1−module A
2− ( Tuple(..)
3− , type (/\)
4− , (/\)
5− , Natural
6− , type (~>)
7− ) where
8−
9− data Tuple a b = Tuple a b
10−
11− infixl 6 Tuple as /\
12− infixl 6 type Tuple as /\
13−
14− type Natural f g = ∀ a. f a → g a
15−
16− infixr 0 type Natural as ~>
1+module Main where
172
18− tup ∷ ∀ a b. a → b → b /\ a
19− tup a b = b /\ a
3+import A (type (~>), type (/\), (/\))
4+import Control.Monad.Eff.Console (log)
205
21− tupX ∷ ∀ a b c. a /\ b /\ c → c
22− tupX (a /\ b /\ c) = c
6+natty ∷ ∀ f. f ~> f
7+natty x = x
238
24−module Main where
9+data Compose f g a = Compose (f (g a))
2510
26− import A (type (~>), type (/\), (/\))
11+testPrecedence1 ∷ ∀ f g. Compose f g ~> Compose f g
12+testPrecedence1 x = x
2713
28− natty ∷ ∀ f. f ~> f
29− natty x = x
14+testPrecedence2 ∷ ∀ f g. f ~> g → f ~> g
15+testPrecedence2 nat fx = nat fx
3016
31− swap ∷ ∀ a b. a /\ b → b /\ a
32− swap (a /\ b) = b /\ a
17+swap ∷ ∀ a b. a /\ b → b /\ a
18+swap (a /\ b) = b /\ a
3319
34− main = Control.Monad.Eff.Console.log "Done"
20+main = log "Done"
examples/passing/TypeOperators/A.pursnew file+22
@@ -0,0 +1,22 @@
1+module A
2+( Tuple(..)
3+, type (/\)
4+, (/\)
5+, Natural
6+, type (~>)
7+) where
8+
9+data Tuple a b = Tuple a b
10+
11+infixl 6 Tuple as /\
12+infixl 6 type Tuple as /\
13+
14+type Natural f g = ∀ a. f a → g a
15+
16+infixr 0 type Natural as ~>
17+
18+tup ∷ ∀ a b. a → b → b /\ a
19+tup a b = b /\ a
20+
21+tupX ∷ ∀ a b c. a /\ b /\ c → c
22+tupX (a /\ b /\ c) = c
examples/passing/TypeSynonymInData.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type A a = Array a
67
@@ -8,4 +9,4 @@ data Foo a = Foo (A a) | Bar
89
910foo (Foo []) = Bar
1011
11−main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/TypeSynonyms.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56type Lens a b =
67 { get :: a -> b
@@ -24,4 +25,4 @@ fst =
2425test1 :: forall a b c. Lens (Pair (Pair a b) c) a
2526test1 = composeLenses fst fst
2627
27−main = Control.Monad.Eff.Console.log "Done"
28+main = log "Done"
examples/passing/TypeWildcards.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56testTopLevel :: _ -> _
67testTopLevel n = n + 1.0
@@ -12,4 +13,4 @@ test f a = go (f a) a
1213 go a1 a2 | a1 == a2 = a1
1314 go a1 _ = go (f a1) a1
1415
15−main = Control.Monad.Eff.Console.log "Done"
16+main = log "Done"
examples/passing/TypeWildcardsRecordExtension.purs+2−1
@@ -1,8 +1,9 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56foo :: forall a. {b :: Number | a} -> {b :: Number | _}
67foo f = f
78
8−main = Control.Monad.Eff.Console.log "Done"
9+main = log "Done"
examples/passing/TypeWithoutParens.purs+7−11
@@ -1,16 +1,12 @@
1−module Lib (X, Y) where
2−
3− data X = X
4− type Y = X
5−
61module Main where
72
8− import Lib (X, Y)
3+import Lib (X, Y)
4+import Control.Monad.Eff.Console (log)
95
10− idX :: X -> X
11− idX x = x
6+idX :: X -> X
7+idX x = x
128
13− idY :: Y -> Y
14− idY y = y
9+idY :: Y -> Y
10+idY y = y
1511
16− main = Control.Monad.Eff.Console.log "Done"
12+main = log "Done"
examples/passing/TypeWithoutParens/Lib.pursnew file+4
@@ -0,0 +1,4 @@
1+module Lib (X, Y) where
2+
3+data X = X
4+type Y = X
examples/passing/TypedBinders.purs+8−7
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Tuple a b = Tuple a b
67
@@ -31,27 +32,27 @@ instance monadStateState :: MonadState s (State s) where
3132 get = State (\s -> Tuple s s)
3233 put s = State (\_ -> Tuple s {})
3334
34−modify :: forall m s. (Prelude.Monad m, MonadState s m) => (s -> s) -> m {}
35+modify :: forall m s. (Monad m, MonadState s m) => (s -> s) -> m {}
3536modify f = do
3637 s <- get
3738 put (f s)
3839
3940test :: Tuple String String
4041test = runState "" $ do
41− modify $ (++) "World!"
42− modify $ (++) "Hello, "
42+ modify $ (<>) "World!"
43+ modify $ (<>) "Hello, "
4344 str :: String <- get
44− return str
45+ pure str
4546
4647test2 :: (Int -> Int) -> Int
4748test2 = (\(f :: Int -> Int) -> f 10)
4849
49−test3 :: Int -> Boolean
50+test3 :: Int -> Boolean
5051test3 n = case n of
5152 (0 :: Int) -> true
5253 _ -> false
5354
54−test4 :: Tuple Int Int -> Tuple Int Int
55+test4 :: Tuple Int Int -> Tuple Int Int
5556test4 = (\(Tuple a b :: Tuple Int Int) -> Tuple b a)
5657
5758type Int1 = Int
@@ -64,4 +65,4 @@ main = do
6465 t2 = test2 id
6566 t3 = test3 1
6667 t4 = test4 (Tuple 1 0)
67− Control.Monad.Eff.Console.log "Done"
68+ log "Done"
examples/passing/TypedWhere.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data E a b = L a | R b
67
@@ -14,4 +15,4 @@ lefts = go N
1415 go ls (C (L a) rest) = go (C a ls) rest
1516 go ls (C _ rest) = go ls rest
1617
17−main = Control.Monad.Eff.Console.log "Done"
18+main = log "Done"
examples/passing/UTF8Sourcefile.purs+8−10
@@ -1,10 +1,8 @@
1−module Main where
2−
3−import Control.Monad.Eff.Console
4−
5−-- '→' is multibyte sequence \u2192.
6−utf8multibyte = "Hello λ→ world!!"
7−
8−main = do
9− log "done"
10−
1+module Main where
2+
3+import Control.Monad.Eff.Console
4+
5+-- '→' is multibyte sequence \u2192.
6+utf8multibyte = "Hello λ→ world!!"
7+
8+main = log "Done"
examples/passing/UnderscoreIdent.purs+3−1
@@ -1,11 +1,13 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56data Data_type = Con_Structor | Con_2 String
67
78type Type_name = Data_type
89
910done (Con_2 s) = s
11+done _ = "Failed"
1012
11−main = Control.Monad.Eff.Console.log (done (Con_2 "Done"))
13+main = log (done (Con_2 "Done"))
examples/passing/UnicodeIdentifier.purs+3−1
@@ -1,5 +1,7 @@
11module Main where
22
3+import Control.Monad.Eff.Console (log)
4+
35f asgård = asgård
46
5−main = Control.Monad.Eff.Console.log (f "Done")
7+main = log (f "Done")
examples/passing/UnicodeOperators.purs+3−1
@@ -1,5 +1,7 @@
11module Main where
22
3+import Control.Monad.Eff.Console (log)
4+
35compose :: forall a b c. (b -> c) -> (a -> b) -> a -> c
46compose f g a = f (g a)
57
@@ -17,4 +19,4 @@ emptySet _ = true
1719
1820test2 = 1 ∈ emptySet
1921
20−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/UnicodeType.purs+8−9
@@ -1,23 +1,22 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
5−class (Monad m) ⇐ Monad1 m where
6+class Monad m ⇐ Monad1 m where
67 f1 :: Int
78
8−class (Monad m) <= Monad2 m where
9+class Monad m <= Monad2 m where
910 f2 :: Int
1011
1112f ∷ ∀ m. Monad m ⇒ Int → m Int
1213f n = do
13− n' ← return n
14− return n'
14+ n' ← pure n
15+ pure n'
1516
1617f' :: forall m. Monad m => Int -> m Int
1718f' n = do
18− n' <- return n
19− return n'
19+ n' <- pure n
20+ pure n'
2021
21−(←→) a b = a ←→ b
22−
23−main = Control.Monad.Eff.Console.log "Done"
22+main = log "Done"
examples/passing/Unit.purs+4−2
@@ -1,6 +1,8 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (logShow, log)
55
6−main = print (const unit $ "Hello world")
6+main = do
7+ logShow (const unit $ "Hello world")
8+ log "Done"
examples/passing/UnknownInTypeClassLookup.purs+2−1
@@ -1,6 +1,7 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56class EQ a b
67
@@ -11,4 +12,4 @@ test _ _ = "Done"
1112
1213runTest a = test a a
1314
14−main = Control.Monad.Eff.Console.log $ runTest 0.0
15+main = log $ runTest 0.0
examples/passing/UntupledConstraints.purs+1−1
@@ -1,7 +1,7 @@
11module Main where
22
33import Prelude
4−import Control.Monad.Eff.Console
4+import Control.Monad.Eff.Console (log)
55
66class Show a <= Nonsense a where
77 method :: a -> a
examples/passing/Where.purs+11−11
@@ -1,8 +1,9 @@
11module Main where
22
33import Prelude
4+import Partial.Unsafe (unsafePartial)
45import Control.Monad.Eff
5−import Control.Monad.ST
6+import Control.Monad.Eff.Console (logShow, log)
67
78test1 x = y
89 where
@@ -14,15 +15,12 @@ test2 x y = x' + y'
1415 x' = x + 1.0
1516 y' = y + 1.0
1617
17−
1818test3 = f 1.0 2.0 3.0
1919 where f x y z = x + y + z
2020
21−
2221test4 = f (+) [1.0, 2.0]
2322 where f x [y, z] = x y z
2423
25−
2624test5 = g 10.0
2725 where
2826 f x | x > 0.0 = g (x / 2.0) + 1.0
@@ -39,11 +37,13 @@ test7 x = go x
3937 go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
4038 go y = go $ (y + x / y) / 2.0
4139
40+main :: Eff _ _
4241main = do
43− Control.Monad.Eff.Console.print (test1 1.0)
44− Control.Monad.Eff.Console.print (test2 1.0 2.0)
45− Control.Monad.Eff.Console.print test3
46− Control.Monad.Eff.Console.print test4
47− Control.Monad.Eff.Console.print test5
48− Control.Monad.Eff.Console.print test6
49− Control.Monad.Eff.Console.print (test7 100.0)
42+ logShow (test1 1.0)
43+ logShow (test2 1.0 2.0)
44+ logShow test3
45+ unsafePartial (logShow test4)
46+ logShow test5
47+ logShow test6
48+ logShow (test7 100.0)
49+ log "Done"
examples/manual/passing/WildcardType.purs → examples/passing/WildcardType.pursrenamed+12−13
@@ -1,13 +1,12 @@
1−module Main where
2−
3−import Prelude
4−import Control.Monad.Eff.Console
5−
6−f1 :: (_ -> _) -> _
7−f1 g = g 1
8−
9−f2 :: _ -> _
10−f2 _ = "Done"
11−
12−main = Control.Monad.Eff.Console.log $ f1 f2
13−
1+module Main where
2+
3+import Prelude
4+import Control.Monad.Eff.Console (log)
5+
6+f1 :: (_ -> _) -> _
7+f1 g = g 1
8+
9+f2 :: _ -> _
10+f2 _ = "Done"
11+
12+main = log $ f1 f2
examples/passing/iota.purs+3−1
@@ -1,9 +1,11 @@
11module Main where
22
3+import Control.Monad.Eff.Console (log)
4+
35s = \x -> \y -> \z -> x z (y z)
46
57k = \x -> \y -> x
68
79iota = \x -> x s k
810
9−main = Control.Monad.Eff.Console.log "Done"
11+main = log "Done"
examples/passing/s.purs+2−1
@@ -1,7 +1,8 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console (log)
45
56s = \x y z -> x z (y z)
67
7−main = Control.Monad.Eff.Console.log "Done"
8+main = log "Done"
examples/warning/DuplicateExportRef.pursnew file+30
@@ -0,0 +1,30 @@
1+-- @shouldWarnWith DuplicateExportRef
2+-- @shouldWarnWith DuplicateExportRef
3+-- @shouldWarnWith DuplicateExportRef
4+-- @shouldWarnWith DuplicateExportRef
5+-- @shouldWarnWith DuplicateExportRef
6+-- @shouldWarnWith DuplicateExportRef
7+-- @shouldWarnWith DuplicateExportRef
8+module Main
9+ ( X(X, X), X
10+ , fn, fn
11+ , (!), (!)
12+ , class Y, class Y
13+ , Natural, type (~>), type (~>)
14+ , module Prelude, module Prelude
15+ ) where
16+
17+import Prelude (Unit)
18+
19+data X = X
20+
21+fn :: X -> X -> X
22+fn _ _ = X
23+
24+infix 2 fn as !
25+
26+class Y a
27+
28+type Natural f g = forall a. f a -> g a
29+
30+infixl 1 type Natural as ~>
examples/warning/DuplicateImport.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldWarnWith DuplicateImport
2+module Main where
3+
4+import Prelude (Unit, unit, pure)
5+import Prelude (Unit, unit, pure)
6+
7+import Control.Monad.Eff (Eff)
8+
9+main :: Eff () Unit
10+main = pure unit
examples/warning/DuplicateImportRef.pursnew file+18
@@ -0,0 +1,18 @@
1+-- @shouldWarnWith DuplicateImportRef
2+-- @shouldWarnWith DuplicateImportRef
3+-- @shouldWarnWith DuplicateImportRef
4+-- @shouldWarnWith DuplicateImportRef
5+module Main where
6+
7+import Prelude
8+ ( Unit, Unit
9+ , unit, unit
10+ , class Functor, class Functor
11+ , (<>), (<>)
12+ )
13+
14+u :: Unit
15+u = unit <> unit
16+
17+fid :: forall f a. Functor f => f a -> f a
18+fid fa = fa
examples/warning/DuplicateSelectiveImport.pursnew file+10
@@ -0,0 +1,10 @@
1+-- @shouldWarnWith DuplicateSelectiveImport
2+module Main where
3+
4+import Prelude (Unit, unit)
5+import Prelude (pure)
6+
7+import Control.Monad.Eff (Eff)
8+
9+main :: Eff () Unit
10+main = pure unit
examples/warning/HidingImport.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldWarnWith HidingImport
2+-- @shouldWarnWith HidingImport
3+module Main where
4+
5+import Prelude hiding (one)
6+import Control.Monad.Eff hiding (runPure)
7+
8+main :: Eff () Unit
9+main = pure unit
examples/warning/ImplicitImport.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldWarnWith ImplicitImport
2+-- @shouldWarnWith ImplicitImport
3+module Main where
4+
5+import Prelude
6+import Control.Monad.Eff
7+
8+main :: Eff () Unit
9+main = pure unit
examples/warning/ImplicitQualifiedImport.pursnew file+11
@@ -0,0 +1,11 @@
1+-- @shouldWarnWith ImplicitQualifiedImport
2+-- @shouldWarnWith ImplicitQualifiedImport
3+module Main where
4+
5+import Data.Unit
6+
7+import Control.Monad.Eff as E
8+import Control.Monad.Eff.Console as E
9+
10+main :: E.Eff (console :: E.CONSOLE) Unit
11+main = E.log "test"
examples/warning/MissingTypeDeclaration.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldWarnWith MissingTypeDeclaration
2+module Main where
3+
4+x = 0
examples/warning/OverlappingInstances.pursnew file+17
@@ -0,0 +1,17 @@
1+-- @shouldWarnWith OverlappingInstances
2+module Main where
3+
4+class Test a where
5+ test :: a -> a
6+
7+instance testRefl :: Test a where
8+ test x = x
9+
10+instance testInt :: Test Int where
11+ test _ = 0
12+
13+-- The OverlappingInstances instances warning only arises when there are two
14+-- choices for a dictionary, not when the instances are defined. So without
15+-- `value` this module would not raise a warning.
16+value :: Int
17+value = test 1
examples/warning/OverlappingPattern.pursnew file+15
@@ -0,0 +1,15 @@
1+-- @shouldWarnWith OverlappingPattern
2+-- @shouldWarnWith OverlappingPattern
3+module Main where
4+
5+data X = A | B
6+
7+pat1 :: X -> Boolean
8+pat1 A = true
9+pat1 A = true
10+pat1 B = false
11+
12+pat2 :: X -> Boolean
13+pat2 A = true
14+pat2 _ = false
15+pat2 B = false
examples/warning/ScopeShadowing.pursnew file+13
@@ -0,0 +1,13 @@
1+-- @shouldWarnWith ScopeShadowing
2+module Main where
3+
4+import Prelude
5+
6+-- No warning at the definition, only when the name is later resolved
7+data Unit = Unit
8+
9+-- This is only a warning as the `Prelude` import is implicit. If `Unit` was
10+-- named explicitly in an import list, then this refernce to `Unit`
11+-- would be a `ScopeConflict` error instead.
12+test :: Unit
13+test = const Unit unit
examples/warning/ShadowedTypeVar.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldWarnWith ShadowedTypeVar
2+module Main where
3+
4+f :: forall a. (forall a. a -> a) -> a -> a
5+f g x = g x
examples/warning/UnnecessaryFFIModule.jsnew file+1
@@ -0,0 +1 @@
1+exports.out = null;
examples/warning/UnnecessaryFFIModule.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldWarnWith UnnecessaryFFIModule
2+module Main where
3+
4+t :: Boolean
5+t = true
examples/warning/UnusedDctorExplicitImport.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldWarnWith UnusedDctorExplicitImport
2+module Main where
3+
4+import Data.Ordering (Ordering(EQ, LT))
5+
6+f :: Ordering -> Ordering
7+f EQ = EQ
8+f x = x
examples/warning/UnusedDctorImportAll.pursnew file+7
@@ -0,0 +1,7 @@
1+-- @shouldWarnWith UnusedDctorImport
2+module Main where
3+
4+import Data.Ordering (Ordering(..))
5+
6+f :: Ordering -> Ordering
7+f x = x
examples/warning/UnusedDctorImportExplicit.pursnew file+7
@@ -0,0 +1,7 @@
1+-- @shouldWarnWith UnusedDctorImport
2+module Main where
3+
4+import Data.Ordering (Ordering(EQ))
5+
6+f :: Ordering -> Ordering
7+f x = x
examples/warning/UnusedExplicitImport.pursnew file+8
@@ -0,0 +1,8 @@
1+-- @shouldWarnWith UnusedExplicitImport
2+module Main where
3+
4+import Prelude (Unit, unit, pure, bind)
5+import Control.Monad.Eff (Eff)
6+
7+main :: Eff () Unit
8+main = pure unit
examples/warning/UnusedFFIImplementations.jsnew file+2
@@ -0,0 +1,2 @@
1+exports.yes = true;
2+exports.no = false;
examples/warning/UnusedFFIImplementations.pursnew file+4
@@ -0,0 +1,4 @@
1+-- @shouldWarnWith UnusedFFIImplementations
2+module Main where
3+
4+foreign import yes :: Boolean
examples/warning/UnusedImport.pursnew file+14
@@ -0,0 +1,14 @@
1+-- @shouldWarnWith UnusedImport
2+-- @shouldWarnWith UnusedImport
3+-- @shouldWarnWith UnusedImport
4+module Main where
5+
6+import Data.Unit (Unit, unit)
7+
8+-- All of the below are unused
9+import Control.Monad.Eff
10+import Control.Monad.Eff.Console as Console
11+import Test.Assert ()
12+
13+main :: Unit
14+main = unit
examples/warning/UnusedTypeVar.pursnew file+5
@@ -0,0 +1,5 @@
1+-- @shouldWarnWith UnusedTypeVar
2+module Main where
3+
4+f :: forall a b. a -> a
5+f x = x
examples/warning/WildcardInferredType.pursnew file+23
@@ -0,0 +1,23 @@
1+-- @shouldWarnWith WildcardInferredType
2+-- @shouldWarnWith WildcardInferredType
3+-- @shouldWarnWith WildcardInferredType
4+-- @shouldWarnWith WildcardInferredType
5+module Main where
6+
7+x :: Int
8+x = 0 :: _
9+
10+y :: _
11+y = 0
12+
13+z :: Int
14+z =
15+ let n :: _
16+ n = 0
17+ in n
18+
19+w :: Int
20+w = n
21+ where
22+ n :: _
23+ n = 0
hierarchy/Main.hs+2−3
@@ -65,7 +65,7 @@ compile (HierarchyOptions inputGlob mOutput) = do
6565 input <- glob inputGlob
6666 modules <- readInput input
6767 case modules of
68− Left errs -> hPutStr stderr (P.prettyPrintMultipleErrors False errs) >> exitFailure
68+ Left errs -> hPutStr stderr (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure
6969 Right ms -> do
7070 for_ ms $ \(P.Module _ _ moduleName decls _) ->
7171 let name = runModuleName moduleName
@@ -84,7 +84,7 @@ compile (HierarchyOptions inputGlob mOutput) = do
8484
8585superClasses :: P.Declaration -> [SuperMap]
8686superClasses (P.TypeClassDeclaration sub _ supers@(_:_) _) =
87− fmap (\(P.Qualified _ super, _) -> SuperMap (Right (super, sub))) supers
87+ fmap (\(P.Constraint (P.Qualified _ super) _ _) -> SuperMap (Right (super, sub))) supers
8888superClasses (P.TypeClassDeclaration sub _ _ _) = [SuperMap (Left sub)]
8989superClasses (P.PositionedDeclaration _ _ decl) = superClasses decl
9090superClasses _ = []
@@ -113,4 +113,3 @@ main = execParser opts >>= compile
113113 infoModList = fullDesc <> headerInfo <> footerInfo
114114 headerInfo = header "hierarchy - Creates a GraphViz directed graph of PureScript TypeClasses"
115115 footerInfo = footer $ "hierarchy " ++ showVersion Paths.version
116−
pcc/Main.hs+86−75
@@ -15,84 +15,99 @@
1515{-# LANGUAGE DataKinds #-}
1616{-# LANGUAGE FlexibleContexts #-}
1717{-# LANGUAGE RecordWildCards #-}
18+{-# LANGUAGE ScopedTypeVariables #-}
1819{-# LANGUAGE TupleSections #-}
1920
2021module Main where
2122
22−import Control.Applicative
23−import Control.Monad
24−import Control.Monad.Error.Class (MonadError(..))
25−import Control.Monad.Writer.Strict
23+import Control.Applicative
24+import Control.Monad
25+import Control.Monad.Writer.Strict
2626
27−import Data.Version (showVersion)
27+import qualified Data.Aeson as A
28+import Data.Bool (bool)
29+import qualified Data.ByteString.Lazy as B
30+import qualified Data.ByteString.UTF8 as BU8
2831import qualified Data.Map as M
32+import Data.Version (showVersion)
2933
30−import Options.Applicative as Opts
34+import qualified Language.PureScript as P
35+import Language.PureScript.Errors.JSON
3136
32−import System.Exit (exitSuccess, exitFailure)
33−import System.IO (hPutStrLn, stderr)
34−import System.IO.UTF8
37+import Options.Applicative as Opts
3538
36−import qualified Language.PureScript as P
3739import qualified Paths_purescript as Paths
3840
39−import Make
40−import Makefile
41+import qualified System.Console.ANSI as ANSI
42+import System.Exit (exitSuccess, exitFailure)
43+import System.FilePath.Glob (glob)
44+import System.IO (hSetEncoding, hPutStrLn, stdout, stderr, utf8)
45+import System.IO.UTF8
46+
47+import Make
48+import Makefile
4149
42−data PCCOptions = PCCOptions
50+data PCCMakeOptions = PCCMakeOptions
4351 { pccmInput :: [FilePath]
44− , pccmForeignInput :: [FilePath]
4552 , pccmOutputDir :: FilePath
4653 , pccmOpts :: P.Options
4754 , pccmUsePrefix :: Bool
55+ , pccmJSONErrors :: Bool
4856 }
4957
50−data InputOptions = InputOptions
51− { ioInputFiles :: [FilePath]
52− }
53−
54−compile :: PCCOptions -> IO ()
55−compile (PCCOptions input _ outputDir opts usePrefix) = do
56− when (null input) generateMakefile
57− moduleFiles <- readInput (InputOptions input)
58− case runWriterT (parseInputs moduleFiles []) of
58+-- | Argumnets: verbose, use JSON, warnings, errors
59+printWarningsAndErrors :: Bool -> Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO ()
60+printWarningsAndErrors verbose False warnings errors = do
61+ cc <- bool Nothing (Just P.defaultCodeColor) <$> ANSI.hSupportsANSI stderr
62+ let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = verbose }
63+ when (P.nonEmpty warnings) $
64+ hPutStrLn stderr (P.prettyPrintMultipleWarnings ppeOpts warnings)
65+ case errors of
5966 Left errs -> do
60− hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
67+ hPutStrLn stderr (P.prettyPrintMultipleErrors ppeOpts errs)
6168 exitFailure
62− Right ((ms, _), warnings) -> do
63− when (P.nonEmpty warnings) $
64− hPutStrLn stderr (P.prettyPrintMultipleWarnings (P.optionsVerboseErrors opts) warnings)
65− let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, fp)) ms
66− makeActions = buildMakeActions outputDir filePathMap usePrefix
67− (e, warnings') <- runMake opts $ P.make makeActions (map snd ms)
68− case e of
69− Left errs -> do
70− putStrLn (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
71− exitFailure
72− Right _ -> exitSuccess
73−
74−readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
75−readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readUTF8File inFile
76−
77−parseInputs :: (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
78− => [(Either P.RebuildPolicy FilePath, String)]
79− -> [(FilePath, P.ForeignJS)]
80− -> m ([(Either P.RebuildPolicy FilePath, P.Module)], M.Map P.ModuleName FilePath)
81−parseInputs modules foreigns =
82− (,) <$> P.parseModulesFromFiles (either (const "") id) modules
83− <*> P.parseForeignModulesFromFiles foreigns
69+ Right _ -> return ()
70+printWarningsAndErrors verbose True warnings errors = do
71+ hPutStrLn stderr . BU8.toString . B.toStrict . A.encode $
72+ JSONResult (toJSONErrors verbose P.Warning warnings)
73+ (either (toJSONErrors verbose P.Error) (const []) errors)
74+ either (const exitFailure) (const (return ())) errors
75+
76+compile :: PCCMakeOptions -> IO ()
77+compile PCCMakeOptions{..} = do
78+ input <- globWarningOnMisses (unless pccmJSONErrors . warnFileTypeNotFound) pccmInput
79+ when (null input && not pccmJSONErrors) $ do
80+ generateMakefile
81+ exitSuccess
82+ moduleFiles <- readInput input
83+ (makeErrors, makeWarnings) <- runMake pccmOpts $ do
84+ ms <- P.parseModulesFromFiles id moduleFiles
85+ let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, Right fp)) ms
86+ let makeActions = buildMakeActions pccmOutputDir filePathMap pccmUsePrefix
87+ P.make makeActions (map snd ms)
88+ printWarningsAndErrors (P.optionsVerboseErrors pccmOpts) pccmJSONErrors makeWarnings makeErrors
89+ exitSuccess
90+
91+warnFileTypeNotFound :: String -> IO ()
92+warnFileTypeNotFound = hPutStrLn stderr . ("pcc: No files found using pattern: " ++)
93+
94+globWarningOnMisses :: (String -> IO ()) -> [FilePath] -> IO [FilePath]
95+globWarningOnMisses warn = concatMapM globWithWarning
96+ where
97+ globWithWarning pattern = do
98+ paths <- glob pattern
99+ when (null paths) $ warn pattern
100+ return paths
101+ concatMapM f = liftM concat . mapM f
102+
103+readInput :: [FilePath] -> IO [(FilePath, String)]
104+readInput inputFiles = forM inputFiles $ \inFile -> (inFile, ) <$> readUTF8File inFile
84105
85106inputFile :: Parser FilePath
86107inputFile = strArgument $
87108 metavar "FILE"
88109 <> help "The input .purs file(s)"
89110
90−inputForeignFile :: Parser FilePath
91−inputForeignFile = strOption $
92− short 'f'
93− <> long "ffi"
94− <> help "The input .js file(s) providing foreign import implementations"
95−
96111outputDirectory :: Parser FilePath
97112outputDirectory = strOption $
98113 short 'o'
@@ -101,37 +116,26 @@ outputDirectory = strOption $
101116 <> showDefault
102117 <> help "The output directory"
103118
104−requirePath :: Parser (Maybe FilePath)
105−requirePath = optional $ strOption $
106− short 'r'
107− <> long "require-path"
108− <> help "The path prefix to use for require() calls in the generated code"
109−
110119noTco :: Parser Bool
111120noTco = switch $
112121 long "no-tco"
113122 <> help "Disable tail call optimizations"
114123
115−noPrelude :: Parser Bool
116−noPrelude = switch $
117− long "no-prelude"
118− <> help "Omit the automatic Prelude import"
119−
120124noMagicDo :: Parser Bool
121125noMagicDo = switch $
122126 long "no-magic-do"
123− <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
127+ <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad"
124128
125129noOpts :: Parser Bool
126130noOpts = switch $
127131 long "no-opts"
128− <> help "Skip the optimization phase."
132+ <> help "Skip the optimization phase"
129133
130134comments :: Parser Bool
131135comments = switch $
132136 short 'c'
133137 <> long "comments"
134− <> help "Include comments in the generated code."
138+ <> help "Include comments in the generated code"
135139
136140verboseErrors :: Parser Bool
137141verboseErrors = switch $
@@ -145,11 +149,16 @@ noPrefix = switch $
145149 <> long "no-prefix"
146150 <> help "Do not include comment header"
147151
152+jsonErrors :: Parser Bool
153+jsonErrors = switch $
154+ long "json-errors"
155+ <> help "Print errors to stderr as JSON"
148156sourceMaps :: Parser Bool
149157sourceMaps = switch $
150158 long "source-maps"
151159 <> help "Generate source maps"
152160
161+
153162options :: Parser P.Options
154163options = P.Options <$> noTco
155164 <*> noMagicDo
@@ -157,20 +166,22 @@ options = P.Options <$> noTco
157166 <*> noOpts
158167 <*> verboseErrors
159168 <*> (not <$> comments)
160− <*> requirePath
161169 <*> sourceMaps
162170
163−pccOptions :: Parser PCCOptions
164−pccOptions = PCCOptions <$> many inputFile
165− <*> many inputForeignFile
166− <*> outputDirectory
167− <*> options
168− <*> (not <$> noPrefix)
171+pccMakeOptions :: Parser PCCMakeOptions
172+pccMakeOptions = PCCMakeOptions <$> many inputFile
173+ <*> outputDirectory
174+ <*> options
175+ <*> (not <$> noPrefix)
176+ <*> jsonErrors
169177
170178main :: IO ()
171−main = execParser opts >>= compile
179+main = do
180+ hSetEncoding stdout utf8
181+ hSetEncoding stderr utf8
182+ execParser opts >>= compile
172183 where
173− opts = info (version <*> helper <*> pccOptions) infoModList
184+ opts = info (version <*> helper <*> pccMakeOptions) infoModList
174185 infoModList = fullDesc <> headerInfo <> footerInfo
175186 headerInfo = header "pcc - Compiles PureScript to C++11"
176187 footerInfo = footer $ "pcc " ++ showVersion Paths.version
pcc/Make.hs+4−7
@@ -15,6 +15,7 @@
1515{-# LANGUAGE DataKinds #-}
1616{-# LANGUAGE FlexibleContexts #-}
1717{-# LANGUAGE GeneralizedNewtypeDeriving #-}
18+{-# LANGUAGE PatternGuards #-}
1819{-# LANGUAGE TupleSections #-}
1920{-# LANGUAGE TemplateHaskell #-}
2021
@@ -29,9 +30,7 @@ import Control.Monad.Error.Class (MonadError(..))
2930import Control.Monad.Reader
3031
3132import Data.FileEmbed (embedFile)
32−import Data.List (intercalate)
3333import Data.Maybe (fromMaybe)
34−import Data.String (fromString)
3534import Data.Time.Clock
3635import Data.Version (showVersion)
3736import qualified Data.Map as M
@@ -158,11 +157,9 @@ buildMakeActions outputDir filePathMap usePrefix =
158157
159158 writeTextFile :: FilePath -> String -> Make ()
160159 writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
161− mkdirp path
162− writeFile path text
163− where
164− mkdirp :: FilePath -> IO ()
165− mkdirp = createDirectoryIfMissing True . takeDirectory
160+ createDirectoryIfMissing True (takeDirectory path)
161+ _ <- tryIOError $ writeFile path text -- TODO: intended to ignore "file busy", fix properly asap
162+ return ()
166163
167164 -- | Render a progress message
168165 renderProgressMessage :: P.ProgressMessage -> String
pcc/Makefile+1−1
@@ -55,7 +55,7 @@ DEPS = $(SRCS:.cc=.d)
5555$(BIN): $(OBJS)
5656 @echo "Linking" $(BIN_DIR)/$(BIN)
5757 @mkdir -p $(BIN_DIR)
58− @$(CXX) $(LDFLAGS) $^ -o $(BIN_DIR)/$@
58+ @$(CXX) $^ -o $(BIN_DIR)/$@ $(LDFLAGS)
5959
6060-include $(DEPS)
6161
pcc/Makefile.hs+1−1
@@ -10,13 +10,13 @@
1010--
1111-------------------------------------------------------------------------------
1212{-# LANGUAGE OverloadedStrings #-}
13+{-# LANGUAGE PatternGuards #-}
1314{-# LANGUAGE TemplateHaskell #-}
1415
1516module Makefile where
1617
1718import Control.Monad (when)
1819import Data.FileEmbed (embedFile)
19−import Data.List
2020import System.Environment (getExecutablePath)
2121import System.Directory (doesFileExist)
2222
pcc/TestMain.hs+15−8
@@ -49,7 +49,7 @@ main = do
4949
5050 -- Auto-generate Makefile
5151 setCurrentDirectory outputDir
52− callProcess "../.cabal-sandbox/bin/pcc" []
52+ callProcess "pcc" []
5353
5454 let tests = filter (`notElem` skipped) passingTestCases
5555
@@ -62,6 +62,11 @@ main = do
6262 putStrLn $ "Compiling test " ++ inputFile ++ " ..."
6363 setCurrentDirectory outputDir
6464 copyFile (passingDir </> inputFile) (srcDir </> inputFile)
65+
66+ let testCaseDir = passingDir </> (takeWhile (/='.') inputFile)
67+ testCaseDirExists <- doesDirectoryExist testCaseDir
68+ when testCaseDirExists $ callProcess "cp" ["-R", testCaseDir, srcDir]
69+
6570 callProcess "make" ["clean"]
6671 callProcess "make" ["debug"]
6772 --
@@ -70,6 +75,7 @@ main = do
7075 callProcess ("output" </> "bin" </> "main") []
7176
7277 removeFile (srcDir </> inputFile)
78+ when testCaseDirExists $ callProcess "rm" ["-rf", srcDir </> (takeWhile (/='.') inputFile)]
7379
7480 -- TODO: support failing test cases
7581 --
@@ -92,12 +98,13 @@ repo = "git://github.com/pure11/"
9298packages :: [(String, String)]
9399-------------------------------------------------------------------------------
94100packages =
95− [ ("purescript-eff", "")
96− , ("purescript-prelude", "")
97− , ("purescript-assert", "")
98− , ("purescript-st", "")
99− , ("purescript-console", "")
100− , ("purescript-functions", "")
101+ [ ("purescript-eff", "pure11-0.9")
102+ , ("purescript-prelude", "pure11-0.9")
103+ , ("purescript-assert", "pure11-0.9")
104+ , ("purescript-st", "pure11-0.9")
105+ , ("purescript-console", "pure11-0.9")
106+ , ("purescript-functions", "pure11-0.9")
107+ , ("purescript-partial", "pure11-0.9")
101108 ]
102109
103110-------------------------------------------------------------------------------
@@ -116,5 +123,5 @@ fetchPackages = do
116123skipped :: [String]
117124-------------------------------------------------------------------------------
118125skipped =
119− [ "ExplicitImportReExport.purs" -- OK, test has no main (would pass otherwise)
126+ [ "NumberLiterals.purs" -- unreliable float comparison, test manually
120127 ]
pcc/include/purescript.cc+2−2
@@ -45,7 +45,7 @@ auto any::operator()() const -> any {
4545 return (*variant.e)();
4646}
4747
48−any::operator integer() const {
48+any::operator int() const {
4949 RETURN_VALUE(Type::Integer, i,)
5050}
5151
@@ -121,7 +121,7 @@ auto any::operator[](const size_t rhs) const -> const any& {
121121auto any::operator[](const any& rhs) const -> const any& {
122122 const any& variant = unthunkVariant(*this);
123123 assert(variant.type == Type::Array);
124− return (*variant.a)[cast<integer>(rhs)];
124+ return (*variant.a)[cast<int>(rhs)];
125125}
126126
127127auto any::contains(const char key[]) const -> bool {
pcc/include/purescript.hh+14−29
@@ -19,6 +19,7 @@
1919
2020#if defined(DEBUG)
2121 #include <cassert>
22+ #include <climits>
2223#else
2324 #define NDEBUG
2425 #undef assert
@@ -36,7 +37,6 @@
3637
3738namespace PureScript {
3839
39−using integer = std::intptr_t;
4040using cstring = const char *;
4141using nullptr_t = std::nullptr_t;
4242
@@ -46,9 +46,6 @@ public:
4646 runtime_error(const char message[]) : std::runtime_error(std::string(message)) {}
4747};
4848
49−const integer INTEGER_MIN = INTPTR_MIN;
50−const integer INTEGER_MAX = INTPTR_MAX;
51−
5249const bool undefined = false;
5350const size_t constructor = 0;
5451
@@ -128,7 +125,7 @@ class any {
128125 private:
129126 union {
130127 mutable thunk t;
131− mutable integer i;
128+ mutable int i;
132129 mutable double d;
133130 mutable char c;
134131 mutable bool b;
@@ -147,9 +144,11 @@ class any {
147144
148145 public:
149146
150− any(const integer val) noexcept : type(Type::Integer), i(val) {}
151147 any(const int val) noexcept : type(Type::Integer), i(val) {}
152− any(const unsigned int val) noexcept : type(Type::Integer), i(val) {}
148+ any(const long int_value) noexcept : type(Type::Integer), i(int_value) {
149+ assert(int_value >= INT_MIN && int_value <= INT_MAX);
150+ }
151+
153152 any(const double val) noexcept : type(Type::Double), d(val) {}
154153 any(const char val) noexcept : type(Type::Character), c(val) {}
155154
@@ -305,7 +304,7 @@ class any {
305304 auto operator()(const as_thunk) const -> const any&;
306305 auto operator()() const -> any;
307306
308− operator integer() const;
307+ operator int() const;
309308 operator double() const;
310309 operator bool() const;
311310 operator char() const;
@@ -338,20 +337,12 @@ class any {
338337 return lhs op (ty)rhs; \
339338 } \
340339
341− #define DEFINE_INT_OPERATOR(op, rty) \
342− inline friend auto operator op (const any& lhs, int rhs) -> rty { \
343− return (integer)lhs op (integer)rhs; \
344− } \
345− inline friend auto operator op (int lhs, const any& rhs) -> rty { \
346− return (integer)lhs op (integer)rhs; \
347− }
348−
349340 #define DECLARE_COMPARISON_OPERATOR(op) \
350341 friend auto operator op (const any&, const any&) -> bool; \
351− DEFINE_OPERATOR(op, integer, bool) \
342+ DEFINE_OPERATOR(op, int, bool) \
352343 DEFINE_OPERATOR(op, double, bool) \
353344 DEFINE_OPERATOR(op, char, bool) \
354− DEFINE_INT_OPERATOR(op, bool) \
345+ DEFINE_OPERATOR(op, bool, bool) \
355346 friend auto operator op (const any&, const char * const) -> bool; \
356347 friend auto operator op (const char * const, const any&) -> bool;
357348
@@ -364,39 +355,34 @@ class any {
364355
365356 friend auto operator+(const any&, const any&) -> any;
366357
367− DEFINE_OPERATOR(+, integer, integer)
358+ DEFINE_OPERATOR(+, int, int)
368359 DEFINE_OPERATOR(+, double, double)
369360 DEFINE_OPERATOR(+, char, char)
370− DEFINE_INT_OPERATOR(+, integer)
371361 friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
372362 friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
373363
374364 friend auto operator-(const any&, const any&) -> any;
375365
376− DEFINE_OPERATOR(-, integer, integer)
366+ DEFINE_OPERATOR(-, int, int)
377367 DEFINE_OPERATOR(-, double, double)
378368 DEFINE_OPERATOR(-, char, char)
379− DEFINE_INT_OPERATOR(-, integer)
380369
381370 friend auto operator*(const any&, const any&) -> any;
382371
383− DEFINE_OPERATOR(*, integer, integer)
372+ DEFINE_OPERATOR(*, int, int)
384373 DEFINE_OPERATOR(*, double, double)
385374 DEFINE_OPERATOR(*, char, char)
386− DEFINE_INT_OPERATOR(*, integer)
387375
388376 friend auto operator/(const any&, const any&) -> any;
389377
390− DEFINE_OPERATOR(/, integer, integer)
378+ DEFINE_OPERATOR(/, int, int)
391379 DEFINE_OPERATOR(/, double, double)
392380 DEFINE_OPERATOR(/, char, char)
393− DEFINE_INT_OPERATOR(/, integer)
394381
395382 friend auto operator%(const any&, const any&) -> any;
396383
397− DEFINE_OPERATOR(%, integer, integer)
384+ DEFINE_OPERATOR(%, int, int)
398385 DEFINE_OPERATOR(%, char, char)
399− DEFINE_INT_OPERATOR(%, integer)
400386
401387 friend auto operator-(const any&) -> any; // unary negate
402388};
@@ -435,7 +421,6 @@ inline auto cast(const any& a) ->
435421#undef WITH_ALLOCATOR
436422#undef IS_POINTER_TYPE
437423#undef DEFINE_OPERATOR
438−#undef DEFINE_INT_OPERATOR
439424#undef DECLARE_COMPARISON_OPERATOR
440425
441426#endif // PureScript_HH
psc-bundle/Main.hs+2−20
@@ -6,7 +6,6 @@
66-- | Bundles compiled PureScript modules for the browser.
77module Main (main) where
88
9−import Data.Maybe
109import Data.Traversable (for)
1110import Data.Version (showVersion)
1211
@@ -16,7 +15,7 @@ import Control.Monad.Error.Class
1615import Control.Monad.Trans.Except
1716import Control.Monad.IO.Class
1817
19−import System.FilePath (takeFileName, takeDirectory)
18+import System.FilePath (takeDirectory)
2019import System.FilePath.Glob (glob)
2120import System.Exit (exitFailure)
2221import System.IO (stderr, stdout, hPutStrLn, hSetEncoding, utf8)
@@ -36,17 +35,8 @@ data Options = Options
3635 , optionsEntryPoints :: [String]
3736 , optionsMainModule :: Maybe String
3837 , optionsNamespace :: String
39− , optionsRequirePath :: Maybe FilePath
4038 } deriving Show
4139
42−-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
43−guessModuleIdentifier :: (MonadError ErrorMessage m) => FilePath -> m ModuleIdentifier
44−guessModuleIdentifier filename = ModuleIdentifier (takeFileName (takeDirectory filename)) <$> guessModuleType (takeFileName filename)
45− where
46− guessModuleType "index.js" = pure Regular
47− guessModuleType "foreign.js" = pure Foreign
48− guessModuleType name = throwError $ UnsupportedModulePath name
49−
5040-- | The main application function.
5141-- This function parses the input files, performs dead code elimination, filters empty modules
5242-- and generates and prints the final Javascript bundle.
@@ -63,7 +53,7 @@ app Options{..} = do
6353
6454 let entryIds = map (`ModuleIdentifier` Regular) optionsEntryPoints
6555
66− bundle input entryIds optionsMainModule optionsNamespace optionsRequirePath
56+ bundle input entryIds optionsMainModule optionsNamespace
6757
6858-- | Command line options parser.
6959options :: Parser Options
@@ -72,7 +62,6 @@ options = Options <$> some inputFile
7262 <*> many entryPoint
7363 <*> optional mainModule
7464 <*> namespace
75− <*> optional requirePath
7665 where
7766 inputFile :: Parser FilePath
7867 inputFile = strArgument $
@@ -104,19 +93,12 @@ options = Options <$> some inputFile
10493 <> showDefault
10594 <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
10695
107− requirePath :: Parser FilePath
108− requirePath = strOption $
109− short 'r'
110− <> long "require-path"
111− <> help "The path prefix used in require() calls in the generated JavaScript [deprecated]"
112−
11396-- | Make it go.
11497main :: IO ()
11598main = do
11699 hSetEncoding stdout utf8
117100 hSetEncoding stderr utf8
118101 opts <- execParser (info (version <*> helper <*> options) infoModList)
119− when (isJust (optionsRequirePath opts)) $ hPutStrLn stderr "The require-path option is deprecated and will be removed in PureScript 0.9."
120102 output <- runExceptT (app opts)
121103 case output of
122104 Left err -> do
psc-docs/Main.hs+1−1
@@ -95,7 +95,7 @@ docgen (PSCDocsOptions fmt inputGlob output) = do
9595 Right x ->
9696 return x
9797 Left err -> do
98− hPutStrLn stderr $ P.prettyPrintMultipleErrors False err
98+ hPutStrLn stderr $ P.prettyPrintMultipleErrors P.defaultPPEOptions err
9999 exitFailure
100100
101101 takeByName = takeModulesByName D.modName
psc-ide-client/Main.hs+6−16
@@ -5,16 +5,15 @@ import Prelude ()
55import Prelude.Compat
66
77import Control.Exception
8−import Data.Text (Text)
9−import qualified Data.Text as T
10−import qualified Data.Text.IO as T
11−import Data.Version (showVersion)
8+import qualified Data.ByteString.Char8 as BS8
9+import qualified Data.Text.IO as T
10+import Data.Version (showVersion)
1211import Network
1312import Options.Applicative
1413import System.Exit
1514import System.IO
1615
17−import qualified Paths_purescript as Paths
16+import qualified Paths_purescript as Paths
1817
1918data Options = Options
2019 { optionsPort :: PortID
@@ -41,16 +40,7 @@ client port = do
4140 ("Couldn't connect to psc-ide-server on port: " ++
4241 show port ++ " Error: " ++ show e) >>
4342 exitFailure)
44− cmd <- T.getLine
45− -- Temporary fix for emacs windows bug
46− let cleanedCmd = removeSurroundingTicks cmd
47− --
48− T.hPutStrLn h cleanedCmd
49− res <- T.hGetLine h
50− putStrLn (T.unpack res)
43+ T.hPutStrLn h =<< T.getLine
44+ BS8.putStrLn =<< BS8.hGetLine h
5145 hFlush stdout
5246 hClose h
53−
54−-- TODO: Fix this in the emacs plugin by using a real process over shellcommands
55−removeSurroundingTicks :: Text -> Text
56−removeSurroundingTicks = T.dropWhile (== '\'') . T.dropWhileEnd (== '\'')
psc-ide-server/Main.hs+39−56
@@ -12,28 +12,22 @@
1212-- The server accepting commands for psc-ide
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
1615{-# LANGUAGE FlexibleContexts #-}
1716{-# LANGUAGE MultiParamTypeClasses #-}
1817{-# LANGUAGE OverloadedStrings #-}
1918{-# LANGUAGE PackageImports #-}
2019{-# LANGUAGE TemplateHaskell #-}
20+{-# LANGUAGE NoImplicitPrelude #-}
2121
2222module Main where
2323
24−import Prelude ()
25−import Prelude.Compat
24+import Protolude
2625
27−import Control.Concurrent (forkFinally)
26+import qualified Data.Aeson as Aeson
2827import Control.Concurrent.STM
29−import Control.Exception (bracketOnError, catchJust)
30−import Control.Monad
31−import Control.Monad.Error.Class
3228import "monad-logger" Control.Monad.Logger
33−import Control.Monad.Reader
34−import Control.Monad.Trans.Except
35−import qualified Data.Text as T
3629import qualified Data.Text.IO as T
30+import qualified Data.ByteString.Lazy.Char8 as BS8
3731import Data.Version (showVersion)
3832import Language.PureScript.Ide
3933import Language.PureScript.Ide.Util
@@ -44,19 +38,16 @@ import Network hiding (socketPort, accept)
4438import Network.BSD (getProtocolNumber)
4539import Network.Socket hiding (PortNumber, Type,
4640 sClose)
47−import Options.Applicative
41+import Options.Applicative hiding ((<>))
4842import System.Directory
4943import System.FilePath
50−import System.IO
44+import System.IO hiding (putStrLn, print)
5145import System.IO.Error (isEOFError)
5246
5347import qualified Paths_purescript as Paths
5448
55−-- "Borrowed" from the Idris Compiler
56−-- Copied from upstream impl of listenOn
57−-- bound to localhost interface instead of iNADDR_ANY
58−listenOnLocalhost :: PortID -> IO Socket
59−listenOnLocalhost (PortNumber port) = do
49+listenOnLocalhost :: PortNumber -> IO Socket
50+listenOnLocalhost port = do
6051 proto <- getProtocolNumber "tcp"
6152 localhost <- inet_addr "127.0.0.1"
6253 bracketOnError
@@ -67,66 +58,59 @@ listenOnLocalhost (PortNumber port) = do
6758 bindSocket sock (SockAddrInet port localhost)
6859 listen sock maxListenQueue
6960 pure sock)
70−listenOnLocalhost _ = error "Wrong Porttype"
7161
7262data Options = Options
7363 { optionsDirectory :: Maybe FilePath
64+ , optionsGlobs :: [FilePath]
7465 , optionsOutputPath :: FilePath
75− , optionsPort :: PortID
66+ , optionsPort :: PortNumber
67+ , optionsNoWatch :: Bool
7668 , optionsDebug :: Bool
7769 }
7870
7971main :: IO ()
8072main = do
81− Options dir outputPath port debug <- execParser opts
73+ Options dir globs outputPath port noWatch debug <- execParser opts
8274 maybe (pure ()) setCurrentDirectory dir
83− serverState <- newTVarIO emptyPscIdeState
75+ ideState <- newTVarIO emptyIdeState
8476 cwd <- getCurrentDirectory
8577 let fullOutputPath = cwd </> outputPath
8678
87− doesDirectoryExist fullOutputPath
88− >>= flip unless
89− (do putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
90− createDirectory fullOutputPath
91− putStrLn "This usually means you didn't compile your project yet."
92− putStrLn "psc-ide needs you to compile your project (for example by running pulp build)"
93− )
79+ unlessM (doesDirectoryExist fullOutputPath) $ do
80+ putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
81+ createDirectory fullOutputPath
82+ putText "This usually means you didn't compile your project yet."
83+ putText "psc-ide needs you to compile your project (for example by running pulp build)"
9484
95− _ <- forkFinally (watcher serverState fullOutputPath) print
96− let conf =
97− Configuration
98− {
99− confDebug = debug
100− , confOutputPath = outputPath
101− }
102− let env =
103− PscIdeEnvironment
104− {
105− envStateVar = serverState
106− , envConfiguration = conf
107− }
85+ unless noWatch $
86+ void (forkFinally (watcher ideState fullOutputPath) print)
87+
88+ let conf = Configuration {confDebug = debug, confOutputPath = outputPath, confGlobs = globs}
89+ env = IdeEnvironment {ideStateVar = ideState, ideConfiguration = conf}
10890 startServer port env
10991 where
11092 parser =
111− Options <$>
112− optional (strOption (long "directory" <> short 'd')) <*>
113− strOption (long "output-directory" <> value "output/") <*>
114− (PortNumber . fromIntegral <$>
115− option auto (long "port" <> short 'p' <> value (4242 :: Integer))) <*>
116− switch (long "debug")
93+ Options
94+ <$> optional (strOption (long "directory" `mappend` short 'd'))
95+ <*> many (argument str (metavar "Source GLOBS..."))
96+ <*> strOption (long "output-directory" `mappend` value "output/")
97+ <*> (fromIntegral <$>
98+ option auto (long "port" `mappend` short 'p' `mappend` value (4242 :: Integer)))
99+ <*> switch (long "no-watch")
100+ <*> switch (long "debug")
117101 opts = info (version <*> helper <*> parser) mempty
118102 version = abortOption
119103 (InfoMsg (showVersion Paths.version))
120− (long "version" <> help "Show the version number")
104+ (long "version" `mappend` help "Show the version number")
121105
122−startServer :: PortID -> PscIdeEnvironment -> IO ()
106+startServer :: PortNumber -> IdeEnvironment -> IO ()
123107startServer port env = withSocketsDo $ do
124108 sock <- listenOnLocalhost port
125109 runLogger (runReaderT (forever (loop sock)) env)
126110 where
127− runLogger = runStdoutLoggingT . filterLogger (\_ _ -> confDebug (envConfiguration env))
111+ runLogger = runStdoutLoggingT . filterLogger (\_ _ -> confDebug (ideConfiguration env))
128112
129− loop :: (PscIde m, MonadLogger m) => Socket -> m ()
113+ loop :: (Ide m, MonadLogger m) => Socket -> m ()
130114 loop sock = do
131115 accepted <- runExceptT $ acceptCommand sock
132116 case accepted of
@@ -138,9 +122,8 @@ startServer port env = withSocketsDo $ do
138122 -- $(logDebug) ("Answer was: " <> T.pack (show result))
139123 liftIO (hFlush stdout)
140124 case result of
141− -- What function can I use to clean this up?
142− Right r -> liftIO $ T.hPutStrLn h (encodeT r)
143− Left err -> liftIO $ T.hPutStrLn h (encodeT err)
125+ Right r -> liftIO $ BS8.hPutStrLn h (Aeson.encode r)
126+ Left err -> liftIO $ BS8.hPutStrLn h (Aeson.encode err)
144127 Nothing -> do
145128 $(logDebug) ("Parsing the command failed. Command: " <> cmd)
146129 liftIO $ do
@@ -149,8 +132,8 @@ startServer port env = withSocketsDo $ do
149132 liftIO (hClose h)
150133
151134
152−acceptCommand :: (MonadIO m, MonadLogger m, MonadError T.Text m)
153− => Socket -> m (T.Text, Handle)
135+acceptCommand :: (MonadIO m, MonadLogger m, MonadError Text m)
136+ => Socket -> m (Text, Handle)
154137acceptCommand sock = do
155138 h <- acceptConnection
156139 $(logDebug) "Accepted a connection"
psc-ide-server/PROTOCOL.md+52−25
@@ -14,64 +14,88 @@ to detect all the compiled modules in your project and load them.
1414
1515**Params:**
1616 - `modules :: (optional) [ModuleName]`: A list of modules to load.
17− psc-ide-server will try to parse all the declarations in these modules
18− - `dependencies :: (optional) [ModuleName]`: A list of modules to load
19− including their dependencies. In contrast to the `module` field, all the
20− imports in these Modules will also be loaded.
17+ psc-ide-server will try to parse all the declarations in these modules
2118
2219```json
2320{
2421 "command": "load",
2522 "params": (optional) {
26− "modules": (optional)["Module.Name1", "Module.Name2"],
27− "dependencies": (optional)["Module.Name3"]
23+ "modules": (optional)["Module.Name1", "Module.Name2"]
2824 }
2925}
3026```
3127
3228**Result:**
3329
34−The Load Command returns a string.
30+The Load Command returns a string with a summary about the loading process.
3531
3632### Type
37−The `type` command looks up the type for a given identifier.
33+The `type` command looks up the type for a given identifier. It also returns the
34+definition position, if it can be found in the passed source files.
3835
3936**Params:**
4037 - `search :: String`: The identifier to look for. Only matches on equality.
41− - `filters :: [Filter]`: These filters will be applied before looking for the
38+ - `filters :: (optional) [Filter]`: These filters will be applied before looking for the
4239 identifier. These filters get combined with *AND*, so a candidate must match *ALL*
4340 of them to be eligible.
41+ - `currentModule :: (optional) String`: see *Complete* command
4442```json
4543{
4644 "command": "type",
4745 "params": {
4846 "search": "filterM",
49− "filters": [Filter]
47+ "filters": [{..}],
48+ "currentModule": "Main"
5049 }
5150}
5251```
5352
5453**Result:**
55−The possible types are returned in the same format as completions
54+The possible types are returned in the same format as completions + eventual position information
55+```json
56+[
57+ {
58+ "module": "Data.Array",
59+ "identifier": "filter",
60+ "type": "forall a. (a -> Boolean) -> Array a -> Array a"
61+ },
62+ {
63+ "module": "Data.Array",
64+ "identifier": "filter",
65+ "type": "forall a. (a -> Boolean) -> Array a -> Array a",
66+ "definedAt":
67+ {
68+ "name": "/path/to/file",
69+ "start": [1, 3],
70+ "end": [3, 1]
71+ }
72+ }
73+]
74+```
5675
5776### Complete
5877The `complete` command looks up possible completions/corrections.
5978
6079**Params**:
61− - `filters :: [Filter]`: The same as for the `type` command. A candidate must match
62− all filters.
63− - `matcher :: (optional) Matcher`: The strategy used for matching candidates after filtering.
64− Results are scored internally and will be returned in the descending order where
65− the nth element is better then the n+1-th.
66−
67− If no matcher is given every candidate, that passes the filters, is returned in no
68− particular order.
80+ - `filters :: [Filter]`: The same as for the `type` command. A candidate must
81+ match all filters.
82+ - `matcher :: (optional) Matcher`: The strategy used for matching candidates
83+ after filtering. Results are scored internally and will be returned in the
84+ descending order where the nth element is better then the n+1-th.
85+ - `currentModule :: (optional) String`: The current modules name. If it matches
86+ with the rebuild cache non-exported modules will also be completed. You can
87+ fill the rebuild cache by using the "Rebuild" command.
88+
89+ If no matcher is given every candidate, that passes the filters, is returned
90+ in no particular order.
91+
6992```json
7093{
7194 "command": "complete",
7295 "params": {
73− "filters": [Filter],
74− "matcher": (optional) Matcher
96+ "filters": [{..}, {..}],
97+ "matcher": {..}
98+ "currentModule": "Main"
7599 }
76100}
77101```
@@ -244,10 +268,11 @@ Example:
244268
245269The `rebuild` command provides a fast rebuild for a single module. It doesn't
246270recompile the entire project though. All the modules dependencies need to be
247−loaded.
271+loaded. A successful rebuild will be stored to allow for completions of private
272+identifiers.
248273
249274Arguments:
250−- `file :: String` the path to the module to rebuild
275+ - `file :: String` the path to the module to rebuild
251276
252277```json
253278{
@@ -407,14 +432,16 @@ Hiding Import(`import Data.Array hiding (filter, filterM, join)`):
407432 }
408433]
409434```
410−### Cwd/Quit
435+### Cwd/Quit/Reset
411436`cwd` returns the working directory of the server(should be your project root).
412437
413438`quit` quits the server.
414439
440+`reset` resets all loaded modules.
441+
415442```json
416443{
417− "command": "cwd|quit"
444+ "command": "cwd|quit|reset"
418445}
419446```
420447
psc-ide-server/README.md+5−1
@@ -10,7 +10,10 @@ A tool which provides editor support for the PureScript programming language.
1010* Vim integration is available here: https://github.com/FrigoEU/psc-ide-vim.
1111
1212## Running the Server
13−Start the server by running the `psc-ide-server` executable.
13+
14+Start the server by running the `psc-ide-server [SOURCEGLOBS]` executable, where
15+`SOURCEGLOBS` are (optional) globs that match your PureScript sourcefiles.
16+
1417It supports the following options:
1518
1619- `-p / --port` specify a port. Defaults to 4242
@@ -20,6 +23,7 @@ It supports the following options:
2023 project directory. Defaults to `output/`, relative to either the current
2124 directory or the directory specified by `-d`.
2225- `--debug`: Enables some logging meant for debugging
26+- `--no-watch`: Disables the filewatcher
2327- `--version`: Output psc-ide version
2428
2529## Issuing queries
psc/Main.hs+27−53
@@ -1,56 +1,54 @@
11{-# LANGUAGE DataKinds #-}
22{-# LANGUAGE FlexibleContexts #-}
33{-# LANGUAGE RecordWildCards #-}
4+{-# LANGUAGE ScopedTypeVariables #-}
45{-# LANGUAGE TupleSections #-}
56
67module Main where
78
8−import Control.Applicative
9−import Control.Monad
10−import Control.Monad.Error.Class (MonadError(..))
11−import Control.Monad.Writer.Strict
9+import Control.Applicative
10+import Control.Monad
11+import Control.Monad.Writer.Strict
1212
13−import Data.List (isSuffixOf, partition)
14−import Data.Version (showVersion)
15−import qualified Data.Map as M
1613import qualified Data.Aeson as A
14+import Data.Bool (bool)
1715import qualified Data.ByteString.Lazy as B
1816import qualified Data.ByteString.UTF8 as BU8
17+import qualified Data.Map as M
18+import Data.Version (showVersion)
1919
20−import Options.Applicative as Opts
20+import qualified Language.PureScript as P
21+import Language.PureScript.Errors.JSON
22+import Language.PureScript.Make
2123
22−import System.Exit (exitSuccess, exitFailure)
23−import System.IO (hSetEncoding, hPutStrLn, stdout, stderr, utf8)
24−import System.IO.UTF8
25−import System.FilePath.Glob (glob)
24+import Options.Applicative as Opts
2625
27−import qualified Language.PureScript as P
2826import qualified Paths_purescript as Paths
2927
30−import Language.PureScript.Make
31−import Language.PureScript.Errors.JSON
28+import qualified System.Console.ANSI as ANSI
29+import System.Exit (exitSuccess, exitFailure)
30+import System.FilePath.Glob (glob)
31+import System.IO (hSetEncoding, hPutStrLn, stdout, stderr, utf8)
32+import System.IO.UTF8
3233
3334data PSCMakeOptions = PSCMakeOptions
3435 { pscmInput :: [FilePath]
35− , pscmForeignInput :: [FilePath]
3636 , pscmOutputDir :: FilePath
3737 , pscmOpts :: P.Options
3838 , pscmUsePrefix :: Bool
3939 , pscmJSONErrors :: Bool
4040 }
4141
42−data InputOptions = InputOptions
43− { ioInputFiles :: [FilePath]
44− }
45−
4642-- | Argumnets: verbose, use JSON, warnings, errors
4743printWarningsAndErrors :: Bool -> Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO ()
4844printWarningsAndErrors verbose False warnings errors = do
45+ cc <- bool Nothing (Just P.defaultCodeColor) <$> ANSI.hSupportsANSI stderr
46+ let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = verbose }
4947 when (P.nonEmpty warnings) $
50− hPutStrLn stderr (P.prettyPrintMultipleWarnings verbose warnings)
48+ hPutStrLn stderr (P.prettyPrintMultipleWarnings ppeOpts warnings)
5149 case errors of
5250 Left errs -> do
53− hPutStrLn stderr (P.prettyPrintMultipleErrors verbose errs)
51+ hPutStrLn stderr (P.prettyPrintMultipleErrors ppeOpts errs)
5452 exitFailure
5553 Right _ -> return ()
5654printWarningsAndErrors verbose True warnings errors = do
@@ -65,14 +63,12 @@ compile PSCMakeOptions{..} = do
6563 when (null input && not pscmJSONErrors) $ do
6664 hPutStrLn stderr "psc: No input files."
6765 exitFailure
68− let (jsFiles, pursFiles) = partition (isSuffixOf ".js") input
69− moduleFiles <- readInput (InputOptions pursFiles)
70− inputForeign <- globWarningOnMisses (unless pscmJSONErrors . warnFileTypeNotFound) pscmForeignInput
71− foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readUTF8File inFile)
66+ moduleFiles <- readInput input
7267 (makeErrors, makeWarnings) <- runMake pscmOpts $ do
73− (ms, foreigns) <- parseInputs moduleFiles foreignFiles
74− let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, fp)) ms
75− makeActions = buildMakeActions pscmOutputDir filePathMap foreigns pscmUsePrefix
68+ ms <- P.parseModulesFromFiles id moduleFiles
69+ let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, Right fp)) ms
70+ foreigns <- inferForeignModules filePathMap
71+ let makeActions = buildMakeActions pscmOutputDir filePathMap foreigns pscmUsePrefix
7672 P.make makeActions (map snd ms)
7773 printWarningsAndErrors (P.optionsVerboseErrors pscmOpts) pscmJSONErrors makeWarnings makeErrors
7874 exitSuccess
@@ -89,28 +85,14 @@ globWarningOnMisses warn = concatMapM globWithWarning
8985 return paths
9086 concatMapM f = liftM concat . mapM f
9187
92−readInput :: InputOptions -> IO [(Either P.RebuildPolicy FilePath, String)]
93−readInput InputOptions{..} = forM ioInputFiles $ \inFile -> (Right inFile, ) <$> readUTF8File inFile
94−
95−parseInputs :: (MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
96− => [(Either P.RebuildPolicy FilePath, String)]
97− -> [(FilePath, P.ForeignJS)]
98− -> m ([(Either P.RebuildPolicy FilePath, P.Module)], M.Map P.ModuleName FilePath)
99−parseInputs modules foreigns =
100− (,) <$> P.parseModulesFromFiles (either (const "") id) modules
101− <*> P.parseForeignModulesFromFiles foreigns
88+readInput :: [FilePath] -> IO [(FilePath, String)]
89+readInput inputFiles = forM inputFiles $ \inFile -> (inFile, ) <$> readUTF8File inFile
10290
10391inputFile :: Parser FilePath
10492inputFile = strArgument $
10593 metavar "FILE"
10694 <> help "The input .purs file(s)"
10795
108−inputForeignFile :: Parser FilePath
109−inputForeignFile = strOption $
110− short 'f'
111− <> long "ffi"
112− <> help "The input .js file(s) providing foreign import implementations"
113−
11496outputDirectory :: Parser FilePath
11597outputDirectory = strOption $
11698 short 'o'
@@ -119,12 +101,6 @@ outputDirectory = strOption $
119101 <> showDefault
120102 <> help "The output directory"
121103
122−requirePath :: Parser (Maybe FilePath)
123−requirePath = optional $ strOption $
124− short 'r'
125− <> long "require-path"
126− <> help "The path prefix to use for require() calls in the generated JavaScript [deprecated]"
127−
128104noTco :: Parser Bool
129105noTco = switch $
130106 long "no-tco"
@@ -175,12 +151,10 @@ options = P.Options <$> noTco
175151 <*> noOpts
176152 <*> verboseErrors
177153 <*> (not <$> comments)
178− <*> requirePath
179154 <*> sourceMaps
180155
181156pscMakeOptions :: Parser PSCMakeOptions
182157pscMakeOptions = PSCMakeOptions <$> many inputFile
183− <*> many inputForeignFile
184158 <*> outputDirectory
185159 <*> options
186160 <*> (not <$> noPrefix)
psci/Main.hsnew file+364
@@ -0,0 +1,364 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE DoAndIfThenElse #-}
3+{-# LANGUAGE GADTs #-}
4+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+{-# LANGUAGE MultiParamTypeClasses #-}
6+{-# LANGUAGE OverloadedStrings #-}
7+{-# LANGUAGE PatternGuards #-}
8+{-# LANGUAGE RecordWildCards #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
10+{-# LANGUAGE TemplateHaskell #-}
11+{-# LANGUAGE TupleSections #-}
12+
13+module Main (main) where
14+
15+import Prelude ()
16+import Prelude.Compat
17+
18+import Data.FileEmbed (embedStringFile)
19+import Data.Monoid ((<>))
20+import Data.String (IsString(..))
21+import Data.Text (Text, unpack)
22+import Data.Traversable (for)
23+import Data.Version (showVersion)
24+
25+import Control.Applicative (many, (<|>))
26+import Control.Concurrent (forkIO)
27+import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar,
28+ tryPutMVar)
29+import Control.Concurrent.STM (TVar, atomically, newTVarIO, writeTVar,
30+ readTVarIO,
31+ TChan, newBroadcastTChanIO, dupTChan,
32+ readTChan, writeTChan)
33+import Control.Exception (fromException)
34+import Control.Monad
35+import Control.Monad.IO.Class (liftIO)
36+import Control.Monad.Trans.Class
37+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
38+import Control.Monad.Trans.State.Strict (StateT, evalStateT)
39+import Control.Monad.Trans.Reader (ReaderT, runReaderT)
40+
41+import qualified Language.PureScript as P
42+import qualified Language.PureScript.Bundle as Bundle
43+import Language.PureScript.Interactive
44+
45+import Network.HTTP.Types.Header (hContentType, hCacheControl,
46+ hPragma, hExpires)
47+import Network.HTTP.Types.Status (status200, status404, status503)
48+import qualified Network.Wai as Wai
49+import qualified Network.Wai.Handler.Warp as Warp
50+import qualified Network.Wai.Handler.WebSockets as WS
51+import qualified Network.WebSockets as WS
52+
53+import qualified Options.Applicative as Opts
54+
55+import qualified Paths_purescript as Paths
56+
57+import System.Console.Haskeline
58+import System.IO.UTF8 (readUTF8File)
59+import System.Exit
60+import System.FilePath ((</>))
61+import System.FilePath.Glob (glob)
62+import System.Process (readProcessWithExitCode)
63+
64+-- | Command line options
65+data PSCiOptions = PSCiOptions
66+ { psciMultiLineMode :: Bool
67+ , psciInputFile :: [FilePath]
68+ , psciBackend :: Backend
69+ }
70+
71+multiLineMode :: Opts.Parser Bool
72+multiLineMode = Opts.switch $
73+ Opts.long "multi-line-mode"
74+ <> Opts.short 'm'
75+ <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
76+
77+inputFile :: Opts.Parser FilePath
78+inputFile = Opts.strArgument $
79+ Opts.metavar "FILE"
80+ <> Opts.help "Optional .purs files to load on start"
81+
82+nodeFlagsFlag :: Opts.Parser [String]
83+nodeFlagsFlag = Opts.option parser $
84+ Opts.long "node-opts"
85+ <> Opts.metavar "NODE_OPTS"
86+ <> Opts.value []
87+ <> Opts.help "Flags to pass to node, separated by spaces"
88+ where
89+ parser = words <$> Opts.str
90+
91+port :: Opts.Parser Int
92+port = Opts.option Opts.auto $
93+ Opts.long "port"
94+ <> Opts.short 'p'
95+ <> Opts.help "The web server port"
96+
97+backend :: Opts.Parser Backend
98+backend =
99+ (browserBackend <$> port)
100+ <|> (nodeBackend <$> nodeFlagsFlag)
101+
102+psciOptions :: Opts.Parser PSCiOptions
103+psciOptions = PSCiOptions <$> multiLineMode
104+ <*> many inputFile
105+ <*> backend
106+
107+version :: Opts.Parser (a -> a)
108+version = Opts.abortOption (Opts.InfoMsg (showVersion Paths.version)) $
109+ Opts.long "version" <>
110+ Opts.help "Show the version number" <>
111+ Opts.hidden
112+
113+getOpt :: IO PSCiOptions
114+getOpt = Opts.execParser opts
115+ where
116+ opts = Opts.info (version <*> Opts.helper <*> psciOptions) infoModList
117+ infoModList = Opts.fullDesc <> headerInfo <> footerInfo
118+ headerInfo = Opts.header "psci - Interactive mode for PureScript"
119+ footerInfo = Opts.footer $ "psci " ++ showVersion Paths.version
120+
121+-- | Parses the input and returns either a command, or an error as a 'String'.
122+getCommand :: forall m. MonadException m => Bool -> InputT m (Either String (Maybe Command))
123+getCommand singleLineMode = handleInterrupt (return (Right Nothing)) $ do
124+ firstLine <- withInterrupt $ getInputLine "> "
125+ case firstLine of
126+ Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty
127+ Just "" -> return (Right Nothing)
128+ Just s | singleLineMode || head s == ':' -> return . fmap Just $ parseCommand s
129+ Just s -> fmap Just . parseCommand <$> go [s]
130+ where
131+ go :: [String] -> InputT m String
132+ go ls = maybe (return . unlines $ reverse ls) (go . (:ls)) =<< getInputLine " "
133+
134+-- | Make a JavaScript bundle for the browser.
135+bundle :: IO (Either Bundle.ErrorMessage String)
136+bundle = runExceptT $ do
137+ inputFiles <- liftIO (glob (".psci_modules" </> "node_modules" </> "*" </> "*.js"))
138+ input <- for inputFiles $ \filename -> do
139+ js <- liftIO (readUTF8File filename)
140+ mid <- Bundle.guessModuleIdentifier filename
141+ length js `seq` return (mid, js)
142+ Bundle.bundle input [] Nothing "PSCI"
143+
144+indexJS :: IsString string => string
145+indexJS = $(embedStringFile "psci/static/index.js")
146+
147+indexPage :: IsString string => string
148+indexPage = $(embedStringFile "psci/static/index.html")
149+
150+-- | All of the functions required to implement a PSCi backend
151+data Backend = forall state. Backend
152+ { _backendSetup :: IO state
153+ -- ^ Initialize, and call the continuation when the backend is ready
154+ , _backendEval :: state -> String -> IO ()
155+ -- ^ Evaluate JavaScript code
156+ , _backendReload :: state -> IO ()
157+ -- ^ Reload the compiled code
158+ , _backendShutdown :: state -> IO ()
159+ -- ^ Shut down the backend
160+ }
161+
162+-- | Commands which can be sent to the browser
163+data BrowserCommand
164+ = Eval (MVar String)
165+ -- ^ Evaluate the latest JS
166+ | Reload
167+ -- ^ Reload the page
168+
169+-- | State for the browser backend
170+data BrowserState = BrowserState
171+ { browserCommands :: TChan BrowserCommand
172+ -- ^ A channel which receives data when the compiled JS has
173+ -- been updated
174+ , browserShutdownNotice :: MVar ()
175+ -- ^ An MVar which becomes full when the server should shut down
176+ , browserIndexJS :: TVar (Maybe String)
177+ -- ^ A TVar holding the latest compiled JS
178+ , browserBundleJS :: TVar (Maybe String)
179+ -- ^ A TVar holding the latest bundled JS
180+ }
181+
182+browserBackend :: Int -> Backend
183+browserBackend serverPort = Backend setup evaluate reload shutdown
184+ where
185+ setup :: IO BrowserState
186+ setup = do
187+ shutdownVar <- newEmptyMVar
188+ cmdChan <- newBroadcastTChanIO
189+ indexJs <- newTVarIO Nothing
190+ bundleJs <- newTVarIO Nothing
191+
192+ let
193+ handleWebsocket :: WS.PendingConnection -> IO ()
194+ handleWebsocket pending = do
195+ conn <- WS.acceptRequest pending
196+ -- Fork a thread to keep the connection alive
197+ WS.forkPingThread conn 10
198+ -- Clone the command channel
199+ cmdChanCopy <- atomically $ dupTChan cmdChan
200+ -- Listen for commands
201+ forever $ do
202+ cmd <- atomically $ readTChan cmdChanCopy
203+ case cmd of
204+ Eval resultVar -> void $ do
205+ WS.sendTextData conn ("eval" :: Text)
206+ result <- WS.receiveData conn
207+ -- With many connected clients, all but one of
208+ -- these attempts will fail.
209+ tryPutMVar resultVar (unpack result)
210+ Reload -> do
211+ WS.sendTextData conn ("reload" :: Text)
212+
213+ shutdownHandler :: IO () -> IO ()
214+ shutdownHandler stopServer = void . forkIO $ do
215+ () <- takeMVar shutdownVar
216+ stopServer
217+
218+ onException :: Maybe Wai.Request -> SomeException -> IO ()
219+ onException req ex
220+ | Just (_ :: WS.ConnectionException) <- fromException ex
221+ = return () -- ignore websocket disconnects
222+ | otherwise = Warp.defaultOnException req ex
223+
224+ staticServer :: Wai.Application
225+ staticServer req respond =
226+ case Wai.pathInfo req of
227+ [] ->
228+ respond $ Wai.responseLBS status200
229+ [(hContentType, "text/html")]
230+ indexPage
231+ ["js", "index.js"] ->
232+ respond $ Wai.responseLBS status200
233+ [(hContentType, "application/javascript")]
234+ indexJS
235+ ["js", "latest.js"] -> do
236+ may <- readTVarIO indexJs
237+ case may of
238+ Nothing ->
239+ respond $ Wai.responseLBS status503 [] "Service not available"
240+ Just js ->
241+ respond $ Wai.responseLBS status200
242+ [ (hContentType, "application/javascript")
243+ , (hCacheControl, "no-cache, no-store, must-revalidate")
244+ , (hPragma, "no-cache")
245+ , (hExpires, "0")
246+ ]
247+ (fromString js)
248+ ["js", "bundle.js"] -> do
249+ may <- readTVarIO bundleJs
250+ case may of
251+ Nothing ->
252+ respond $ Wai.responseLBS status503 [] "Service not available"
253+ Just js ->
254+ respond $ Wai.responseLBS status200
255+ [ (hContentType, "application/javascript")]
256+ (fromString js)
257+ _ -> respond $ Wai.responseLBS status404 [] "Not found"
258+
259+ let browserState = BrowserState cmdChan shutdownVar indexJs bundleJs
260+ createBundle browserState
261+
262+ putStrLn $ "Serving http://localhost:" <> show serverPort <> "/. Waiting for connections..."
263+ _ <- forkIO $ Warp.runSettings ( Warp.setInstallShutdownHandler shutdownHandler
264+ . Warp.setPort serverPort
265+ . Warp.setOnException onException
266+ $ Warp.defaultSettings
267+ ) $
268+ WS.websocketsOr WS.defaultConnectionOptions
269+ handleWebsocket
270+ staticServer
271+ return browserState
272+
273+ createBundle :: BrowserState -> IO ()
274+ createBundle state = do
275+ putStrLn "Bundling Javascript..."
276+ ejs <- bundle
277+ case ejs of
278+ Left err -> do
279+ putStrLn (unlines (Bundle.printErrorMessage err))
280+ exitFailure
281+ Right js -> do
282+ atomically $ writeTVar (browserBundleJS state) (Just js)
283+
284+ reload :: BrowserState -> IO ()
285+ reload state = do
286+ createBundle state
287+ atomically $ writeTChan (browserCommands state) Reload
288+
289+ shutdown :: BrowserState -> IO ()
290+ shutdown state = putMVar (browserShutdownNotice state) ()
291+
292+ evaluate :: BrowserState -> String -> IO ()
293+ evaluate state js = liftIO $ do
294+ resultVar <- newEmptyMVar
295+ atomically $ do
296+ writeTVar (browserIndexJS state) (Just js)
297+ writeTChan (browserCommands state) (Eval resultVar)
298+ result <- takeMVar resultVar
299+ putStrLn result
300+
301+nodeBackend :: [String] -> Backend
302+nodeBackend nodeArgs = Backend setup eval reload shutdown
303+ where
304+ setup :: IO ()
305+ setup = return ()
306+
307+ eval :: () -> String -> IO ()
308+ eval _ _ = do
309+ writeFile indexFile "require('$PSCI')['$main']();"
310+ process <- findNodeProcess
311+ result <- traverse (\node -> readProcessWithExitCode node (nodeArgs ++ [indexFile]) "") process
312+ case result of
313+ Just (ExitSuccess, out, _) -> putStrLn out
314+ Just (ExitFailure _, _, err) -> putStrLn err
315+ Nothing -> putStrLn "Couldn't find node.js"
316+
317+ reload :: () -> IO ()
318+ reload _ = return ()
319+
320+ shutdown :: () -> IO ()
321+ shutdown _ = return ()
322+
323+-- | Get command line options and drop into the REPL
324+main :: IO ()
325+main = getOpt >>= loop
326+ where
327+ loop :: PSCiOptions -> IO ()
328+ loop PSCiOptions{..} = do
329+ inputFiles <- concat <$> traverse glob psciInputFile
330+ e <- runExceptT $ do
331+ modules <- ExceptT (loadAllModules inputFiles)
332+ unless (supportModuleIsDefined (map snd modules)) . liftIO $ do
333+ putStrLn supportModuleMessage
334+ exitFailure
335+ (externs, env) <- ExceptT . runMake . make $ modules
336+ return (modules, externs, env)
337+ case psciBackend of
338+ Backend setup eval reload (shutdown :: state -> IO ()) -> do
339+ case e of
340+ Left errs -> putStrLn (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure
341+ Right (modules, externs, env) -> do
342+ historyFilename <- getHistoryFilename
343+ let settings = defaultSettings { historyFile = Just historyFilename }
344+ initialState = PSCiState [] [] (zip (map snd modules) externs)
345+ config = PSCiConfig inputFiles env
346+ runner = flip runReaderT config
347+ . flip evalStateT initialState
348+ . runInputT (setComplete completion settings)
349+
350+ go :: state -> InputT (StateT PSCiState (ReaderT PSCiConfig IO)) ()
351+ go state = do
352+ c <- getCommand (not psciMultiLineMode)
353+ case c of
354+ Left err -> outputStrLn err >> go state
355+ Right Nothing -> go state
356+ Right (Just QuitPSCi) -> do
357+ outputStrLn quitMessage
358+ liftIO $ shutdown state
359+ Right (Just c') -> do
360+ handleInterrupt (outputStrLn "Interrupted.")
361+ (withInterrupt (lift (handleCommand (liftIO . eval state) (liftIO (reload state)) c')))
362+ go state
363+ putStrLn prologueMessage
364+ setup >>= runner . go
psci/PSCi.hsdeleted−372
@@ -1,372 +0,0 @@
1−{-# LANGUAGE DoAndIfThenElse #-}
2−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE RecordWildCards #-}
4−{-# LANGUAGE TupleSections #-}
5−{-# LANGUAGE DataKinds #-}
6−
7−-- |
8−-- PureScript Compiler Interactive.
9−--
10−module PSCi (runPSCi) where
11−
12−import Prelude ()
13−import Prelude.Compat
14−
15−import Data.Foldable (traverse_)
16−import Data.List (intercalate, nub, sort, find)
17−import Data.Tuple (swap)
18−import qualified Data.Map as M
19−
20−import Control.Arrow (first)
21−import Control.Monad
22−import Control.Monad.Error.Class (MonadError(..))
23−import Control.Monad.Trans.Class
24−import Control.Monad.Trans.Except (ExceptT(), runExceptT)
25−import Control.Monad.Trans.State.Strict
26−import Control.Monad.IO.Class (liftIO)
27−import Control.Monad.Writer.Strict (Writer(), runWriter)
28−
29−import System.Console.Haskeline
30−import System.Directory (doesFileExist, getHomeDirectory, getCurrentDirectory)
31−import System.Exit
32−import System.FilePath ((</>))
33−import System.FilePath.Glob (glob)
34−import System.Process (readProcessWithExitCode)
35−import System.IO.Error (tryIOError)
36−import System.IO.UTF8 (readUTF8File)
37−
38−import qualified Language.PureScript as P
39−import qualified Language.PureScript.Names as N
40−
41−import PSCi.Completion (completion)
42−import PSCi.Parser (parseCommand)
43−import PSCi.Option
44−import PSCi.Types
45−import PSCi.Message
46−import PSCi.IO
47−import PSCi.Printer
48−import PSCi.Module
49−
50−-- |
51−-- PSCI monad
52−--
53−newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Functor, Applicative, Monad)
54−
55−psciIO :: IO a -> PSCI a
56−psciIO io = PSCI . lift $ lift io
57−
58−-- |
59−-- The runner
60−--
61−runPSCi :: IO ()
62−runPSCi = getOpt >>= loop
63−
64−-- |
65−-- The PSCI main loop.
66−--
67−loop :: PSCiOptions -> IO ()
68−loop PSCiOptions{..} = do
69− config <- loadUserConfig
70− inputFiles <- concat <$> traverse glob psciInputFile
71− foreignFiles <- concat <$> traverse glob psciForeignInputFiles
72− modulesOrFirstError <- loadAllModules inputFiles
73− case modulesOrFirstError of
74− Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
75− Right modules -> do
76− historyFilename <- getHistoryFilename
77− let settings = defaultSettings { historyFile = Just historyFilename }
78− foreignsOrError <- runMake $ do
79− foreignFilesContent <- forM foreignFiles (\inFile -> (inFile,) <$> makeIO (const (P.ErrorMessage [] $ P.CannotReadFile inFile)) (readUTF8File inFile))
80− P.parseForeignModulesFromFiles foreignFilesContent
81− case foreignsOrError of
82− Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
83− Right foreigns ->
84− flip evalStateT (mkPSCiState [] modules foreigns [] psciInputNodeFlags) . runInputT (setComplete completion settings) $ do
85− outputStrLn prologueMessage
86− traverse_ (traverse_ (runPSCI . handleCommand)) config
87− modules' <- lift $ gets psciLoadedModules
88− unless (consoleIsDefined (map snd modules')) . outputStrLn $ unlines
89− [ "PSCi requires the purescript-console module to be installed."
90− , "For help getting started, visit http://wiki.purescript.org/PSCi"
91− ]
92− go
93− where
94− go :: InputT (StateT PSCiState IO) ()
95− go = do
96− c <- getCommand (not psciMultiLineMode)
97− case c of
98− Left err -> outputStrLn err >> go
99− Right Nothing -> go
100− Right (Just QuitPSCi) -> outputStrLn quitMessage
101− Right (Just c') -> do
102− handleInterrupt (outputStrLn "Interrupted.")
103− (withInterrupt (runPSCI (loadAllImportedModules >> handleCommand c')))
104− go
105−
106−-- Compile the module
107−
108−-- |
109−-- Load all modules, updating the application state
110−--
111−loadAllImportedModules :: PSCI ()
112−loadAllImportedModules = do
113− files <- PSCI . lift $ fmap psciImportedFilenames get
114− modulesOrFirstError <- psciIO $ loadAllModules files
115− case modulesOrFirstError of
116− Left errs -> PSCI $ printErrors errs
117− Right modules -> PSCI . lift . modify $ updateModules modules
118−
119−-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
120−-- options and ignores the warning messages.
121−runMake :: P.Make a -> IO (Either P.MultipleErrors a)
122−runMake mk = fst <$> P.runMake P.defaultOptions mk
123−
124−makeIO :: (IOError -> P.ErrorMessage) -> IO a -> P.Make a
125−makeIO f io = do
126− e <- liftIO $ tryIOError io
127− either (throwError . P.singleError . f) return e
128−
129−make :: PSCiState -> [P.Module] -> P.Make P.Environment
130−make st@PSCiState{..} ms = P.make actions' (map snd loadedModules ++ ms)
131− where
132− filePathMap = M.fromList $ (first P.getModuleName . swap) `map` allModules
133− actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
134− actions' = actions { P.progress = const (return ()) }
135− loadedModules = psciLoadedModules st
136− allModules = map (first Right) loadedModules ++ map (Left P.RebuildAlways,) ms
137−
138−
139−-- Commands
140−
141−-- |
142−-- Parses the input and returns either a Metacommand, or an error as a string.
143−--
144−getCommand :: Bool -> InputT (StateT PSCiState IO) (Either String (Maybe Command))
145−getCommand singleLineMode = handleInterrupt (return (Right Nothing)) $ do
146− firstLine <- withInterrupt $ getInputLine "> "
147− case firstLine of
148− Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty
149− Just "" -> return (Right Nothing)
150− Just s | singleLineMode || head s == ':' -> return .fmap Just $ parseCommand s
151− Just s -> fmap Just . parseCommand <$> go [s]
152− where
153− go :: [String] -> InputT (StateT PSCiState IO) String
154− go ls = maybe (return . unlines $ reverse ls) (go . (:ls)) =<< getInputLine " "
155−
156−-- |
157−-- Performs an action for each meta-command given, and also for expressions.
158−--
159−handleCommand :: Command -> PSCI ()
160−handleCommand (Expression val) = handleExpression val
161−handleCommand ShowHelp = PSCI $ outputStrLn helpMessage
162−handleCommand (Import im) = handleImport im
163−handleCommand (Decls l) = handleDecls l
164−handleCommand (LoadFile filePath) = PSCI $ whenFileExists filePath $ \absPath -> do
165− m <- lift . lift $ loadModule absPath
166− case m of
167− Left err -> outputStrLn err
168− Right mods -> lift $ modify (updateModules (map (absPath,) mods))
169−handleCommand (LoadForeign filePath) = PSCI $ whenFileExists filePath $ \absPath -> do
170− foreignsOrError <- lift . lift . runMake $ do
171− foreignFile <- makeIO (const (P.ErrorMessage [] $ P.CannotReadFile absPath)) (readUTF8File absPath)
172− P.parseForeignModulesFromFiles [(absPath, foreignFile)]
173− case foreignsOrError of
174− Left err -> outputStrLn $ P.prettyPrintMultipleErrors False err
175− Right foreigns -> lift $ modify (updateForeignFiles foreigns)
176−handleCommand ResetState = do
177− PSCI . lift . modify $ \st ->
178− st { psciImportedModules = []
179− , psciLetBindings = []
180− }
181− loadAllImportedModules
182−handleCommand (TypeOf val) = handleTypeOf val
183−handleCommand (KindOf typ) = handleKindOf typ
184−handleCommand (BrowseModule moduleName) = handleBrowse moduleName
185−handleCommand (ShowInfo QueryLoaded) = handleShowLoadedModules
186−handleCommand (ShowInfo QueryImport) = handleShowImportedModules
187−handleCommand QuitPSCi = P.internalError "`handleCommand QuitPSCi` was called. This is a bug."
188−
189−
190−-- |
191−-- Takes a value expression and evaluates it with the current state.
192−--
193−handleExpression :: P.Expr -> PSCI ()
194−handleExpression val = do
195− st <- PSCI $ lift get
196− let m = createTemporaryModule True st val
197− let nodeArgs = psciNodeFlags st ++ [indexFile]
198− e <- psciIO . runMake $ make st [supportModule, m]
199− case e of
200− Left errs -> PSCI $ printErrors errs
201− Right _ -> do
202− psciIO $ writeFile indexFile "require('$PSCI')['$main']();"
203− process <- psciIO findNodeProcess
204− result <- psciIO $ traverse (\node -> readProcessWithExitCode node nodeArgs "") process
205− case result of
206− Just (ExitSuccess, out, _) -> PSCI $ outputStrLn out
207− Just (ExitFailure _, _, err) -> PSCI $ outputStrLn err
208− Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
209−
210−-- |
211−-- Takes a list of declarations and updates the environment, then run a make. If the declaration fails,
212−-- restore the original environment.
213−--
214−handleDecls :: [P.Declaration] -> PSCI ()
215−handleDecls ds = do
216− st <- PSCI $ lift get
217− let st' = updateLets ds st
218− let m = createTemporaryModule False st' (P.Literal (P.ObjectLiteral []))
219− e <- psciIO . runMake $ make st' [m]
220− case e of
221− Left err -> PSCI $ printErrors err
222− Right _ -> PSCI $ lift (put st')
223−
224−-- |
225−-- Show actual loaded modules in psci.
226−--
227−handleShowLoadedModules :: PSCI ()
228−handleShowLoadedModules = do
229− loadedModules <- PSCI $ lift $ gets psciLoadedModules
230− psciIO $ readModules loadedModules >>= putStrLn
231− return ()
232− where readModules = return . unlines . sort . nub . map toModuleName
233− toModuleName = N.runModuleName . (\ (P.Module _ _ mdName _ _) -> mdName) . snd
234−
235−-- |
236−-- Show the imported modules in psci.
237−--
238−handleShowImportedModules :: PSCI ()
239−handleShowImportedModules = do
240− PSCiState { psciImportedModules = importedModules } <- PSCI $ lift get
241− psciIO $ showModules importedModules >>= putStrLn
242− return ()
243− where
244− showModules = return . unlines . sort . map showModule
245− showModule (mn, declType, asQ) =
246− "import " ++ N.runModuleName mn ++ showDeclType declType ++
247− foldMap (\mn' -> " as " ++ N.runModuleName mn') asQ
248−
249− showDeclType P.Implicit = ""
250− showDeclType (P.Explicit refs) = refsList refs
251− showDeclType (P.Hiding refs) = " hiding " ++ refsList refs
252− refsList refs = " (" ++ commaList (map showRef refs) ++ ")"
253−
254− showRef :: P.DeclarationRef -> String
255− showRef (P.TypeRef pn dctors) = N.runProperName pn ++ "(" ++ maybe ".." (commaList . map N.runProperName) dctors ++ ")"
256− showRef (P.TypeOpRef ident) = "type (" ++ N.runIdent ident ++ ")"
257− showRef (P.ValueRef ident) = N.runIdent ident
258− showRef (P.TypeClassRef pn) = "class " ++ N.runProperName pn
259− showRef (P.ProperRef pn) = pn
260− showRef (P.TypeInstanceRef ident) = N.runIdent ident
261− showRef (P.ModuleRef name) = "module " ++ N.runModuleName name
262− showRef (P.PositionedDeclarationRef _ _ ref) = showRef ref
263−
264− commaList :: [String] -> String
265− commaList = intercalate ", "
266−
267−-- |
268−-- Imports a module, preserving the initial state on failure.
269−--
270−handleImport :: ImportedModule -> PSCI ()
271−handleImport im = do
272− st <- updateImportedModules im <$> PSCI (lift get)
273− let m = createTemporaryModuleForImports st
274− e <- psciIO . runMake $ make st [m]
275− case e of
276− Left errs -> PSCI $ printErrors errs
277− Right _ -> do
278− PSCI $ lift $ put st
279− return ()
280−
281−-- |
282−-- Takes a value and prints its type
283−--
284−handleTypeOf :: P.Expr -> PSCI ()
285−handleTypeOf val = do
286− st <- PSCI $ lift get
287− let m = createTemporaryModule False st val
288− e <- psciIO . runMake $ make st [m]
289− case e of
290− Left errs -> PSCI $ printErrors errs
291− Right env' ->
292− case M.lookup (P.ModuleName [P.ProperName "$PSCI"], P.Ident "it") (P.names env') of
293− Just (ty, _, _) -> PSCI . outputStrLn . P.prettyPrintType $ ty
294− Nothing -> PSCI $ outputStrLn "Could not find type"
295−
296−-- |
297−-- Browse a module and displays its signature (if module exists).
298−--
299−handleBrowse :: P.ModuleName -> PSCI ()
300−handleBrowse moduleName = do
301− st <- PSCI $ lift get
302− env <- psciIO . runMake $ make st []
303− case env of
304− Left errs -> PSCI $ printErrors errs
305− Right env' ->
306− if isModInEnv moduleName st
307− then PSCI $ printModuleSignatures moduleName env'
308− else case lookupUnQualifiedModName moduleName st of
309− Just unQualifiedName ->
310− if isModInEnv unQualifiedName st
311− then PSCI $ printModuleSignatures unQualifiedName env'
312− else failNotInEnv moduleName
313− Nothing ->
314− failNotInEnv moduleName
315− where
316− isModInEnv modName =
317− any ((== modName) . P.getModuleName . snd) . psciLoadedModules
318− failNotInEnv modName =
319− PSCI $ outputStrLn $ "Module '" ++ N.runModuleName modName ++ "' is not valid."
320− lookupUnQualifiedModName quaModName st =
321− (\(modName,_,_) -> modName) <$> find ( \(_, _, mayQuaName) -> mayQuaName == Just quaModName) (psciImportedModules st)
322−
323−-- |
324−-- Takes a value and prints its kind
325−--
326−handleKindOf :: P.Type -> PSCI ()
327−handleKindOf typ = do
328− st <- PSCI $ lift get
329− let m = createTemporaryModuleForKind st typ
330− mName = P.ModuleName [P.ProperName "$PSCI"]
331− e <- psciIO . runMake $ make st [m]
332− case e of
333− Left errs -> PSCI $ printErrors errs
334− Right env' ->
335− case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
336− Just (_, typ') -> do
337− let chk = (P.emptyCheckState env') { P.checkCurrentModule = Just mName }
338− k = check (P.kindOf typ') chk
339−
340− check :: StateT P.CheckState (ExceptT P.MultipleErrors (Writer P.MultipleErrors)) a -> P.CheckState -> Either P.MultipleErrors (a, P.CheckState)
341− check sew = fst . runWriter . runExceptT . runStateT sew
342− case k of
343− Left errStack -> PSCI . outputStrLn . P.prettyPrintMultipleErrors False $ errStack
344− Right (kind, _) -> PSCI . outputStrLn . P.prettyPrintKind $ kind
345− Nothing -> PSCI $ outputStrLn "Could not find kind"
346−
347−-- Misc
348−
349−-- |
350−-- Attempts to read initial commands from '.psci' in the present working
351−-- directory then the user's home
352−--
353−loadUserConfig :: IO (Maybe [Command])
354−loadUserConfig = onFirstFileMatching readCommands pathGetters
355− where
356− pathGetters = [getCurrentDirectory, getHomeDirectory]
357− readCommands :: IO FilePath -> IO (Maybe [Command])
358− readCommands path = do
359− configFile <- (</> ".psci") <$> path
360− exists <- doesFileExist configFile
361− if exists
362− then do
363− ls <- lines <$> readUTF8File configFile
364− case traverse parseCommand ls of
365− Left err -> print err >> exitFailure
366− Right cs -> return $ Just cs
367− else
368− return Nothing
369−
370−-- | Checks if the Console module is defined
371−consoleIsDefined :: [P.Module] -> Bool
372−consoleIsDefined = any ((== P.ModuleName (map P.ProperName [ "Control", "Monad", "Eff", "Console" ])) . P.getModuleName)
psci/PSCi/Message.hsdeleted−53
@@ -1,53 +0,0 @@
1−module PSCi.Message where
2−
3−
4−import Data.List (intercalate)
5−import qualified PSCi.Directive as D
6−import PSCi.Types
7−
8−-- Messages
9−
10−-- |
11−-- The help message.
12−--
13−helpMessage :: String
14−helpMessage = "The following commands are available:\n\n " ++
15− intercalate "\n " (map line D.help) ++
16− "\n\n" ++ extraHelp
17− where
18− line :: (Directive, String, String) -> String
19− line (dir, arg, desc) =
20− let cmd = ':' : D.stringFor dir
21− in unwords [ cmd
22− , replicate (11 - length cmd) ' '
23− , arg
24− , replicate (11 - length arg) ' '
25− , desc
26− ]
27−
28− extraHelp =
29− "Further information is available on the PureScript wiki:\n" ++
30− " --> https://github.com/purescript/purescript/wiki/psci"
31−
32−
33−-- |
34−-- The welcome prologue.
35−--
36−prologueMessage :: String
37−prologueMessage = intercalate "\n"
38− [ " ____ ____ _ _ "
39− , "| _ \\ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_ "
40− , "| |_) | | | | '__/ _ \\___ \\ / __| '__| | '_ \\| __|"
41− , "| __/| |_| | | | __/___) | (__| | | | |_) | |_ "
42− , "|_| \\__,_|_| \\___|____/ \\___|_| |_| .__/ \\__|"
43− , " |_| "
44− , ""
45− , ":? shows help"
46− ]
47−
48−-- |
49−-- The quit message.
50−--
51−quitMessage :: String
52−quitMessage = "See ya!"
53−
psci/PSCi/Module.hsdeleted−107
@@ -1,107 +0,0 @@
1−module PSCi.Module where
2−
3−import Prelude ()
4−import Prelude.Compat
5−
6−import qualified Language.PureScript as P
7−import PSCi.Types
8−import System.FilePath (pathSeparator)
9−import System.IO.UTF8 (readUTF8File)
10−import Control.Monad
11−
12−-- | The name of the PSCI support module
13−supportModuleName :: P.ModuleName
14−supportModuleName = P.ModuleName [P.ProperName "$PSCI", P.ProperName "Support"]
15−
16−-- | Support module, contains code to evaluate terms
17−supportModule :: P.Module
18−supportModule =
19− case P.parseModulesFromFiles id [("", code)] of
20− Right [(_, P.Module ss cs _ ds exps)] -> P.Module ss cs supportModuleName ds exps
21− _ -> P.internalError "Support module could not be parsed"
22− where
23− code :: String
24− code = unlines
25− [ "module S where"
26− , ""
27− , "import Prelude"
28− , "import Control.Monad.Eff"
29− , "import Control.Monad.Eff.Console"
30− , "import Control.Monad.Eff.Unsafe"
31− , ""
32− , "class Eval a where"
33− , " eval :: a -> Eff (console :: CONSOLE) Unit"
34− , ""
35− , "instance evalShow :: (Show a) => Eval a where"
36− , " eval = print"
37− , ""
38− , "instance evalEff :: (Eval a) => Eval (Eff eff a) where"
39− , " eval x = unsafeInterleaveEff x >>= eval"
40− ]
41−
42−-- Module Management
43−
44−-- |
45−-- Loads a file for use with imports.
46−--
47−loadModule :: FilePath -> IO (Either String [P.Module])
48−loadModule filename = do
49− content <- readUTF8File filename
50− return $ either (Left . P.prettyPrintMultipleErrors False) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
51−
52−-- |
53−-- Load all modules.
54−--
55−loadAllModules :: [FilePath] -> IO (Either P.MultipleErrors [(FilePath, P.Module)])
56−loadAllModules files = do
57− filesAndContent <- forM files $ \filename -> do
58− content <- readUTF8File filename
59− return (filename, content)
60− return $ P.parseModulesFromFiles id filesAndContent
61−
62−
63−-- |
64−-- Makes a volatile module to execute the current expression.
65−--
66−createTemporaryModule :: Bool -> PSCiState -> P.Expr -> P.Module
67−createTemporaryModule exec PSCiState{psciImportedModules = imports, psciLetBindings = lets} val =
68− let
69− moduleName = P.ModuleName [P.ProperName "$PSCI"]
70− trace = P.Var (P.Qualified (Just supportModuleName) (P.Ident "eval"))
71− mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
72− itDecl = P.ValueDeclaration (P.Ident "it") P.Public [] $ Right val
73− mainDecl = P.ValueDeclaration (P.Ident "$main") P.Public [] $ Right mainValue
74− decls = if exec then [itDecl, mainDecl] else [itDecl]
75− in
76− P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing
77−
78−
79−-- |
80−-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
81−--
82−createTemporaryModuleForKind :: PSCiState -> P.Type -> P.Module
83−createTemporaryModuleForKind PSCiState{psciImportedModules = imports, psciLetBindings = lets} typ =
84− let
85− moduleName = P.ModuleName [P.ProperName "$PSCI"]
86− itDecl = P.TypeSynonymDeclaration (P.ProperName "IT") [] typ
87− in
88− P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing
89−
90−-- |
91−-- Makes a volatile module to execute the current imports.
92−--
93−createTemporaryModuleForImports :: PSCiState -> P.Module
94−createTemporaryModuleForImports PSCiState{psciImportedModules = imports} =
95− let
96− moduleName = P.ModuleName [P.ProperName "$PSCI"]
97− in
98− P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName (importDecl `map` imports) Nothing
99−
100−importDecl :: ImportedModule -> P.Declaration
101−importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ False
102−
103−indexFile :: FilePath
104−indexFile = ".psci_modules" ++ pathSeparator : "index.js"
105−
106−modulesDir :: FilePath
107−modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
psci/PSCi/Option.hsdeleted−57
@@ -1,57 +0,0 @@
1−module PSCi.Option (
2− getOpt
3−) where
4−
5−import Prelude ()
6−import Prelude.Compat
7−
8−import Options.Applicative as Opts
9−import Data.Version (showVersion)
10−
11−import PSCi.Types
12−import qualified Paths_purescript as Paths
13−
14−-- Parse Command line option
15−
16−multiLineMode :: Parser Bool
17−multiLineMode = switch $
18− long "multi-line-mode"
19− <> short 'm'
20− <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
21−
22−inputFile :: Parser FilePath
23−inputFile = strArgument $
24− metavar "FILE"
25− <> Opts.help "Optional .purs files to load on start"
26−
27−inputForeignFile :: Parser FilePath
28−inputForeignFile = strOption $
29− short 'f'
30− <> long "ffi"
31− <> help "The input .js file(s) providing foreign import implementations"
32−
33−nodeFlagsFlag :: Parser [String]
34−nodeFlagsFlag = option parser $
35− long "node-opts"
36− <> metavar "NODE_OPTS"
37− <> value []
38− <> Opts.help "Flags to pass to node, separated by spaces"
39− where
40− parser = words <$> str
41−
42−psciOptions :: Parser PSCiOptions
43−psciOptions = PSCiOptions <$> multiLineMode
44− <*> many inputFile
45− <*> many inputForeignFile
46− <*> nodeFlagsFlag
47−
48−version :: Parser (a -> a)
49−version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> Opts.help "Show the version number" <> hidden
50−
51−getOpt :: IO PSCiOptions
52−getOpt = execParser opts
53− where
54− opts = info (version <*> helper <*> psciOptions) infoModList
55− infoModList = fullDesc <> headerInfo <> footerInfo
56− headerInfo = header "psci - Interactive mode for PureScript"
57− footerInfo = footer $ "psci " ++ showVersion Paths.version
psci/PSCi/Types.hsdeleted−218
@@ -1,218 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Types
4−-- Copyright : (c) Phil Freeman 2014
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−-- Type declarations and associated basic functions for PSCI.
13−--
14−-----------------------------------------------------------------------------
15−
16−module PSCi.Types where
17−
18−import Prelude ()
19−import Prelude.Compat
20−
21−import Control.Arrow (second)
22−import Data.Map (Map)
23−import qualified Data.Map as Map
24−import qualified Language.PureScript as P
25−
26−data PSCiOptions = PSCiOptions
27− { psciMultiLineMode :: Bool
28− , psciInputFile :: [FilePath]
29− , psciForeignInputFiles :: [FilePath]
30− , psciInputNodeFlags :: [String]
31− }
32−
33−-- |
34−-- The PSCI state.
35−-- Holds a list of imported modules, loaded files, and partial let bindings.
36−-- The let bindings are partial,
37−-- because it makes more sense to apply the binding to the final evaluated expression.
38−--
39−data PSCiState = PSCiState
40− { psciImportedModules :: [ImportedModule]
41− , _psciLoadedModules :: Map FilePath [P.Module]
42− , psciForeignFiles :: Map P.ModuleName FilePath
43− , psciLetBindings :: [P.Declaration]
44− , psciNodeFlags :: [String]
45− }
46−
47−initialPSCiState :: PSCiState
48−initialPSCiState =
49− PSCiState [] Map.empty Map.empty [] []
50−
51−mkPSCiState :: [ImportedModule]
52− -> [(FilePath, P.Module)]
53− -> Map P.ModuleName FilePath
54− -> [P.Declaration]
55− -> [String]
56− -> PSCiState
57−mkPSCiState imported loaded foreigns lets nodeFlags =
58− (initialPSCiState
59− |> each imported updateImportedModules
60− |> updateModules loaded)
61− { psciForeignFiles = foreigns
62− , psciLetBindings = lets
63− , psciNodeFlags = nodeFlags
64− }
65− where
66− x |> f = f x
67− each xs f st = foldl (flip f) st xs
68−
69−-- Public psci state accessors
70−
71−-- | Get the imported filenames as a list.
72−psciImportedFilenames :: PSCiState -> [FilePath]
73−psciImportedFilenames = Map.keys . _psciLoadedModules
74−
75−-- | Get the loaded modules as a list.
76−psciLoadedModules :: PSCiState -> [(FilePath, P.Module)]
77−psciLoadedModules = collect . Map.toList . _psciLoadedModules
78− where
79− collect :: [(k, [v])] -> [(k, v)]
80− collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
81−
82−-- | All of the data that is contained by an ImportDeclaration in the AST.
83−-- That is:
84−--
85−-- * A module name, the name of the module which is being imported
86−-- * An ImportDeclarationType which specifies whether there is an explicit
87−-- import list, a hiding list, or neither.
88−-- * If the module is imported qualified, its qualified name in the importing
89−-- module. Otherwise, Nothing.
90−--
91−type ImportedModule = (P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)
92−
93−psciImportedModuleNames :: PSCiState -> [P.ModuleName]
94−psciImportedModuleNames (PSCiState{psciImportedModules = is}) =
95− map (\(mn, _, _) -> mn) is
96−
97−allImportsOf :: P.Module -> PSCiState -> [ImportedModule]
98−allImportsOf m (PSCiState{psciImportedModules = is}) =
99− filter isImportOfThis is
100− where
101− name = P.getModuleName m
102− isImportOfThis (name', _, _) = name == name'
103−
104−-- State helpers
105−
106−-- |
107−-- Updates the state to have more imported modules.
108−--
109−updateImportedModules :: ImportedModule -> PSCiState -> PSCiState
110−updateImportedModules im st = st { psciImportedModules = im : psciImportedModules st }
111−
112−-- |
113−-- Updates the state to have more loaded modules (available for import, but
114−-- not necessarily imported).
115−--
116−updateModules :: [(FilePath, P.Module)] -> PSCiState -> PSCiState
117−updateModules modules st =
118− st { _psciLoadedModules = Map.union (go modules) (_psciLoadedModules st) }
119− where
120− go = Map.fromListWith (++) . map (second (:[]))
121−
122−-- |
123−-- Updates the state to have more let bindings.
124−--
125−updateLets :: [P.Declaration] -> PSCiState -> PSCiState
126−updateLets ds st = st { psciLetBindings = psciLetBindings st ++ ds }
127−
128−-- |
129−-- Updates the state to have more let bindings.
130−--
131−updateForeignFiles :: Map P.ModuleName FilePath -> PSCiState -> PSCiState
132−updateForeignFiles fs st = st { psciForeignFiles = psciForeignFiles st `Map.union` fs }
133−
134−-- |
135−-- Valid Meta-commands for PSCI
136−--
137−data Command
138− -- |
139− -- A purescript expression
140− --
141− = Expression P.Expr
142− -- |
143− -- Show the help (ie, list of directives)
144− --
145− | ShowHelp
146− -- |
147− -- Import a module from a loaded file
148− --
149− | Import ImportedModule
150− -- |
151− -- Browse a module
152− --
153− | BrowseModule P.ModuleName
154− -- |
155− -- Load a file for use with importing
156− --
157− | LoadFile FilePath
158− -- |
159− -- Load a foreign module
160− --
161− | LoadForeign FilePath
162− -- |
163− -- Exit PSCI
164− --
165− | QuitPSCi
166− -- |
167− -- Reset the state of the REPL
168− --
169− | ResetState
170− -- |
171− -- Add some declarations to the current evaluation context.
172− --
173− | Decls [P.Declaration]
174− -- |
175− -- Find the type of an expression
176− --
177− | TypeOf P.Expr
178− -- |
179− -- Find the kind of an expression
180− --
181− | KindOf P.Type
182− -- |
183− -- Shows information about the current state of the REPL
184− --
185− | ShowInfo ReplQuery
186−
187−data ReplQuery
188− = QueryLoaded
189− | QueryImport
190− deriving (Eq, Show)
191−
192−-- | A list of all ReplQuery values.
193−replQueries :: [ReplQuery]
194−replQueries = [QueryLoaded, QueryImport]
195−
196−replQueryStrings :: [String]
197−replQueryStrings = map showReplQuery replQueries
198−
199−showReplQuery :: ReplQuery -> String
200−showReplQuery QueryLoaded = "loaded"
201−showReplQuery QueryImport = "import"
202−
203−parseReplQuery :: String -> Maybe ReplQuery
204−parseReplQuery "loaded" = Just QueryLoaded
205−parseReplQuery "import" = Just QueryImport
206−parseReplQuery _ = Nothing
207−
208−data Directive
209− = Help
210− | Quit
211− | Reset
212− | Browse
213− | Load
214− | Foreign
215− | Type
216− | Kind
217− | Show
218− deriving (Eq, Show)
psci/main/Main.hsdeleted−6
@@ -1,6 +0,0 @@
1−module Main where
2−
3−import PSCi
4−
5−main :: IO ()
6−main = runPSCi
psci/static/index.htmlnew file+10
@@ -0,0 +1,10 @@
1+<!DOCTYPE html>
2+<html>
3+<head>
4+ <title>PureScript Interactive</title>
5+ <script src='js/bundle.js'></script>
6+ <script src='js/index.js'></script>
7+</head>
8+<body>
9+</body>
10+</html>
psci/static/index.jsnew file+63
@@ -0,0 +1,63 @@
1+var get = function get(uri, callback, onError) {
2+ var request = new XMLHttpRequest();
3+ request.addEventListener('load', function() {
4+ callback(request.responseText);
5+ });
6+ request.addEventListener('error', onError);
7+ request.open('GET', uri);
8+ request.send();
9+};
10+var evaluate = function evaluate(js) {
11+ var buffer = [];
12+ // Save the old console.log function
13+ var oldLog = console.log;
14+ console.log = function(s) {
15+ // Push log output into a temporary buffer
16+ // which will be returned to PSCi.
17+ buffer.push(s);
18+ };
19+ // Replace any require(...) statements with lookups on the PSCI object.
20+ var replaced = js.replace(/require\("[^"]*"\)/g, function(s) {
21+ return "PSCI['" + s.substring(12, s.length - 2) + "']";
22+ });
23+ // Wrap the module and evaluate it.
24+ var wrapped =
25+ [ 'var module = {};'
26+ , '(function(module) {'
27+ , replaced
28+ , '})(module);'
29+ , 'return module.exports["$main"] && module.exports["$main"]();'
30+ ].join('\n');
31+ new Function(wrapped)();
32+ // Restore console.log
33+ console.log = oldLog;
34+ return buffer.join('\n');
35+};
36+window.onload = function() {
37+ var socket = new WebSocket('ws://0.0.0.0:' + location.port);
38+ var evalNext = function reload() {
39+ get('js/latest.js', function(response) {
40+ try {
41+ var result = evaluate(response);
42+ socket.send(result);
43+ } catch (ex) {
44+ socket.send(ex.stack);
45+ }
46+ }, function(err) {
47+ socket.send('Error sending JavaScript');
48+ });
49+ };
50+ socket.onopen = function() {
51+ console.log('Connected');
52+ socket.onmessage = function(event) {
53+ switch (event.data) {
54+ case 'eval':
55+ evalNext();
56+ break;
57+ case 'reload':
58+ location.reload();
59+ break;
60+ }
61+ };
62+ };
63+};
purescript.cabal+280−126
@@ -1,5 +1,5 @@
11name: purescript
2−version: 0.8.5.0
2+version: 0.9.3
33cabal-version: >=1.8
44build-type: Simple
55license: MIT
@@ -20,27 +20,75 @@ author: Phil Freeman <paf31@cantab.net>,
2020tested-with: GHC==7.10.3
2121
2222extra-source-files: examples/passing/*.purs
23+ , examples/passing/*.js
24+ , examples/passing/2018/*.purs
25+ , examples/passing/2138/*.purs
26+ , examples/passing/ClassRefSyntax/*.purs
27+ , examples/passing/DctorOperatorAlias/*.purs
28+ , examples/passing/ExplicitImportReExport/*.purs
29+ , examples/passing/ExportExplicit/*.purs
30+ , examples/passing/ExportExplicit2/*.purs
31+ , examples/passing/Import/*.purs
32+ , examples/passing/ImportExplicit/*.purs
33+ , examples/passing/ImportQualified/*.purs
34+ , examples/passing/Module/*.purs
35+ , examples/passing/ModuleDeps/*.purs
36+ , examples/passing/ModuleExport/*.purs
37+ , examples/passing/ModuleExportDupes/*.purs
38+ , examples/passing/ModuleExportExcluded/*.purs
39+ , examples/passing/ModuleExportQualified/*.purs
40+ , examples/passing/ModuleExportSelf/*.purs
41+ , examples/passing/NonConflictingExports/*.purs
42+ , examples/passing/OperatorAliasElsewhere/*.purs
43+ , examples/passing/Operators/*.purs
44+ , examples/passing/PendingConflictingImports/*.purs
45+ , examples/passing/PendingConflictingImports2/*.purs
46+ , examples/passing/QualifiedNames/*.purs
47+ , examples/passing/RedefinedFixity/*.purs
48+ , examples/passing/ReExportQualified/*.purs
49+ , examples/passing/ResolvableScopeConflict/*.purs
50+ , examples/passing/ResolvableScopeConflict2/*.purs
51+ , examples/passing/ResolvableScopeConflict3/*.purs
52+ , examples/passing/ShadowedModuleName/*.purs
53+ , examples/passing/TransitiveImport/*.purs
54+ , examples/passing/TypeOperators/*.purs
55+ , examples/passing/TypeWithoutParens/*.purs
2356 , examples/failing/*.purs
57+ , examples/failing/1733/*.purs
58+ , examples/failing/ConflictingExports/*.purs
59+ , examples/failing/ConflictingImports/*.purs
60+ , examples/failing/ConflictingImports2/*.purs
61+ , examples/failing/ConflictingQualifiedImports/*.purs
62+ , examples/failing/ConflictingQualifiedImports2/*.purs
63+ , examples/failing/ExportConflictClass/*.purs
64+ , examples/failing/ExportConflictCtor/*.purs
65+ , examples/failing/ExportConflictType/*.purs
66+ , examples/failing/ExportConflictTypeOp/*.purs
67+ , examples/failing/ExportConflictValue/*.purs
68+ , examples/failing/ExportConflictValueOp/*.purs
69+ , examples/failing/ExportExplicit1/*.purs
70+ , examples/failing/ExportExplicit3/*.purs
71+ , examples/failing/ImportExplicit/*.purs
72+ , examples/failing/ImportExplicit2/*.purs
73+ , examples/failing/ImportHidingModule/*.purs
74+ , examples/failing/ImportModule/*.purs
75+ , examples/failing/InstanceExport/*.purs
76+ , examples/failing/OrphanInstance/*.purs
77+ , examples/warning/*.purs
78+ , examples/warning/*.js
2479 , examples/docs/bower_components/purescript-prelude/src/*.purs
2580 , examples/docs/bower.json
2681 , examples/docs/src/*.purs
27− , tests/support/setup.js
82+ , psci/static/index.html
83+ , psci/static/index.js
2884 , tests/support/package.json
29− , tests/support/prelude/bower.json
30− , tests/support/prelude/src/*.purs
31− , tests/support/prelude/src/*.js
32− , tests/support/prelude/LICENSE
3385 , tests/support/bower.json
3486 , tests/support/setup-win.cmd
35− , tests/support/flattened/*.purs
36− , tests/support/flattened/*.js
3787 , tests/support/psci/*.purs
3888 , tests/support/pscide/src/*.purs
3989 , tests/support/pscide/src/*.js
4090 , tests/support/pscide/src/*.fail
4191 , stack.yaml
42− , stack-lts-5.yaml
43− , stack-nightly.yaml
4492 , README.md
4593 , INSTALL.md
4694 , CONTRIBUTORS.md
@@ -53,47 +101,52 @@ source-repository head
53101
54102library
55103 build-depends: base >=4.8 && <5,
104+ aeson >= 0.8 && < 1.1,
105+ aeson-better-errors >= 0.8,
106+ ansi-terminal >= 0.6.2 && < 0.7,
56107 base-compat >=0.6.0,
57− lifted-base >= 0.2.3 && < 0.2.4,
58− monad-control >= 1.0.0.0 && < 1.1,
59− transformers-base >= 0.4.0 && < 0.5,
108+ bower-json >= 0.8,
109+ boxes >= 0.1.4 && < 0.2.0,
110+ bytestring -any,
60111 containers -any,
61− unordered-containers -any,
62− dlist -any,
112+ clock -any,
63113 directory >= 1.2,
114+ dlist -any,
115+ edit-distance -any,
64116 filepath -any,
117+ fsnotify >= 0.2.1,
118+ Glob >= 0.7 && < 0.8,
119+ haskeline >= 0.7.0.0,
120+ http-client >= 0.4.30 && <0.5,
121+ http-types -any,
122+ language-javascript == 0.6.*,
123+ lifted-base >= 0.2.3 && < 0.2.4,
124+ monad-control >= 1.0.0.0 && < 1.1,
125+ monad-logger >= 0.3 && < 0.4,
65126 mtl >= 2.1.0 && < 2.3.0,
66− parsec -any,
67− transformers >= 0.3.0 && < 0.6,
68− transformers-compat >= 0.3.0,
69− utf8-string >= 1 && < 2,
127+ parallel >= 3.2 && < 3.3,
128+ parsec >=3.1.10,
70129 pattern-arrows >= 0.0.2 && < 0.1,
71− time -any,
72− boxes >= 0.1.4 && < 0.2.0,
73− aeson >= 0.8 && < 0.12,
74− vector -any,
75− bower-json >= 0.8,
76− aeson-better-errors >= 0.8,
77− bytestring -any,
78− text -any,
79− split -any,
80− language-javascript == 0.6.*,
81− syb -any,
82− Glob >= 0.7 && < 0.8,
130+ pipes >= 4.0.0 && < 4.3.0,
131+ pipes-http -any,
83132 process >= 1.2.0 && < 1.5,
133+ protolude >= 0.1.6,
134+ regex-tdfa -any,
84135 safe >= 0.3.9 && < 0.4,
85136 semigroups >= 0.16.2 && < 0.19,
86− parallel >= 3.2 && < 3.3,
87137 sourcemap >= 0.1.6,
138+ spdx == 0.2.*,
139+ split -any,
88140 stm >= 0.2.4.0,
89− regex-tdfa -any,
90− edit-distance -any,
91− fsnotify >= 0.2.1,
92− monad-logger >= 0.3 && < 0.4,
93− pipes >= 4.0.0 && < 4.2.0 ,
94− pipes-http -any,
95− http-types -any,
96− spdx == 0.2.*
141+ syb -any,
142+ text -any,
143+ time -any,
144+ transformers >= 0.3.0 && < 0.6,
145+ transformers-base >= 0.4.0 && < 0.5,
146+ transformers-compat >= 0.3.0,
147+ unordered-containers -any,
148+ utf8-string >= 1 && < 2,
149+ vector -any
97150
98151 exposed-modules: Language.PureScript
99152 Language.PureScript.AST
@@ -158,7 +211,6 @@ library
158211 Language.PureScript.Parser.Lexer
159212 Language.PureScript.Parser.Common
160213 Language.PureScript.Parser.Declarations
161− Language.PureScript.Parser.JS
162214 Language.PureScript.Parser.Kinds
163215 Language.PureScript.Parser.State
164216 Language.PureScript.Parser.Types
@@ -174,9 +226,10 @@ library
174226 Language.PureScript.Sugar.CaseDeclarations
175227 Language.PureScript.Sugar.DoNotation
176228 Language.PureScript.Sugar.Names
229+ Language.PureScript.Sugar.Names.Common
177230 Language.PureScript.Sugar.Names.Env
178− Language.PureScript.Sugar.Names.Imports
179231 Language.PureScript.Sugar.Names.Exports
232+ Language.PureScript.Sugar.Names.Imports
180233 Language.PureScript.Sugar.ObjectWildcards
181234 Language.PureScript.Sugar.Operators
182235 Language.PureScript.Sugar.Operators.Common
@@ -219,22 +272,33 @@ library
219272 Language.PureScript.Publish.BoxesHelpers
220273
221274 Language.PureScript.Ide
275+ Language.PureScript.Ide.CaseSplit
222276 Language.PureScript.Ide.Command
277+ Language.PureScript.Ide.Completion
278+ Language.PureScript.Ide.Conversions
223279 Language.PureScript.Ide.Externs
224280 Language.PureScript.Ide.Error
225− Language.PureScript.Ide.Pursuit
226− Language.PureScript.Ide.Completion
227− Language.PureScript.Ide.Matcher
281+ Language.PureScript.Ide.Imports
228282 Language.PureScript.Ide.Filter
229− Language.PureScript.Ide.Types
230− Language.PureScript.Ide.State
231− Language.PureScript.Ide.CaseSplit
232− Language.PureScript.Ide.SourceFile
233− Language.PureScript.Ide.Watcher
283+ Language.PureScript.Ide.Matcher
284+ Language.PureScript.Ide.Pursuit
285+ Language.PureScript.Ide.Rebuild
234286 Language.PureScript.Ide.Reexports
235− Language.PureScript.Ide.Imports
287+ Language.PureScript.Ide.SourceFile
288+ Language.PureScript.Ide.State
289+ Language.PureScript.Ide.Types
236290 Language.PureScript.Ide.Util
237− Language.PureScript.Ide.Rebuild
291+ Language.PureScript.Ide.Watcher
292+
293+ Language.PureScript.Interactive
294+ Language.PureScript.Interactive.Types
295+ Language.PureScript.Interactive.Parser
296+ Language.PureScript.Interactive.Directive
297+ Language.PureScript.Interactive.Completion
298+ Language.PureScript.Interactive.IO
299+ Language.PureScript.Interactive.Message
300+ Language.PureScript.Interactive.Module
301+ Language.PureScript.Interactive.Printer
238302
239303 Control.Monad.Logger
240304 Control.Monad.Supply
@@ -242,7 +306,22 @@ library
242306
243307 System.IO.UTF8
244308
245− extensions: DataKinds
309+ extensions: ConstraintKinds
310+ DataKinds
311+ DeriveFunctor
312+ EmptyDataDecls
313+ FlexibleContexts
314+ KindSignatures
315+ LambdaCase
316+ MultiParamTypeClasses
317+ NoImplicitPrelude
318+ PatternGuards
319+ PatternSynonyms
320+ RankNTypes
321+ RecordWildCards
322+ ScopedTypeVariables
323+ TupleSections
324+ ViewPatterns
246325 exposed: True
247326 buildable: True
248327 hs-source-dirs: src
@@ -250,11 +329,23 @@ library
250329 ghc-options: -Wall -O2
251330
252331executable psc
253− build-depends: base >=4 && <5, base-compat >=0.6.0,
254− containers -any, directory -any, filepath -any,
255− mtl -any, optparse-applicative >= 0.12.1, parsec -any, purescript -any,
256− time -any, transformers -any, transformers-compat -any, Glob >= 0.7 && < 0.8,
257− aeson >= 0.8 && < 0.12, bytestring -any, utf8-string >= 1 && < 2
332+ build-depends: base >=4 && <5,
333+ purescript -any,
334+ aeson >= 0.8 && < 1.1,
335+ ansi-terminal >= 0.6.2 && < 0.7,
336+ base-compat >=0.6.0,
337+ bytestring -any,
338+ containers -any,
339+ directory -any,
340+ filepath -any,
341+ Glob >= 0.7 && < 0.8,
342+ mtl -any,
343+ optparse-applicative >= 0.12.1,
344+ parsec -any,
345+ time -any,
346+ transformers -any,
347+ transformers-compat -any,
348+ utf8-string >= 1 && < 2
258349 main-is: Main.hs
259350 buildable: True
260351 hs-source-dirs: psc
@@ -262,33 +353,49 @@ executable psc
262353 ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
263354
264355executable psci
265− build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
266− mtl -any, optparse-applicative >= 0.12.1, parsec -any,
267− haskeline >= 0.7.0.0, purescript -any, transformers -any,
268− transformers-compat -any, process -any, time -any, Glob -any, base-compat >=0.6.0,
269− boxes >= 0.1.4 && < 0.2.0
270−
356+ build-depends: base >=4 && <5,
357+ purescript -any,
358+ base-compat >=0.6.0,
359+ boxes >= 0.1.4 && < 0.2.0,
360+ bytestring -any,
361+ containers -any,
362+ directory -any,
363+ filepath -any,
364+ file-embed -any,
365+ Glob -any,
366+ haskeline >= 0.7.0.0,
367+ http-types == 0.9.*,
368+ mtl -any,
369+ optparse-applicative >= 0.12.1,
370+ parsec -any,
371+ process -any,
372+ stm >= 0.2.4.0,
373+ text -any,
374+ time -any,
375+ transformers -any,
376+ transformers-compat -any,
377+ wai == 3.*,
378+ wai-websockets == 3.*,
379+ warp == 3.*,
380+ websockets >= 0.9 && <0.10
271381 main-is: Main.hs
272382 buildable: True
273− hs-source-dirs: psci psci/main
274− other-modules: PSCi
275− PSCi.Types
276− PSCi.Parser
277− PSCi.Directive
278− PSCi.Completion
279− PSCi.IO
280− PSCi.Message
281− PSCi.Option
282− PSCi.Module
283− PSCi.Printer
284− Paths_purescript
383+ hs-source-dirs: psci
384+ other-modules: Paths_purescript
285385 ghc-options: -Wall -O2
286386
287387executable psc-docs
288− build-depends: base >=4 && <5, purescript -any,
289− optparse-applicative >= 0.12.1, process -any, mtl -any,
290− split -any, ansi-wl-pprint -any, directory -any,
291− filepath -any, Glob -any, transformers -any,
388+ build-depends: base >=4 && <5,
389+ purescript -any,
390+ ansi-wl-pprint -any,
391+ directory -any,
392+ filepath -any,
393+ Glob -any,
394+ mtl -any,
395+ optparse-applicative >= 0.12.1,
396+ process -any,
397+ split -any,
398+ transformers -any,
292399 transformers-compat -any
293400 main-is: Main.hs
294401 other-modules: Paths_purescript
@@ -300,7 +407,11 @@ executable psc-docs
300407 ghc-options: -Wall -O2
301408
302409executable psc-publish
303− build-depends: base >=4 && <5, purescript -any, bytestring -any, aeson -any, optparse-applicative -any
410+ build-depends: base >=4 && <5,
411+ purescript -any,
412+ aeson -any,
413+ bytestring -any,
414+ optparse-applicative -any
304415 main-is: Main.hs
305416 other-modules: Paths_purescript
306417 buildable: True
@@ -308,9 +419,15 @@ executable psc-publish
308419 ghc-options: -Wall -O2
309420
310421executable psc-hierarchy
311− build-depends: base >=4 && <5, purescript -any, optparse-applicative >= 0.12.1,
312− process -any, mtl -any, parsec -any, filepath -any, directory -any,
313− Glob -any
422+ build-depends: base >=4 && <5,
423+ purescript -any,
424+ directory -any,
425+ filepath -any,
426+ Glob -any,
427+ mtl -any,
428+ optparse-applicative >= 0.12.1,
429+ parsec -any,
430+ process -any
314431 main-is: Main.hs
315432 other-modules: Paths_purescript
316433 buildable: True
@@ -324,13 +441,13 @@ executable psc-bundle
324441 other-extensions:
325442 build-depends: base >=4 && <5,
326443 purescript -any,
327− filepath -any,
328444 directory -any,
445+ filepath -any,
446+ Glob -any,
329447 mtl -any,
330− transformers -any,
331− transformers-compat -any,
332448 optparse-applicative >= 0.12.1,
333− Glob -any
449+ transformers -any,
450+ transformers-compat -any
334451 ghc-options: -Wall -O2
335452 hs-source-dirs: psc-bundle
336453
@@ -338,19 +455,22 @@ executable psc-ide-server
338455 main-is: Main.hs
339456 other-modules: Paths_purescript
340457 other-extensions:
341− build-depends: base >=4 && <5
342− , purescript -any
343− , directory -any
344− , filepath -any
345− , monad-logger -any
346− , mtl -any
347− , transformers -any
348− , transformers-compat -any
349− , network -any
350− , optparse-applicative >= 0.12.1
351− , stm -any
352− , text -any
353− , base-compat >=0.6.0
458+ build-depends: base >=4 && <5,
459+ aeson >= 0.8 && < 1.1,
460+ bytestring -any,
461+ purescript -any,
462+ base-compat >=0.6.0,
463+ directory -any,
464+ filepath -any,
465+ monad-logger -any,
466+ mtl -any,
467+ network -any,
468+ optparse-applicative >= 0.12.1,
469+ protolude >= 0.1.6,
470+ stm -any,
471+ text -any,
472+ transformers -any,
473+ transformers-compat -any
354474 ghc-options: -Wall -O2 -threaded
355475 hs-source-dirs: psc-ide-server
356476
@@ -358,35 +478,71 @@ executable psc-ide-client
358478 main-is: Main.hs
359479 other-modules: Paths_purescript
360480 other-extensions:
361− build-depends: base >=4 && <5
362− , mtl -any
363− , text -any
364− , optparse-applicative >= 0.12.1
365− , network -any
366− , base-compat >=0.6.0
481+ build-depends: base >=4 && <5,
482+ base-compat >=0.6.0,
483+ bytestring -any,
484+ mtl -any,
485+ network -any,
486+ optparse-applicative >= 0.12.1,
487+ text -any
367488 ghc-options: -Wall -O2
368489 hs-source-dirs: psc-ide-client
369490
370491executable pcc
371− build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
372− file-embed -any,
492+ build-depends: base >=4 && <5,
493+ purescript -any,
494+ aeson -any,
495+ ansi-terminal >= 0.6.2 && < 0.7,
496+ base-compat >=0.6.0,
373497 bytestring -any,
374− mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
375− time -any, transformers -any, transformers-compat -any
498+ containers -any,
499+ directory -any,
500+ filepath -any,
501+ file-embed -any,
502+ Glob >= 0.7 && < 0.8,
503+ mtl -any,
504+ optparse-applicative >= 0.12.1,
505+ parsec -any,
506+ time -any,
507+ transformers -any,
508+ transformers-compat -any,
509+ utf8-string >= 1 && < 2
376510 main-is: Main.hs
377511 buildable: True
378512 hs-source-dirs: pcc
379− other-modules:
380− ghc-options: -Wall -O2 -fno-warn-unused-do-bind
513+ other-modules: Paths_purescript
514+ ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
515+
381516
382517test-suite tests
383− build-depends: base >=4 && <5, containers -any, directory -any,
384− filepath -any, mtl -any, parsec -any, purescript -any,
385− transformers -any, process -any, transformers-compat -any, time -any,
386− Glob -any, aeson-better-errors -any, bytestring -any, aeson -any,
387− base-compat -any, haskeline >= 0.7.0.0, optparse-applicative -any,
388− boxes -any, HUnit -any, hspec -any, hspec-discover -any, stm -any, text -any,
389− vector -any, utf8-string -any
518+ build-depends: base >=4 && <5,
519+ purescript -any,
520+ aeson -any,
521+ aeson-better-errors -any,
522+ base-compat -any,
523+ boxes -any,
524+ bytestring -any,
525+ containers -any,
526+ directory -any,
527+ filepath -any,
528+ Glob -any,
529+ haskeline >= 0.7.0.0,
530+ hspec -any,
531+ hspec-discover -any,
532+ HUnit -any,
533+ mtl -any,
534+ optparse-applicative -any,
535+ parsec -any,
536+ process -any,
537+ protolude >= 0.1.6,
538+ silently -any,
539+ stm -any,
540+ text -any,
541+ time -any,
542+ transformers -any,
543+ transformers-compat -any,
544+ utf8-string -any,
545+ vector -any
390546 ghc-options: -Wall
391547 type: exitcode-stdio-1.0
392548 main-is: Main.hs
@@ -404,13 +560,10 @@ test-suite tests
404560 Language.PureScript.Ide.MatcherSpec
405561 Language.PureScript.Ide.RebuildSpec
406562 Language.PureScript.Ide.ReexportsSpec
407− Language.PureScript.IdeSpec
408− PSCi.Completion
409− PSCi.Directive
410− PSCi.Module
411− PSCi.Types
563+ Language.PureScript.Ide.SourceFile.IntegrationSpec
564+ Language.PureScript.Ide.SourceFileSpec
412565 buildable: True
413− hs-source-dirs: tests psci
566+ hs-source-dirs: tests
414567
415568test-suite pcc-tests
416569 build-depends: base >=4 && <5, directory -any, filepath -any, process -any
@@ -418,3 +571,4 @@ test-suite pcc-tests
418571 main-is: TestMain.hs
419572 buildable: True
420573 hs-source-dirs: pcc
574+
src/Control/Monad/Logger.hs+7−20
@@ -1,33 +1,20 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Control.Monad.Logger
4−-- Author : Phil Freeman
5−-- License : MIT (http://opensource.org/licenses/MIT)
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | A replacement for WriterT IO which uses mutable references.
12−--
13−-----------------------------------------------------------------------------
14−
151{-# LANGUAGE FlexibleInstances #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
172{-# LANGUAGE TypeFamilies #-}
183
4+-- |
5+-- A replacement for WriterT IO which uses mutable references.
6+--
197module Control.Monad.Logger where
208
21−import Prelude ()
229import Prelude.Compat
2310
24−import Data.IORef
25−
2611import Control.Monad (ap)
27−import Control.Monad.IO.Class
28−import Control.Monad.Writer.Class
2912import Control.Monad.Base (MonadBase(..))
13+import Control.Monad.IO.Class
3014import Control.Monad.Trans.Control (MonadBaseControl(..))
15+import Control.Monad.Writer.Class
16+
17+import Data.IORef
3118
3219-- | A replacement for WriterT IO which uses mutable references.
3320newtype Logger w a = Logger { runLogger :: IORef w -> IO a }
src/Control/Monad/Supply.hs+5−18
@@ -1,32 +1,19 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Control.Monad.Supply
4−-- Copyright : (c) Phil Freeman 2014
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+
113-- |
124-- Fresh variable supply
135--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17−
186module Control.Monad.Supply where
197
20−import Prelude ()
218import Prelude.Compat
229
23−import Data.Functor.Identity
24−
25−import Control.Monad.State
2610import Control.Monad.Error.Class (MonadError(..))
2711import Control.Monad.Reader
12+import Control.Monad.State
2813import Control.Monad.Writer
2914
15+import Data.Functor.Identity
16+
3017newtype SupplyT m a = SupplyT { unSupplyT :: StateT Integer m a }
3118 deriving (Functor, Applicative, Monad, MonadTrans, MonadError e, MonadWriter w, MonadReader r)
3219
src/Control/Monad/Supply/Class.hs+6−6
@@ -1,24 +1,24 @@
1−{-# LANGUAGE MultiParamTypeClasses #-}
2−
31-- |
42-- A class for monads supporting a supply of fresh names
53--
64module Control.Monad.Supply.Class where
75
6+import Prelude.Compat
7+
88import Control.Monad.Supply
99import Control.Monad.State
1010
11−class (Monad m) => MonadSupply m where
11+class Monad m => MonadSupply m where
1212 fresh :: m Integer
1313
14−instance (Monad m) => MonadSupply (SupplyT m) where
14+instance Monad m => MonadSupply (SupplyT m) where
1515 fresh = SupplyT $ do
1616 n <- get
1717 put (n + 1)
1818 return n
1919
20−instance (MonadSupply m) => MonadSupply (StateT s m) where
20+instance MonadSupply m => MonadSupply (StateT s m) where
2121 fresh = lift fresh
2222
23−freshName :: (MonadSupply m) => m String
23+freshName :: MonadSupply m => m String
2424freshName = fmap (('$' :) . show) fresh
src/Language/PureScript.hs+5−17
@@ -1,33 +1,22 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- The main compiler module
133--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
18−
194module Language.PureScript
205 ( module P
216 , version
227 ) where
238
9+
10+import Control.Monad.Supply as P
11+
2412import Data.Version (Version)
2513
2614import Language.PureScript.AST as P
27−import Language.PureScript.Crash as P
2815import Language.PureScript.Comments as P
16+import Language.PureScript.Crash as P
2917import Language.PureScript.Environment as P
3018import Language.PureScript.Errors as P hiding (indent)
19+import Language.PureScript.Externs as P
3120import Language.PureScript.Kinds as P
3221import Language.PureScript.Linter as P
3322import Language.PureScript.Make as P
@@ -38,7 +27,6 @@ import Language.PureScript.Parser as P
3827import Language.PureScript.Pretty as P
3928import Language.PureScript.Renamer as P
4029import Language.PureScript.Sugar as P
41−import Control.Monad.Supply as P
4230import Language.PureScript.TypeChecker as P
4331import Language.PureScript.Types as P
4432
src/Language/PureScript/AST/Binders.hs+4−2
@@ -3,6 +3,8 @@
33--
44module Language.PureScript.AST.Binders where
55
6+import Prelude.Compat
7+
68import Language.PureScript.AST.SourcePos
79import Language.PureScript.AST.Literals
810import Language.PureScript.Names
@@ -33,7 +35,7 @@ data Binder
3335 -- A operator alias binder. During the rebracketing phase of desugaring,
3436 -- this data constructor will be removed.
3537 --
36− | OpBinder (Qualified Ident)
38+ | OpBinder (Qualified (OpName 'ValueOpName))
3739 -- |
3840 -- Binary operator application. During the rebracketing phase of desugaring,
3941 -- this data constructor will be removed.
@@ -59,7 +61,7 @@ data Binder
5961 -- A binder with a type annotation
6062 --
6163 | TypedBinder Type Binder
62− deriving (Show, Read, Eq)
64+ deriving (Show, Eq)
6365
6466-- |
6567-- Collect all names introduced in binders in an expression
src/Language/PureScript/AST/Declarations.hs+227−92
@@ -1,23 +1,17 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
21{-# LANGUAGE TemplateHaskell #-}
3−{-# LANGUAGE LambdaCase #-}
42
53-- |
64-- Data types for modules and declarations
75--
86module Language.PureScript.AST.Declarations where
97
10−import Prelude ()
118import Prelude.Compat
129
13−import Data.Aeson.TH
14−import Data.List (nub, (\\))
15−import Data.Maybe (mapMaybe)
10+import Control.Monad.Identity
1611
12+import Data.Aeson.TH
1713import qualified Data.Map as M
1814
19−import Control.Monad.Identity
20−
2115import Language.PureScript.AST.Binders
2216import Language.PureScript.AST.Literals
2317import Language.PureScript.AST.Operators
@@ -28,6 +22,148 @@ import Language.PureScript.Kinds
2822import Language.PureScript.TypeClassDictionaries
2923import Language.PureScript.Comments
3024import Language.PureScript.Environment
25+import qualified Language.PureScript.Bundle as Bundle
26+
27+import qualified Text.Parsec as P
28+
29+-- | A map of locally-bound names in scope.
30+type Context = [(Ident, Type)]
31+
32+-- | A type of error messages
33+data SimpleErrorMessage
34+ = ErrorParsingFFIModule FilePath (Maybe Bundle.ErrorMessage)
35+ | ErrorParsingModule P.ParseError
36+ | MissingFFIModule ModuleName
37+ | MultipleFFIModules ModuleName [FilePath]
38+ | UnnecessaryFFIModule ModuleName FilePath
39+ | MissingFFIImplementations ModuleName [Ident]
40+ | UnusedFFIImplementations ModuleName [Ident]
41+ | InvalidFFIIdentifier ModuleName String
42+ | CannotGetFileInfo FilePath
43+ | CannotReadFile FilePath
44+ | CannotWriteFile FilePath
45+ | InfiniteType Type
46+ | InfiniteKind Kind
47+ | MultipleValueOpFixities (OpName 'ValueOpName)
48+ | MultipleTypeOpFixities (OpName 'TypeOpName)
49+ | OrphanTypeDeclaration Ident
50+ | RedefinedModule ModuleName [SourceSpan]
51+ | RedefinedIdent Ident
52+ | OverlappingNamesInLet
53+ | UnknownName (Qualified Name)
54+ | UnknownImport ModuleName Name
55+ | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
56+ | UnknownExport Name
57+ | UnknownExportDataConstructor (ProperName 'TypeName) (ProperName 'ConstructorName)
58+ | ScopeConflict Name [ModuleName]
59+ | ScopeShadowing Name (Maybe ModuleName) [ModuleName]
60+ | DeclConflict Name Name
61+ | ExportConflict (Qualified Name) (Qualified Name)
62+ | DuplicateModuleName ModuleName
63+ | DuplicateTypeArgument String
64+ | InvalidDoBind
65+ | InvalidDoLet
66+ | CycleInDeclaration Ident
67+ | CycleInTypeSynonym (Maybe (ProperName 'TypeName))
68+ | CycleInModules [ModuleName]
69+ | NameIsUndefined Ident
70+ | UndefinedTypeVariable (ProperName 'TypeName)
71+ | PartiallyAppliedSynonym (Qualified (ProperName 'TypeName))
72+ | EscapedSkolem (Maybe Expr)
73+ | TypesDoNotUnify Type Type
74+ | KindsDoNotUnify Kind Kind
75+ | ConstrainedTypeUnified Type Type
76+ | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
77+ | NoInstanceFound Constraint
78+ | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
79+ | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
80+ | CannotFindDerivingType (ProperName 'TypeName)
81+ | DuplicateLabel String (Maybe Expr)
82+ | DuplicateValueDeclaration Ident
83+ | ArgListLengthsDiffer Ident
84+ | OverlappingArgNames (Maybe Ident)
85+ | MissingClassMember Ident
86+ | ExtraneousClassMember Ident (Qualified (ProperName 'ClassName))
87+ | ExpectedType Type Kind
88+ | IncorrectConstructorArity (Qualified (ProperName 'ConstructorName))
89+ | ExprDoesNotHaveType Expr Type
90+ | PropertyIsMissing String
91+ | AdditionalProperty String
92+ | CannotApplyFunction Type Expr
93+ | TypeSynonymInstance
94+ | OrphanInstance Ident (Qualified (ProperName 'ClassName)) [Type]
95+ | InvalidNewtype (ProperName 'TypeName)
96+ | InvalidInstanceHead Type
97+ | TransitiveExportError DeclarationRef [DeclarationRef]
98+ | TransitiveDctorExportError DeclarationRef (ProperName 'ConstructorName)
99+ | ShadowedName Ident
100+ | ShadowedTypeVar String
101+ | UnusedTypeVar String
102+ | WildcardInferredType Type Context
103+ | HoleInferredType String Type Context
104+ | MissingTypeDeclaration Ident Type
105+ | OverlappingPattern [[Binder]] Bool
106+ | IncompleteExhaustivityCheck
107+ | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
108+ | ImportHidingModule ModuleName
109+ | UnusedImport ModuleName
110+ | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
111+ | UnusedDctorImport (ProperName 'TypeName)
112+ | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
113+ | DuplicateSelectiveImport ModuleName
114+ | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
115+ | DuplicateImportRef Name
116+ | DuplicateExportRef Name
117+ | IntOutOfRange Integer String Integer Integer
118+ | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
119+ | ImplicitImport ModuleName [DeclarationRef]
120+ | HidingImport ModuleName [DeclarationRef]
121+ | CaseBinderLengthDiffers Int [Binder]
122+ | IncorrectAnonymousArgument
123+ | InvalidOperatorInBinder (Qualified (OpName 'ValueOpName)) (Qualified Ident)
124+ | DeprecatedRequirePath
125+ | CannotGeneralizeRecursiveFunction Ident Type
126+ deriving (Show)
127+
128+-- | Error message hints, providing more detailed information about failure.
129+data ErrorMessageHint
130+ = ErrorUnifyingTypes Type Type
131+ | ErrorInExpression Expr
132+ | ErrorInModule ModuleName
133+ | ErrorInInstance (Qualified (ProperName 'ClassName)) [Type]
134+ | ErrorInSubsumption Type Type
135+ | ErrorCheckingAccessor Expr String
136+ | ErrorCheckingType Expr Type
137+ | ErrorCheckingKind Type
138+ | ErrorCheckingGuard
139+ | ErrorInferringType Expr
140+ | ErrorInApplication Expr Type Expr
141+ | ErrorInDataConstructor (ProperName 'ConstructorName)
142+ | ErrorInTypeConstructor (ProperName 'TypeName)
143+ | ErrorInBindingGroup [Ident]
144+ | ErrorInDataBindingGroup
145+ | ErrorInTypeSynonym (ProperName 'TypeName)
146+ | ErrorInValueDeclaration Ident
147+ | ErrorInTypeDeclaration Ident
148+ | ErrorInForeignImport Ident
149+ | ErrorSolvingConstraint Constraint
150+ | PositionedError SourceSpan
151+ deriving (Show)
152+
153+-- | Categories of hints
154+data HintCategory
155+ = ExprHint
156+ | KindHint
157+ | CheckHint
158+ | PositionHint
159+ | SolverHint
160+ | OtherHint
161+ deriving (Show, Eq)
162+
163+data ErrorMessage = ErrorMessage
164+ [ErrorMessageHint]
165+ SimpleErrorMessage
166+ deriving (Show)
31167
32168-- |
33169-- A module declaration, consisting of comments about the module, a module name,
@@ -35,7 +171,7 @@ import Language.PureScript.Environment
35171-- explicitly exported. If the export list is Nothing, everything is exported.
36172--
37173data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef])
38− deriving (Show, Read)
174+ deriving (Show)
39175
40176-- | Return a module's name.
41177getModuleName :: Module -> ModuleName
@@ -47,9 +183,9 @@ getModuleName (Module _ _ name _ _) = name
47183addDefaultImport :: ModuleName -> Module -> Module
48184addDefaultImport toImport m@(Module ss coms mn decls exps) =
49185 if isExistingImport `any` decls || mn == toImport then m
50− else Module ss coms mn (ImportDeclaration toImport Implicit Nothing False : decls) exps
186+ else Module ss coms mn (ImportDeclaration toImport Implicit Nothing : decls) exps
51187 where
52− isExistingImport (ImportDeclaration mn' _ _ _) | mn' == toImport = True
188+ isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True
53189 isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
54190 isExistingImport _ = False
55191
@@ -64,16 +200,20 @@ data DeclarationRef
64200 -- |
65201 -- A type operator
66202 --
67− | TypeOpRef Ident
203+ | TypeOpRef (OpName 'TypeOpName)
68204 -- |
69205 -- A value
70206 --
71207 | ValueRef Ident
72208 -- |
209+ -- A value-level operator
210+ --
211+ | ValueOpRef (OpName 'ValueOpName)
212+ -- |
73213 -- A type class
74214 --
75215 | TypeClassRef (ProperName 'ClassName)
76− -- |
216+ -- |
77217 -- A type class instance, created during typeclass desugaring (name, class name, instance types)
78218 --
79219 | TypeInstanceRef Ident
@@ -82,54 +222,59 @@ data DeclarationRef
82222 --
83223 | ModuleRef ModuleName
84224 -- |
85− -- An unspecified ProperName ref. This will be replaced with a TypeClassRef
86− -- or TypeRef during name desugaring.
87− | ProperRef String
225+ -- A value re-exported from another module. These will be inserted during
226+ -- elaboration in name desugaring.
227+ --
228+ | ReExportRef ModuleName DeclarationRef
88229 -- |
89230 -- A declaration reference with source position information
90231 --
91232 | PositionedDeclarationRef SourceSpan [Comment] DeclarationRef
92− deriving (Show, Read)
233+ deriving (Show)
93234
94235instance Eq DeclarationRef where
95− (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
96− (TypeOpRef name) == (TypeOpRef name') = name == name'
97− (ValueRef name) == (ValueRef name') = name == name'
98− (TypeClassRef name) == (TypeClassRef name') = name == name'
236+ (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
237+ (TypeOpRef name) == (TypeOpRef name') = name == name'
238+ (ValueRef name) == (ValueRef name') = name == name'
239+ (ValueOpRef name) == (ValueOpRef name') = name == name'
240+ (TypeClassRef name) == (TypeClassRef name') = name == name'
99241 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
100− (ModuleRef name) == (ModuleRef name') = name == name'
101− (ProperRef name) == (ProperRef name') = name == name'
242+ (ModuleRef name) == (ModuleRef name') = name == name'
243+ (ReExportRef mn ref) == (ReExportRef mn' ref') = mn == mn' && ref == ref'
102244 (PositionedDeclarationRef _ _ r) == r' = r == r'
103245 r == (PositionedDeclarationRef _ _ r') = r == r'
104246 _ == _ = False
105247
248+getTypeRef :: DeclarationRef -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
249+getTypeRef (TypeRef name dctors) = Just (name, dctors)
250+getTypeRef (PositionedDeclarationRef _ _ r) = getTypeRef r
251+getTypeRef _ = Nothing
252+
253+getTypeOpRef :: DeclarationRef -> Maybe (OpName 'TypeOpName)
254+getTypeOpRef (TypeOpRef op) = Just op
255+getTypeOpRef (PositionedDeclarationRef _ _ r) = getTypeOpRef r
256+getTypeOpRef _ = Nothing
257+
258+getValueRef :: DeclarationRef -> Maybe Ident
259+getValueRef (ValueRef name) = Just name
260+getValueRef (PositionedDeclarationRef _ _ r) = getValueRef r
261+getValueRef _ = Nothing
262+
263+getValueOpRef :: DeclarationRef -> Maybe (OpName 'ValueOpName)
264+getValueOpRef (ValueOpRef op) = Just op
265+getValueOpRef (PositionedDeclarationRef _ _ r) = getValueOpRef r
266+getValueOpRef _ = Nothing
267+
268+getTypeClassRef :: DeclarationRef -> Maybe (ProperName 'ClassName)
269+getTypeClassRef (TypeClassRef name) = Just name
270+getTypeClassRef (PositionedDeclarationRef _ _ r) = getTypeClassRef r
271+getTypeClassRef _ = Nothing
272+
106273isModuleRef :: DeclarationRef -> Bool
107274isModuleRef (PositionedDeclarationRef _ _ r) = isModuleRef r
108275isModuleRef (ModuleRef _) = True
109276isModuleRef _ = False
110277
111−-- |
112−-- Finds duplicate values in a list of declaration refs. The returned values
113−-- are the duplicate refs with data constructors elided, and then a separate
114−-- list of duplicate data constructors.
115−--
116−findDuplicateRefs :: [DeclarationRef] -> ([DeclarationRef], [ProperName 'ConstructorName])
117−findDuplicateRefs refs =
118− let positionless = stripPosInfo `map` refs
119− simplified = simplifyTypeRefs `map` positionless
120− dupeRefs = nub $ simplified \\ nub simplified
121− dupeCtors = concat $ flip mapMaybe positionless $ \case
122− TypeRef _ (Just dctors) ->
123− let dupes = dctors \\ nub dctors
124− in if null dupes then Nothing else Just dupes
125− _ -> Nothing
126− in (dupeRefs, dupeCtors)
127− where
128− stripPosInfo (PositionedDeclarationRef _ _ ref) = stripPosInfo ref
129− stripPosInfo other = other
130− simplifyTypeRefs (TypeRef pn _) = TypeRef pn Nothing
131− simplifyTypeRefs other = other
132−
133278-- |
134279-- The data type which specifies type of import declaration
135280--
@@ -146,7 +291,7 @@ data ImportDeclarationType
146291 -- An import with a list of references to hide: `import M hiding (foo)`
147292 --
148293 | Hiding [DeclarationRef]
149− deriving (Eq, Show, Read)
294+ deriving (Eq, Show)
150295
151296isImplicit :: ImportDeclarationType -> Bool
152297isImplicit Implicit = True
@@ -193,14 +338,13 @@ data Declaration
193338 --
194339 | ExternDataDeclaration (ProperName 'TypeName) Kind
195340 -- |
196− -- A fixity declaration (fixity data, operator name, value the operator is an alias for)
341+ -- A fixity declaration
197342 --
198− | FixityDeclaration Fixity String (Maybe (Qualified FixityAlias))
343+ | FixityDeclaration (Either ValueFixity TypeFixity)
199344 -- |
200345 -- A module import (module name, qualified/unqualified/hiding, optional "qualified as" name)
201− -- TODO: also a boolean specifying whether the old `qualified` syntax was used, so a warning can be raised in desugaring (remove for 0.9)
202346 --
203− | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName) Bool
347+ | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName)
204348 -- |
205349 -- A type class declaration (name, argument, implies, member declarations)
206350 --
@@ -214,32 +358,19 @@ data Declaration
214358 -- A declaration with source position information
215359 --
216360 | PositionedDeclaration SourceSpan [Comment] Declaration
217− deriving (Show, Read)
218−
219−data FixityAlias
220− = AliasValue Ident
221− | AliasConstructor (ProperName 'ConstructorName)
222− | AliasType (ProperName 'TypeName)
223− deriving (Eq, Ord, Show, Read)
224−
225−foldFixityAlias
226− :: (Ident -> a)
227− -> (ProperName 'ConstructorName -> a)
228− -> (ProperName 'TypeName -> a)
229− -> FixityAlias
230− -> a
231−foldFixityAlias f _ _ (AliasValue name) = f name
232−foldFixityAlias _ g _ (AliasConstructor name) = g name
233−foldFixityAlias _ _ h (AliasType name) = h name
234−
235−getValueAlias :: FixityAlias -> Maybe (Either Ident (ProperName 'ConstructorName))
236−getValueAlias (AliasValue name) = Just $ Left name
237−getValueAlias (AliasConstructor name) = Just $ Right name
238−getValueAlias _ = Nothing
239−
240−getTypeAlias :: FixityAlias -> Maybe (ProperName 'TypeName)
241−getTypeAlias (AliasType name) = Just name
242−getTypeAlias _ = Nothing
361+ deriving (Show)
362+
363+data ValueFixity = ValueFixity Fixity (Qualified (Either Ident (ProperName 'ConstructorName))) (OpName 'ValueOpName)
364+ deriving (Eq, Ord, Show)
365+
366+data TypeFixity = TypeFixity Fixity (Qualified (ProperName 'TypeName)) (OpName 'TypeOpName)
367+ deriving (Eq, Ord, Show)
368+
369+pattern ValueFixityDeclaration :: Fixity -> Qualified (Either Ident (ProperName 'ConstructorName)) -> OpName 'ValueOpName -> Declaration
370+pattern ValueFixityDeclaration fixity name op = FixityDeclaration (Left (ValueFixity fixity name op))
371+
372+pattern TypeFixityDeclaration :: Fixity -> Qualified (ProperName 'TypeName) -> OpName 'TypeOpName -> Declaration
373+pattern TypeFixityDeclaration fixity name op = FixityDeclaration (Right (TypeFixity fixity name op))
243374
244375-- | The members of a type class instance declaration
245376data TypeInstanceBody
@@ -247,7 +378,7 @@ data TypeInstanceBody
247378 = DerivedInstance
248379 -- | This is a regular (explicit) instance
249380 | ExplicitInstance [Declaration]
250− deriving (Show, Read)
381+ deriving (Show)
251382
252383mapTypeInstanceBody :: ([Declaration] -> [Declaration]) -> TypeInstanceBody -> TypeInstanceBody
253384mapTypeInstanceBody f = runIdentity . traverseTypeInstanceBody (Identity . f)
@@ -298,6 +429,11 @@ isFixityDecl FixityDeclaration{} = True
298429isFixityDecl (PositionedDeclaration _ _ d) = isFixityDecl d
299430isFixityDecl _ = False
300431
432+getFixityDecl :: Declaration -> Maybe (Either ValueFixity TypeFixity)
433+getFixityDecl (FixityDeclaration fixity) = Just fixity
434+getFixityDecl (PositionedDeclaration _ _ d) = getFixityDecl d
435+getFixityDecl _ = Nothing
436+
301437-- |
302438-- Test if a declaration is a foreign import
303439--
@@ -361,16 +497,9 @@ data Expr
361497 --
362498 | Parens Expr
363499 -- |
364− -- Operator section. This will be removed during desugaring and replaced with lambda.
365− --
366− | OperatorSection Expr (Either Expr Expr)
367− -- |
368− -- An object property getter (e.g. `_.x`). This will be removed during
369− -- desugaring and expanded into a lambda that reads a property from an object.
370− --
371− | ObjectGetter String
372− -- |
373− -- An record property accessor expression
500+ -- An record property accessor expression (e.g. `obj.x` or `_.x`).
501+ -- Anonymous arguments will be removed during desugaring and expanded
502+ -- into a lambda that reads a property from a record.
374503 --
375504 | Accessor String Expr
376505 -- |
@@ -390,6 +519,11 @@ data Expr
390519 --
391520 | Var (Qualified Ident)
392521 -- |
522+ -- An operator. This will be desugared into a function during the "operators"
523+ -- phase of desugaring.
524+ --
525+ | Op (Qualified (OpName 'ValueOpName))
526+ -- |
393527 -- Conditional (if-then-else expression)
394528 --
395529 | IfThenElse Expr Expr Expr
@@ -426,7 +560,9 @@ data Expr
426560 -- at superclass implementations when searching for a dictionary, the type class name and
427561 -- instance type, and the type class dictionaries in scope.
428562 --
429− | TypeClassDictionary Constraint (M.Map (Maybe ModuleName) (M.Map (Qualified (ProperName 'ClassName)) (M.Map (Qualified Ident) TypeClassDictionaryInScope)))
563+ | TypeClassDictionary Constraint
564+ (M.Map (Maybe ModuleName) (M.Map (Qualified (ProperName 'ClassName)) (M.Map (Qualified Ident) TypeClassDictionaryInScope)))
565+ [ErrorMessageHint]
430566 -- |
431567 -- A typeclass dictionary accessor, the implementation is left unspecified until CoreFn desugaring.
432568 --
@@ -447,7 +583,7 @@ data Expr
447583 -- A value with source position information
448584 --
449585 | PositionedValue SourceSpan [Comment] Expr
450− deriving (Show, Read)
586+ deriving (Show)
451587
452588-- |
453589-- An alternative in a case statement
@@ -461,7 +597,7 @@ data CaseAlternative = CaseAlternative
461597 -- The result expression or a collect of guarded expressions
462598 --
463599 , caseAlternativeResult :: Either [(Guard, Expr)] Expr
464− } deriving (Show, Read)
600+ } deriving (Show)
465601
466602-- |
467603-- A statement in a do-notation block
@@ -483,8 +619,7 @@ data DoNotationElement
483619 -- A do notation element with source position information
484620 --
485621 | PositionedDoNotationElement SourceSpan [Comment] DoNotationElement
486− deriving (Show, Read)
622+ deriving (Show)
487623
488624$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
489625$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ImportDeclarationType)
490−$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''FixityAlias)
src/Language/PureScript/AST/Exported.hs+12−15
@@ -3,7 +3,10 @@ module Language.PureScript.AST.Exported
33 , isExported
44 ) where
55
6+import Prelude.Compat
7+
68import Control.Category ((>>>))
9+
710import Data.Maybe (mapMaybe)
811
912import Language.PureScript.AST.Declarations
@@ -99,7 +102,7 @@ typeInstanceConstituents (TypeInstanceDeclaration _ constraints className tys _)
99102 Left className : (concatMap fromConstraint constraints ++ concatMap fromType tys)
100103 where
101104
102− fromConstraint (name, tys') = Left name : concatMap fromType tys'
105+ fromConstraint c = Left (constraintClass c) : concatMap fromType (constraintArgs c)
103106 fromType = everythingOnTypes (++) go
104107
105108 -- Note that type synonyms are disallowed in instance declarations, so
@@ -124,21 +127,15 @@ isExported _ TypeInstanceDeclaration{} = True
124127isExported exps (PositionedDeclaration _ _ d) = isExported exps d
125128isExported (Just exps) decl = any (matches decl) exps
126129 where
127− matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
128− matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
129− matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
130− matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
131− matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
132− matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
130+ matches (TypeDeclaration ident _) (ValueRef ident') = ident == ident'
131+ matches (ValueDeclaration ident _ _ _) (ValueRef ident') = ident == ident'
132+ matches (ExternDeclaration ident _) (ValueRef ident') = ident == ident'
133+ matches (DataDeclaration _ ident _ _) (TypeRef ident' _) = ident == ident'
134+ matches (ExternDataDeclaration ident _) (TypeRef ident' _) = ident == ident'
135+ matches (TypeSynonymDeclaration ident _ _) (TypeRef ident' _) = ident == ident'
133136 matches (TypeClassDeclaration ident _ _ _) (TypeClassRef ident') = ident == ident'
134−
135− matches (DataDeclaration _ ident _ _) (ProperRef ident') = runProperName ident == ident'
136− matches (TypeClassDeclaration ident _ _ _) (ProperRef ident') = runProperName ident == ident'
137−
138− matches (FixityDeclaration _ name (Just (Qualified _ (AliasValue _)))) (ValueRef ident') = name == runIdent ident'
139− matches (FixityDeclaration _ name (Just (Qualified _ (AliasConstructor _)))) (ValueRef ident') = name == runIdent ident'
140− matches (FixityDeclaration _ name (Just (Qualified _ (AliasType _)))) (TypeOpRef ident') = name == runIdent ident'
141−
137+ matches (ValueFixityDeclaration _ _ op) (ValueOpRef op') = op == op'
138+ matches (TypeFixityDeclaration _ _ op) (TypeOpRef op') = op == op'
142139 matches (PositionedDeclaration _ _ d) r = d `matches` r
143140 matches d (PositionedDeclarationRef _ _ r) = d `matches` r
144141 matches _ _ = False
src/Language/PureScript/AST/Literals.hs+3−3
@@ -1,10 +1,10 @@
1−{-# LANGUAGE DeriveFunctor #-}
2−
31-- |
42-- The core functional representation for literal values.
53--
64module Language.PureScript.AST.Literals where
75
6+import Prelude.Compat
7+
88-- |
99-- Data type for literal values. Parameterised so it can be used for Exprs and
1010-- Binders.
@@ -34,4 +34,4 @@ data Literal a
3434 -- An object literal
3535 --
3636 | ObjectLiteral [(String, a)]
37− deriving (Eq, Ord, Show, Read, Functor)
37+ deriving (Eq, Ord, Show, Functor)
src/Language/PureScript/AST/Operators.hs+4−2
@@ -5,6 +5,8 @@
55--
66module Language.PureScript.AST.Operators where
77
8+import Prelude.Compat
9+
810import Data.Aeson ((.=))
911import qualified Data.Aeson as A
1012
@@ -19,7 +21,7 @@ type Precedence = Integer
1921-- Associativity for infix operators
2022--
2123data Associativity = Infixl | Infixr | Infix
22− deriving (Show, Read, Eq, Ord)
24+ deriving (Show, Eq, Ord)
2325
2426showAssoc :: Associativity -> String
2527showAssoc Infixl = "infixl"
@@ -42,7 +44,7 @@ instance A.FromJSON Associativity where
4244-- Fixity data for infix operators
4345--
4446data Fixity = Fixity Associativity Precedence
45− deriving (Show, Read, Eq, Ord)
47+ deriving (Show, Eq, Ord)
4648
4749instance A.ToJSON Fixity where
4850 toJSON (Fixity associativity precedence) =
src/Language/PureScript/AST/SourcePos.hs+2−5
@@ -1,5 +1,3 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE RecordWildCards #-}
31{-# LANGUAGE OverloadedStrings #-}
42
53-- |
@@ -7,7 +5,6 @@
75--
86module Language.PureScript.AST.SourcePos where
97
10−import Prelude ()
118import Prelude.Compat
129
1310import Data.Aeson ((.=), (.:))
@@ -25,7 +22,7 @@ data SourcePos = SourcePos
2522 -- Column number
2623 --
2724 , sourcePosColumn :: Int
28− } deriving (Show, Read, Eq, Ord)
25+ } deriving (Show, Eq, Ord)
2926
3027displaySourcePos :: SourcePos -> String
3128displaySourcePos sp =
@@ -53,7 +50,7 @@ data SourceSpan = SourceSpan
5350 -- End of the span
5451 --
5552 , spanEnd :: SourcePos
56− } deriving (Show, Read, Eq, Ord)
53+ } deriving (Show, Eq, Ord)
5754
5855displayStartEndPos :: SourceSpan -> String
5956displayStartEndPos sp =
src/Language/PureScript/AST/Traversals.hs+8−25
@@ -1,21 +1,18 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−
31-- |
42-- AST traversal helpers
53--
64module Language.PureScript.AST.Traversals where
75
8−import Prelude ()
96import Prelude.Compat
107
11−import Data.Maybe (mapMaybe)
12−import Data.List (mapAccumL)
13−import Data.Foldable (fold)
14−import qualified Data.Set as S
15−
168import Control.Monad
179import Control.Arrow ((***), (+++))
1810
11+import Data.Foldable (fold)
12+import Data.List (mapAccumL)
13+import Data.Maybe (mapMaybe)
14+import qualified Data.Set as S
15+
1916import Language.PureScript.AST.Binders
2017import Language.PureScript.AST.Literals
2118import Language.PureScript.AST.Declarations
@@ -47,8 +44,6 @@ everywhereOnValues f g h = (f', g', h')
4744 g' (UnaryMinus v) = g (UnaryMinus (g' v))
4845 g' (BinaryNoParens op v1 v2) = g (BinaryNoParens (g' op) (g' v1) (g' v2))
4946 g' (Parens v) = g (Parens (g' v))
50− g' (OperatorSection op (Left v)) = g (OperatorSection (g' op) (Left $ g' v))
51− g' (OperatorSection op (Right v)) = g (OperatorSection (g' op) (Right $ g' v))
5247 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
5348 g' (Accessor prop v) = g (Accessor prop (g' v))
5449 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
@@ -116,8 +111,6 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
116111 g' (UnaryMinus v) = UnaryMinus <$> (g v >>= g')
117112 g' (BinaryNoParens op v1 v2) = BinaryNoParens <$> (g op >>= g') <*> (g v1 >>= g') <*> (g v2 >>= g')
118113 g' (Parens v) = Parens <$> (g v >>= g')
119− g' (OperatorSection op (Left v)) = OperatorSection <$> (g op >>= g') <*> (Left <$> (g v >>= g'))
120− g' (OperatorSection op (Right v)) = OperatorSection <$> (g op >>= g') <*> (Right <$> (g v >>= g'))
121114 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
122115 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
123116 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> traverse (sndM (g' <=< g)) vs
@@ -185,8 +178,6 @@ everywhereOnValuesM f g h = (f', g', h')
185178 g' (UnaryMinus v) = (UnaryMinus <$> g' v) >>= g
186179 g' (BinaryNoParens op v1 v2) = (BinaryNoParens <$> g' op <*> g' v1 <*> g' v2) >>= g
187180 g' (Parens v) = (Parens <$> g' v) >>= g
188− g' (OperatorSection op (Left v)) = (OperatorSection <$> g' op <*> (Left <$> g' v)) >>= g
189− g' (OperatorSection op (Right v)) = (OperatorSection <$> g' op <*> (Right <$> g' v)) >>= g
190181 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
191182 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
192183 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> traverse (sndM g') vs) >>= g
@@ -259,8 +250,6 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
259250 g' v@(UnaryMinus v1) = g v <> g' v1
260251 g' v@(BinaryNoParens op v1 v2) = g v <> g' op <> g' v1 <> g' v2
261252 g' v@(Parens v1) = g v <> g' v1
262− g' v@(OperatorSection op (Left v1)) = g v <> g' op <> g' v1
263− g' v@(OperatorSection op (Right v1)) = g v <> g' op <> g' v1
264253 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
265254 g' v@(Accessor _ v1) = g v <> g' v1
266255 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
@@ -338,8 +327,6 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
338327 g' s (UnaryMinus v1) = g'' s v1
339328 g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
340329 g' s (Parens v1) = g'' s v1
341− g' s (OperatorSection op (Left v)) = g'' s op <> g'' s v
342− g' s (OperatorSection op (Right v)) = g'' s op <> g'' s v
343330 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
344331 g' s (Accessor _ v1) = g'' s v1
345332 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
@@ -419,8 +406,6 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
419406 g' s (UnaryMinus v) = UnaryMinus <$> g'' s v
420407 g' s (BinaryNoParens op v1 v2) = BinaryNoParens <$> g'' s op <*> g'' s v1 <*> g'' s v2
421408 g' s (Parens v) = Parens <$> g'' s v
422− g' s (OperatorSection op (Left v)) = OperatorSection <$> g'' s op <*> (Left <$> g'' s v)
423− g' s (OperatorSection op (Right v)) = OperatorSection <$> g'' s op <*> (Right <$> g'' s v)
424409 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
425410 g' s (Accessor prop v) = Accessor prop <$> g'' s v
426411 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> traverse (sndM (g'' s)) vs
@@ -510,8 +495,6 @@ everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
510495 g' s (UnaryMinus v1) = g'' s v1
511496 g' s (BinaryNoParens op v1 v2) = g'' s op <> g'' s v1 <> g'' s v2
512497 g' s (Parens v1) = g'' s v1
513− g' s (OperatorSection op (Left v)) = g'' s op <> g'' s v
514− g' s (OperatorSection op (Right v)) = g'' s op <> g'' s v
515498 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
516499 g' s (Accessor _ v1) = g'' s v1
517500 g' s (ObjectUpdate obj vs) = g'' s obj <> foldMap (g'' s . snd) vs
@@ -593,13 +576,13 @@ accumTypes f = everythingOnValues mappend forDecls forValues (const mempty) (con
593576 where
594577 forDecls (DataDeclaration _ _ _ dctors) = mconcat (concatMap (map f . snd) dctors)
595578 forDecls (ExternDeclaration _ ty) = f ty
596− forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . snd) implies)
597− forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . snd) cs) `mappend` mconcat (map f tys)
579+ forDecls (TypeClassDeclaration _ _ implies _) = mconcat (concatMap (map f . constraintArgs) implies)
580+ forDecls (TypeInstanceDeclaration _ cs _ tys _) = mconcat (concatMap (map f . constraintArgs) cs) `mappend` mconcat (map f tys)
598581 forDecls (TypeSynonymDeclaration _ _ ty) = f ty
599582 forDecls (TypeDeclaration _ ty) = f ty
600583 forDecls _ = mempty
601584
602− forValues (TypeClassDictionary (_, cs) _) = mconcat (map f cs)
585+ forValues (TypeClassDictionary c _ _) = mconcat (map f (constraintArgs c))
603586 forValues (SuperClassDictionary _ tys) = mconcat (map f tys)
604587 forValues (TypedValue _ _ ty) = f ty
605588 forValues _ = mempty
src/Language/PureScript/Bundle.hs+72−56
@@ -1,53 +1,40 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : psc-bundle
4−-- Copyright : (c) Phil Freeman 2015
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | Bundles compiled PureScript modules for the browser.
1+-- |
2+-- Bundles compiled PureScript modules for the browser.
123--
134-- This module takes as input the individual generated modules from 'Language.PureScript.Make' and
145-- performs dead code elimination, filters empty modules,
156-- and generates the final Javascript bundle.
16−-----------------------------------------------------------------------------
17−
18−{-# LANGUAGE PatternGuards #-}
19−{-# LANGUAGE FlexibleContexts #-}
20−{-# LANGUAGE ScopedTypeVariables #-}
21−{-# LANGUAGE TupleSections #-}
22−
23−module Language.PureScript.Bundle (
24− bundle
25− , ModuleIdentifier(..)
26− , moduleName
27− , ModuleType(..)
28− , ErrorMessage(..)
29− , printErrorMessage
30− , getExportedIdentifiers
31−) where
32−
33−import Prelude ()
7+module Language.PureScript.Bundle
8+ ( bundle
9+ , guessModuleIdentifier
10+ , ModuleIdentifier(..)
11+ , moduleName
12+ , ModuleType(..)
13+ , ErrorMessage(..)
14+ , printErrorMessage
15+ , getExportedIdentifiers
16+ ) where
17+
3418import Prelude.Compat
3519
36−import Data.List (nub, stripPrefix)
37−import Data.Maybe (mapMaybe, catMaybes, fromMaybe)
20+import Control.Monad
21+import Control.Monad.Error.Class
22+
23+import Data.Char (chr, digitToInt)
3824import Data.Generics (everything, everywhere, mkQ, mkT)
3925import Data.Graph
26+import Data.List (nub, stripPrefix)
27+import Data.Maybe (mapMaybe, catMaybes)
4028import Data.Version (showVersion)
41−
4229import qualified Data.Set as S
4330
44−import Control.Monad
45−import Control.Monad.Error.Class
4631import Language.JavaScript.Parser
4732import Language.JavaScript.Parser.AST
4833
4934import qualified Paths_purescript as Paths
5035
36+import System.FilePath (takeFileName, takeDirectory)
37+
5138-- | The type of error messages. We separate generation and rendering of errors using a data
5239-- type, in case we need to match on error types later.
5340data ErrorMessage
@@ -56,24 +43,32 @@ data ErrorMessage
5643 | UnableToParseModule String
5744 | UnsupportedExport
5845 | ErrorInModule ModuleIdentifier ErrorMessage
59− deriving (Show, Read)
46+ deriving (Show)
6047
6148-- | Modules are either "regular modules" (i.e. those generated by psc) or foreign modules.
6249data ModuleType
6350 = Regular
6451 | Foreign
65− deriving (Show, Read, Eq, Ord)
52+ deriving (Show, Eq, Ord)
6653
6754showModuleType :: ModuleType -> String
6855showModuleType Regular = "Regular"
6956showModuleType Foreign = "Foreign"
7057
7158-- | A module is identified by its module name and its type.
72−data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Read, Eq, Ord)
59+data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Eq, Ord)
7360
7461moduleName :: ModuleIdentifier -> String
7562moduleName (ModuleIdentifier name _) = name
7663
64+-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
65+guessModuleIdentifier :: MonadError ErrorMessage m => FilePath -> m ModuleIdentifier
66+guessModuleIdentifier filename = ModuleIdentifier (takeFileName (takeDirectory filename)) <$> guessModuleType (takeFileName filename)
67+ where
68+ guessModuleType "index.js" = pure Regular
69+ guessModuleType "foreign.js" = pure Foreign
70+ guessModuleType name = throwError $ UnsupportedModulePath name
71+
7772-- | A piece of code is identified by its module and its name. These keys are used to label vertices
7873-- in the dependency graph.
7974type Key = (ModuleIdentifier, String)
@@ -134,13 +129,13 @@ printErrorMessage (ErrorInModule mid e) =
134129 name ++ " (" ++ showModuleType ty ++ ")"
135130
136131-- | Calculate the ModuleIdentifier which a require(...) statement imports.
137−checkImportPath :: Maybe FilePath -> String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
138−checkImportPath _ "./foreign" m _ =
132+checkImportPath :: String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
133+checkImportPath "./foreign" m _ =
139134 Right (ModuleIdentifier (moduleName m) Foreign)
140−checkImportPath requirePath name _ names
141− | Just name' <- stripPrefix (fromMaybe "../" requirePath) name
135+checkImportPath name _ names
136+ | Just name' <- stripPrefix "../" name
142137 , name' `S.member` names = Right (ModuleIdentifier name' Regular)
143−checkImportPath _ name _ _ = Left name
138+checkImportPath name _ _ = Left name
144139
145140-- | Compute the dependencies of all elements in a module, and add them to the tree.
146141--
@@ -203,11 +198,34 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
203198
204199-- String literals include the quote chars
205200fromStringLiteral :: JSExpression -> Maybe String
206−fromStringLiteral (JSStringLiteral _ str) = Just $ trimStringQuotes str
201+fromStringLiteral (JSStringLiteral _ str) = Just $ strValue str
207202fromStringLiteral _ = Nothing
208203
209−trimStringQuotes :: String -> String
210−trimStringQuotes str = reverse $ drop 1 $ reverse $ drop 1 $ str
204+strValue :: String -> String
205+strValue str = go $ drop 1 str
206+ where
207+ go ('\\' : 'b' : xs) = '\b' : go xs
208+ go ('\\' : 'f' : xs) = '\f' : go xs
209+ go ('\\' : 'n' : xs) = '\n' : go xs
210+ go ('\\' : 'r' : xs) = '\r' : go xs
211+ go ('\\' : 't' : xs) = '\t' : go xs
212+ go ('\\' : 'v' : xs) = '\v' : go xs
213+ go ('\\' : '0' : xs) = '\0' : go xs
214+ go ('\\' : 'x' : a : b : xs) = chr (a' + b') : go xs
215+ where
216+ a' = 16 * digitToInt a
217+ b' = digitToInt b
218+ go ('\\' : 'u' : a : b : c : d : xs) = chr (a' + b' + c' + d') : go xs
219+ where
220+ a' = 16 * 16 * 16 * digitToInt a
221+ b' = 16 * 16 * digitToInt b
222+ c' = 16 * digitToInt c
223+ d' = digitToInt d
224+ go ('\\' : x : xs) = x : go xs
225+ go "\"" = ""
226+ go "'" = ""
227+ go (x : xs) = x : go xs
228+ go "" = ""
211229
212230commaList :: JSCommaList a -> [a]
213231commaList JSLNil = []
@@ -222,8 +240,8 @@ trailingCommaList (JSCTLNone l) = commaList l
222240--
223241-- Each type of module element is matched using pattern guards, and everything else is bundled into the
224242-- Other constructor.
225−toModule :: forall m. (MonadError ErrorMessage m) => Maybe FilePath -> S.Set String -> ModuleIdentifier -> JSAST -> m Module
226−toModule requirePath mids mid top
243+toModule :: forall m. (MonadError ErrorMessage m) => S.Set String -> ModuleIdentifier -> JSAST -> m Module
244+toModule mids mid top
227245 | JSAstProgram smts _ <- top = Module mid <$> traverse toModuleElement smts
228246 | otherwise = err InvalidTopLevel
229247 where
@@ -231,7 +249,7 @@ toModule requirePath mids mid top
231249
232250 toModuleElement :: JSStatement -> m ModuleElement
233251 toModuleElement stmt
234− | Just (importName, importPath) <- matchRequire requirePath mids mid stmt
252+ | Just (importName, importPath) <- matchRequire mids mid stmt
235253 = pure (Require stmt importName importPath)
236254 toModuleElement stmt
237255 | Just (exported, name, decl) <- matchMember stmt
@@ -291,12 +309,11 @@ getExportedIdentifiers mname top
291309
292310-- Matches JS statements like this:
293311-- var ModuleName = require("file");
294−matchRequire :: Maybe FilePath
295− -> S.Set String
312+matchRequire :: S.Set String
296313 -> ModuleIdentifier
297314 -> JSStatement
298315 -> Maybe (String, Either String ModuleIdentifier)
299−matchRequire requirePath mids mid stmt
316+matchRequire mids mid stmt
300317 | JSVariable _ jsInit _ <- stmt
301318 , [JSVarInitExpression var varInit] <- commaList jsInit
302319 , JSIdentifier _ importName <- var
@@ -304,7 +321,7 @@ matchRequire requirePath mids mid stmt
304321 , JSMemberExpression req _ argsE _ <- jsInitEx
305322 , JSIdentifier _ "require" <- req
306323 , [ Just importPath ] <- map fromStringLiteral (commaList argsE)
307− , importPath' <- checkImportPath requirePath importPath mid mids
324+ , importPath' <- checkImportPath importPath mid mids
308325 = Just (importName, importPath')
309326 | otherwise
310327 = Nothing
@@ -350,7 +367,7 @@ matchExportsAssignment stmt
350367 = Nothing
351368
352369extractLabel :: JSPropertyName -> Maybe String
353−extractLabel (JSPropertyString _ nm) = Just (trimStringQuotes nm)
370+extractLabel (JSPropertyString _ nm) = Just $ strValue nm
354371extractLabel (JSPropertyIdent _ nm) = Just nm
355372extractLabel _ = Nothing
356373
@@ -590,16 +607,15 @@ bundle :: (MonadError ErrorMessage m)
590607 -> [ModuleIdentifier] -- ^ Entry points. These module identifiers are used as the roots for dead-code elimination
591608 -> Maybe String -- ^ An optional main module.
592609 -> String -- ^ The namespace (e.g. PS).
593− -> Maybe FilePath -- ^ The require path prefix
594610 -> m String
595−bundle inputStrs entryPoints mainModule namespace requirePath = do
611+bundle inputStrs entryPoints mainModule namespace = do
596612 input <- forM inputStrs $ \(ident, js) -> do
597613 ast <- either (throwError . ErrorInModule ident . UnableToParseModule) pure $ parse js (moduleName ident)
598614 return (ident, ast)
599615
600616 let mids = S.fromList (map (moduleName . fst) input)
601617
602− modules <- traverse (fmap withDeps . uncurry (toModule requirePath mids)) input
618+ modules <- traverse (fmap withDeps . uncurry (toModule mids)) input
603619
604620 let compiled = compile modules entryPoints
605621 sorted = sortModules (filter (not . isModuleEmpty) compiled)
src/Language/PureScript/CodeGen.hs+8−20
@@ -1,20 +1,8 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−-- A collection of modules related to code generation:
13−--
14−-- [@Language.PureScript.CodeGen.JS@] Code generator for Javascript
15−--
16−-----------------------------------------------------------------------------
17−
18−module Language.PureScript.CodeGen (module C) where
19−
20−import Language.PureScript.CodeGen.JS as C
1+-- |
2+-- A collection of modules related to code generation:
3+--
4+-- [@Language.PureScript.CodeGen.JS@] Code generator for Javascript
5+--
6+module Language.PureScript.CodeGen (module C) where
7+
8+import Language.PureScript.CodeGen.JS as C
src/Language/PureScript/CodeGen/Cpp.hs+17−18
@@ -26,6 +26,8 @@ module Language.PureScript.CodeGen.Cpp
2626 , P.prettyPrintCpp
2727 ) where
2828
29+import Prelude.Compat
30+
2931import Data.Char (isLetter)
3032import Data.List
3133import Data.Function (on)
@@ -124,9 +126,6 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
124126 (supers, members) = span (C.__superclass_ `isPrefixOf`) (identToCpp <$> (fst $ unAbs e []))
125127 in return $ CppStruct className [CppEnum Nothing Nothing (sort supers ++ members)]
126128
127− declToCpp _ (_, Op _) (Var (_, _, Nothing, _) _) =
128− return CppNoOp -- skip operator aliases
129−
130129 declToCpp vqs (_, ident) (Abs (_, com, ty, _) arg body) = do
131130 fn <- if argcnt > 1 && CppTopLevel `elem` vqs
132131 then do
@@ -170,7 +169,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
170169 return (CppComment com fn)
171170 where
172171 ty' | Just t <- ty = Just t
173− | Just (t, _, _) <- M.lookup (mn, ident) (E.names env) = Just t
172+ | Just (t, _, _) <- M.lookup (Qualified (Just mn) ident) (E.names env) = Just t
174173 | otherwise = Nothing
175174 argcnt = maybe 0 countArgs ty'
176175 name = identToCpp ident
@@ -185,7 +184,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
185184 isIndexer :: Cpp -> Bool
186185 isIndexer (CppIndexer (CppStringLiteral _) (CppVar _)) = True
187186 isIndexer _ = False
188− classes = qualifiedToCpp (Ident . runProperName) . fst <$>
187+ classes = qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
189188 maybe [] extractConstraints ty'
190189 dictClasses = zip (CppVar . fst <$> arg' : args') classes
191190 convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
@@ -420,7 +419,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
420419 CppArrayLiteral <$> mapM valueToCpp xs
421420
422421 valueToCpp (Literal _ (ObjectLiteral ps)) =
423− CppObjectLiteral <$> sortBy (compare `on` fst) <$> mapM (sndM valueToCpp) ps
422+ CppObjectLiteral CppRecord <$> sortBy (compare `on` fst) <$> mapM (sndM valueToCpp) ps
424423
425424 valueToCpp (Accessor _ prop val) =
426425 CppIndexer <$> pure (CppStringLiteral prop) <*> valueToCpp val
@@ -431,7 +430,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
431430 updatedFields <- mapM (sndM valueToCpp) ps
432431 let origKeys = (allKeys ty) \\ (fst <$> updatedFields)
433432 origFields = (\key -> (key, CppIndexer (CppStringLiteral key) obj')) <$> origKeys
434− return $ CppObjectLiteral . sortBy (compare `on` fst) $ origFields ++ updatedFields
433+ return $ CppObjectLiteral CppRecord . sortBy (compare `on` fst) $ origFields ++ updatedFields
435434 where
436435 allKeys :: T.Type -> [String]
437436 allKeys (T.TypeApp (T.TypeConstructor _) r@(T.RCons {})) = fst <$> (fst $ T.rowToList r)
@@ -452,7 +451,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
452451 where
453452 arg' = identToCpp arg
454453 args' = identToCpp <$> (fst $ unAbs body [])
455− classes = qualifiedToCpp (Ident . runProperName) . fst <$>
454+ classes = qualifiedToCpp (Ident . runProperName) . T.constraintClass <$>
456455 maybe [] extractConstraints ty
457456 dictClasses = zip (CppVar <$> arg' : args') classes
458457 convertDictIndexers = everywhereOnCpp (dictIndexerToEnum dictClasses)
@@ -466,7 +465,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
466465 return $ CppApp (uncurried' $ qualifiedToCpp id ident) args'
467466 Var (_, _, _, Just IsTypeClassConstructor) (Qualified mn' (Ident classname)) ->
468467 let Just (_, constraints, fns) = findClass (Qualified mn' (ProperName classname)) in
469− return . CppObjectLiteral $
468+ return . CppObjectLiteral CppInstance $
470469 zip
471470 ((sort $ superClassDictionaryNames constraints) ++ (fst <$> fns))
472471 args'
@@ -485,7 +484,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
485484 return $ foldl (\fn a -> CppApp fn [a]) fn' curriedArgs
486485 where
487486 ty | (_, _, Just t, _) <- ann = Just t
488− | Just (t, _, _) <- M.lookup (mn', ident) (E.names env) = Just t
487+ | Just (t, _, _) <- M.lookup (Qualified (Just mn') ident) (E.names env) = Just t
489488 | otherwise = Nothing
490489 _ ->
491490 flip (foldl (\fn a -> CppApp fn [a])) args' <$> valueToCpp f
@@ -618,7 +617,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
618617 SumType ->
619618 [ CppIfElse
620619 (CppBinary
621− Equal
620+ EqualTo
622621 (CppIndexer
623622 (CppVar ctorKey)
624623 (CppCast dataType $ CppVar varName))
@@ -665,19 +664,19 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
665664 -------------------------------------------------------------------------------------------------
666665 literalToBinderCpp varName done (NumericLiteral num) =
667666 return [ CppIfElse
668− (CppBinary Equal (CppVar varName) (CppNumericLiteral num))
667+ (CppBinary EqualTo (CppVar varName) (CppNumericLiteral num))
669668 (CppBlock done)
670669 Nothing ]
671670
672671 literalToBinderCpp varName done (CharLiteral c) =
673672 return [ CppIfElse
674− (CppBinary Equal (CppVar varName) (CppCharLiteral c))
673+ (CppBinary EqualTo (CppVar varName) (CppCharLiteral c))
675674 (CppBlock done)
676675 Nothing ]
677676
678677 literalToBinderCpp varName done (StringLiteral str) =
679678 return [ CppIfElse
680− (CppBinary Equal (CppVar varName) (CppStringLiteral str))
679+ (CppBinary EqualTo (CppVar varName) (CppStringLiteral str))
681680 (CppBlock done)
682681 Nothing ]
683682
@@ -690,7 +689,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
690689 literalToBinderCpp varName done (BooleanLiteral False) =
691690 return [ CppIfElse
692691 (CppUnary
693− CppNot
692+ Not
694693 (CppVar varName))
695694 (CppBlock done)
696695 Nothing ]
@@ -722,7 +721,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
722721 (CppApp (CppVar "empty") [])
723722 n -> let var = CppCast arrayType $ CppVar varName
724723 in CppBinary
725− Equal
724+ EqualTo
726725 (CppBinary Dot var (CppApp (CppVar "size") []))
727726 (CppNumericLiteral (Left (fromIntegral n)))
728727 return [ CppIfElse cond (CppBlock cpp) Nothing ]
@@ -811,8 +810,8 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
811810 go _ = return []
812811
813812 allForeigns :: [(Ident, T.Type)]
814− allForeigns = map (\((_, ident), (ty, _, _)) -> (ident, ty)) .
815− filter (\((mn', _), (_, kind, _)) -> mn' == mn && kind == E.External) .
813+ allForeigns = map (\((Qualified _ ident), (ty, _, _)) -> (ident, ty)) .
814+ filter (\((Qualified mn' _), (_, kind, _)) -> mn' == Just mn && kind == E.External) .
816815 M.toList $ E.names env
817816
818817---------------------------------------------------------------------------------------------------
src/Language/PureScript/CodeGen/Cpp/AST.hs+22−21
@@ -18,12 +18,13 @@
1818
1919module Language.PureScript.CodeGen.Cpp.AST where
2020
21+import Prelude.Compat
22+
2123#if __GLASGOW_HASKELL__ < 710
2224import Control.Applicative (Applicative, (<$>), (<*>))
2325import Data.Traversable (traverse)
2426#endif
2527import Control.Monad.Identity
26−import Data.Data
2728import Language.PureScript.Comments
2829import Language.PureScript.CodeGen.Cpp.Types
2930import Language.PureScript.Traversals
@@ -31,33 +32,33 @@ import Language.PureScript.Traversals
3132-- |
3233-- Built-in unary operators
3334--
34−data CppUnaryOp
35+data UnaryOperator
3536 -- |
3637 -- Numeric negation
3738 --
38− = CppNegate
39+ = Negate
3940 -- |
4041 -- Boolean negation
4142 --
42− | CppNot
43+ | Not
4344 -- |
4445 -- Bitwise negation
4546 --
46− | CppBitwiseNot
47+ | BitwiseNot
4748 -- |
4849 -- Numeric unary \'plus\'
4950 --
50− | CppPositive
51+ | Positive
5152 -- |
5253 -- Constructor
5354 --
54− | CppNew
55− deriving (Show, Read, Eq)
55+ | New
56+ deriving (Show, Eq)
5657
5758-- |
5859-- Built-in binary operators
5960--
60−data BinaryOp
61+data BinaryOperator
6162 -- |
6263 -- Numeric addition
6364 --
@@ -85,11 +86,11 @@ data BinaryOp
8586 -- |
8687 -- Generic equality test
8788 --
88− | Equal
89+ | EqualTo
8990 -- |
9091 -- Generic inequality test
9192 --
92− | NotEqual
93+ | NotEqualTo
9394 -- |
9495 -- Numeric less-than
9596 --
@@ -97,7 +98,7 @@ data BinaryOp
9798 -- |
9899 -- Numeric less-than-or-equal
99100 --
100− | LessThanOrEqual
101+ | LessThanOrEqualTo
101102 -- |
102103 -- Numeric greater-than
103104 --
@@ -105,7 +106,7 @@ data BinaryOp
105106 -- |
106107 -- Numeric greater-than-or-equal
107108 --
108− | GreaterThanOrEqual
109+ | GreaterThanOrEqualTo
109110 -- |
110111 -- Boolean and
111112 --
@@ -135,7 +136,7 @@ data BinaryOp
135136 --
136137 | ShiftRight
137138 --
138− deriving (Show, Read, Eq)
139+ deriving (Show, Eq)
139140
140141-- |
141142-- Data type for simplified C++11 expressions
@@ -160,11 +161,11 @@ data Cpp
160161 -- |
161162 -- A unary operator application
162163 --
163− | CppUnary CppUnaryOp Cpp
164+ | CppUnary UnaryOperator Cpp
164165 -- |
165166 -- A binary operator application
166167 --
167− | CppBinary BinaryOp Cpp Cpp
168+ | CppBinary BinaryOperator Cpp Cpp
168169 -- |
169170 -- An array literal
170171 --
@@ -184,7 +185,7 @@ data Cpp
184185 -- |
185186 -- An object literal
186187 --
187− | CppObjectLiteral [(String, Cpp)]
188+ | CppObjectLiteral CppObjectType [(String, Cpp)]
188189 -- |
189190 -- An general property accessor expression (property, expr)
190191 --
@@ -281,7 +282,7 @@ data Cpp
281282 -- Commented C++11
282283 --
283284 | CppComment [Comment] Cpp
284− deriving (Show, Read, Eq)
285+ deriving (Show, Eq)
285286
286287--
287288-- Traversals
@@ -296,7 +297,7 @@ everywhereOnCpp f = go
296297 go (CppArrayLiteral cpp) = f (CppArrayLiteral (map go cpp))
297298 go (CppDataLiteral cpp) = f (CppDataLiteral (map go cpp))
298299 go (CppIndexer j1 j2) = f (CppIndexer (go j1) (go j2))
299− go (CppObjectLiteral cpp) = f (CppObjectLiteral (map (fmap go) cpp))
300+ go (CppObjectLiteral t cpp) = f (CppObjectLiteral t (map (fmap go) cpp))
300301 go (CppAccessor prop j) = f (CppAccessor (go prop) (go j))
301302 go (CppFunction name args rty qs j) = f (CppFunction name args rty qs (go j))
302303 go (CppLambda cps args rty j) = f (CppLambda cps args rty (go j))
@@ -327,7 +328,7 @@ everywhereOnCppTopDownM f = f >=> go
327328 go (CppArrayLiteral cpp) = CppArrayLiteral <$> traverse f' cpp
328329 go (CppDataLiteral cpp) = CppDataLiteral <$> traverse f' cpp
329330 go (CppIndexer j1 j2) = CppIndexer <$> f' j1 <*> f' j2
330− go (CppObjectLiteral cpp) = CppObjectLiteral <$> traverse (sndM f') cpp
331+ go (CppObjectLiteral t cpp) = CppObjectLiteral t <$> traverse (sndM f') cpp
331332 go (CppAccessor prop j) = CppAccessor prop <$> f' j
332333 go (CppFunction name args rty qs j) = CppFunction name args rty qs <$> f' j
333334 go (CppLambda cps args rty j) = CppLambda cps args rty <$> f' j
@@ -354,7 +355,7 @@ everythingOnCpp (<>) f = go
354355 go j@(CppArrayLiteral cpp) = foldl (<>) (f j) (map go cpp)
355356 go j@(CppDataLiteral cpp) = foldl (<>) (f j) (map go cpp)
356357 go j@(CppIndexer j1 j2) = f j <> go j1 <> go j2
357− go j@(CppObjectLiteral cpp) = foldl (<>) (f j) (map (go . snd) cpp)
358+ go j@(CppObjectLiteral _ cpp) = foldl (<>) (f j) (map (go . snd) cpp)
358359 go j@(CppAccessor j1 j2) = f j <> go j1 <> go j2
359360 go j@(CppFunction _ _ _ _ j1) = f j <> go j1
360361 go j@(CppLambda _ _ _ j1) = f j <> go j1
src/Language/PureScript/CodeGen/Cpp/Common.hs+4−2
@@ -17,9 +17,12 @@
1717
1818module Language.PureScript.CodeGen.Cpp.Common where
1919
20+import Prelude.Compat
21+
2022import Data.Char
2123import Data.List (intercalate)
2224
25+import Language.PureScript.Crash
2326import Language.PureScript.Names
2427
2528-- |
@@ -35,7 +38,7 @@ identToCpp :: Ident -> String
3538identToCpp (Ident name) | nameIsCppReserved name = '_' : name ++ "_"
3639identToCpp (Ident name@('$' : s)) | all isDigit s = name
3740identToCpp (Ident name) = concatMap identCharToString name
38−identToCpp (Op op) = concatMap identCharToString op
41+identToCpp (GenIdent _ _) = internalError "GenIdent in identToJs"
3942
4043-- |
4144-- Test if a string is a valid Cpp identifier without escaping.
@@ -126,7 +129,6 @@ nameIsCppReserved name =
126129 , "import"
127130 , "inline"
128131 , "int"
129− , "integer"
130132 , "list"
131133 , "long"
132134 , "mutable"
src/Language/PureScript/CodeGen/Cpp/File.hs+16−6
@@ -17,6 +17,8 @@
1717
1818module Language.PureScript.CodeGen.Cpp.File where
1919
20+import Prelude.Compat
21+
2022import Data.Maybe
2123
2224import Language.PureScript.CodeGen.Cpp.AST
@@ -50,9 +52,14 @@ toHeader = catMaybes . map go
5052 Nothing
5153 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty _))) =
5254 Just $ CppFunction name [] rty [] CppNoOp
55+
5356 -- Generate thunks for top-level values
54− go (CppVariableIntroduction (name, _) _ (Just _)) =
55− Just $ CppVariableIntroduction (name, Just $ CppAny [CppConst]) [CppExtern] Nothing
57+ go (CppVariableIntroduction (name, vty) _ (Just cpp)) =
58+ case cpp of
59+ CppObjectLiteral CppInstance vals ->
60+ Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) [] CppNoOp
61+ _ ->
62+ Just $ CppVariableIntroduction (name, vty) [CppExtern] Nothing
5663 go cpp@(CppStruct {}) =
5764 Just cpp
5865 go (CppComment comms cpp')
@@ -113,15 +120,18 @@ toBody = catMaybes . map go
113120 Nothing
114121 go (CppVariableIntroduction (name, _) _ (Just (CppLambda _ [] rty body))) =
115122 Just $ CppFunction name [] rty [] body
116− -- Generate thunks for top-level values
117− go (CppVariableIntroduction (name, _) _ (Just cpp)) =
118− Just $ CppVariableIntroduction (name, Just $ CppAny [CppConst]) [] (Just lambda)
123+ go (CppVariableIntroduction (name, vty) _ (Just cpp)) =
124+ case cpp of
125+ CppObjectLiteral CppInstance vals ->
126+ Just $ CppFunction name [("", Just thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) [] block
127+ _ ->
128+ Just $ CppVariableIntroduction (name, vty) [] (Just lambda)
119129 where
120130 val = CppVariableIntroduction ("$value$", Just $ CppAny [CppConst]) [CppStatic] (Just $ addCaptures cpp)
121131 block = CppBlock [val, CppReturn (CppVar "$value$")]
122132 lambda = CppLambda [] [("", Just $ thunkMarkerType)] (Just $ CppAny [CppConst, CppRef]) block
123133 addCaptures :: Cpp -> Cpp
124− addCaptures (CppObjectLiteral objs) = CppObjectLiteral (objlam <$> objs)
134+ addCaptures (CppObjectLiteral t objs) = CppObjectLiteral t (objlam <$> objs)
125135 where
126136 objlam :: (String, Cpp) -> (String, Cpp)
127137 objlam (name', (CppLambda _ args rty body)) = (name' , CppLambda [] args rty $ addCaptures body)
src/Language/PureScript/CodeGen/Cpp/Optimizer.hs+3−1
@@ -38,6 +38,8 @@ module Language.PureScript.CodeGen.Cpp.Optimizer (
3838 optimize
3939) where
4040
41+import Prelude.Compat
42+
4143#if __GLASGOW_HASKELL__ < 710
4244import Control.Applicative (Applicative)
4345#endif
@@ -79,7 +81,7 @@ optimize' cpp = do
7981 , etaConvert
8082 , evaluateIifes
8183 , inlineVariables
82− , inlineValues
84+ , inlineCommonValues
8385 , inlineOperator (C.prelude, (C.$)) $ \f x -> CppApp f [x]
8486 , inlineOperator (C.prelude, (C.#)) $ \x f -> CppApp f [x]
8587 , inlineOperator (C.dataArrayUnsafe, C.unsafeIndex) $ flip CppIndexer
src/Language/PureScript/CodeGen/Cpp/Optimizer/Blocks.hs+12−10
@@ -19,6 +19,8 @@ module Language.PureScript.CodeGen.Cpp.Optimizer.Blocks
1919 , collapseIfElses
2020 ) where
2121
22+import Prelude.Compat
23+
2224import Language.PureScript.CodeGen.Cpp.AST
2325import qualified Language.PureScript.Constants as C
2426
@@ -49,29 +51,29 @@ collapseIfElses = everywhereOnCpp collapse
4951 collapse :: Cpp -> Cpp
5052 collapse (CppBlock cpps) = CppBlock (go cpps)
5153 where
52− go (st'@(CppIfElse (CppBinary Equal a _) _ Nothing) : sts') =
54+ go (st'@(CppIfElse (CppBinary EqualTo lhs _) _ Nothing) : sts') =
5355 if length (fst cpps') > 1
54− then CppSwitch a (mkCases <$> fst cpps') : snd cpps'
56+ then CppSwitch lhs (mkCases <$> fst cpps') : snd cpps'
5557 else st' : sts'
5658 where
57− cpps' = span (isIntEq a) (st' : sts')
59+ cpps' = span (isIntEq lhs) (st' : sts')
5860 isIntEq :: Cpp -> Cpp -> Bool
59− isIntEq a (CppIfElse (CppBinary Equal a' (CppNumericLiteral (Left _))) (CppBlock [CppReturn _]) Nothing)
61+ isIntEq a (CppIfElse (CppBinary EqualTo a' (CppNumericLiteral (Left _))) (CppBlock [CppReturn _]) Nothing)
6062 | a == a' = True
61− isIntEq a (CppIfElse (CppBinary Equal a' (CppCharLiteral _)) (CppBlock [CppReturn _]) Nothing)
63+ isIntEq a (CppIfElse (CppBinary EqualTo a' (CppCharLiteral _)) (CppBlock [CppReturn _]) Nothing)
6264 | a == a' = True
63− isIntEq a (CppIfElse (CppBinary Equal a' (CppBooleanLiteral _)) (CppBlock [CppReturn _]) Nothing)
65+ isIntEq a (CppIfElse (CppBinary EqualTo a' (CppBooleanLiteral _)) (CppBlock [CppReturn _]) Nothing)
6466 | a == a' = True
6567 isIntEq _ _ = False
6668 mkCases :: Cpp -> (Cpp, Cpp)
67− mkCases (CppIfElse (CppBinary Equal _ b') (CppBlock [body]) Nothing) = (b', body)
68− mkCases (CppIfElse (CppUnary CppNot _) (CppBlock [body]) Nothing) = (CppBooleanLiteral False, body)
69+ mkCases (CppIfElse (CppBinary EqualTo _ b') (CppBlock [body]) Nothing) = (b', body)
70+ mkCases (CppIfElse (CppUnary Not _) (CppBlock [body]) Nothing) = (CppBooleanLiteral False, body)
6971 mkCases (CppIfElse _ (CppBlock [body]) Nothing) = (CppBooleanLiteral True, body)
7072 mkCases _ = error ""
7173 go ((CppIfElse cond1 body1 Nothing) : (CppIfElse cond2 body2 Nothing) : _)
7274 | returns body1 && returns body2 &&
73− (CppUnary CppNot cond1 == cond2 ||
74− CppUnary CppNot cond2 == cond1) = [CppIfElse cond1 body1 (Just body2)]
75+ (CppUnary Not cond1 == cond2 ||
76+ CppUnary Not cond2 == cond1) = [CppIfElse cond1 body1 (Just body2)]
7577 where
7678 returns :: Cpp -> Bool
7779 returns (CppBlock rets@(_:_)) | CppReturn{} <- last rets = True
src/Language/PureScript/CodeGen/Cpp/Optimizer/Common.hs+16
@@ -15,6 +15,8 @@
1515
1616module Language.PureScript.CodeGen.Cpp.Optimizer.Common where
1717
18+import Prelude.Compat
19+
1820import Data.Maybe (fromMaybe)
1921
2022import Language.PureScript.CodeGen.Cpp.AST
@@ -73,3 +75,17 @@ isUpdated var1 = everythingOnCpp (||) check
7375removeFromBlock :: ([Cpp] -> [Cpp]) -> Cpp -> Cpp
7476removeFromBlock go (CppBlock sts) = CppBlock (go sts)
7577removeFromBlock _ cpp = cpp
78+
79+isFn :: (String, String) -> Cpp -> Bool
80+isFn (moduleName, fnName) (CppAccessor (CppVar x) (CppVar y)) =
81+ x == fnName && y == moduleName
82+isFn (moduleName, fnName) (CppIndexer (CppStringLiteral x) (CppVar y)) =
83+ x == fnName && y == moduleName
84+isFn _ _ = False
85+
86+isDict :: (String, String) -> Cpp -> Bool
87+isDict (moduleName, dictName) (CppAccessor (CppVar x) (CppVar y)) = x == dictName && y == moduleName
88+isDict _ _ = False
89+
90+isDict' :: [(String, String)] -> Cpp -> Bool
91+isDict' xs cpp = any (`isDict` cpp) xs
src/Language/PureScript/CodeGen/Cpp/Optimizer/Inliner.hs+197−142
@@ -12,28 +12,25 @@
1212-- This module provides basic inlining capabilities
1313--
1414-----------------------------------------------------------------------------
15+module Language.PureScript.CodeGen.Cpp.Optimizer.Inliner
16+ ( inlineVariables
17+ , inlineCommonValues
18+ , inlineOperator
19+ , inlineCommonOperators
20+ , inlineFnComposition
21+ , etaConvert
22+ , unThunk
23+ , evaluateIifes
24+ ) where
25+
26+import Prelude.Compat
1527
16−{-# LANGUAGE CPP #-}
17−
18−module Language.PureScript.CodeGen.Cpp.Optimizer.Inliner (
19− inlineVariables,
20− inlineValues,
21− inlineOperator,
22− inlineCommonOperators,
23− inlineFnComposition,
24− etaConvert,
25− unThunk,
26− evaluateIifes
27−) where
28−
29−#if __GLASGOW_HASKELL__ < 710
30−import Control.Applicative (Applicative)
31−#endif
3228import Control.Monad.Supply.Class (MonadSupply, freshName)
33−import Language.PureScript.CodeGen.Cpp.Types
29+
3430import Language.PureScript.CodeGen.Cpp.AST
3531import Language.PureScript.CodeGen.Cpp.Common
3632import Language.PureScript.CodeGen.Cpp.Optimizer.Common
33+import Language.PureScript.CodeGen.Cpp.Types
3734import Language.PureScript.Names
3835import qualified Language.PureScript.Constants as C
3936
@@ -99,36 +96,34 @@ inlineVariables = everywhereOnCpp $ removeFromBlock go
9996 go (map (replaceIdent var cpp) sts)
10097 go (s:sts) = s : go sts
10198
102−inlineValues :: Cpp -> Cpp
103−inlineValues = everywhereOnCpp convert
99+inlineCommonValues :: Cpp -> Cpp
100+inlineCommonValues = everywhereOnCpp convert
104101 where
105102 convert :: Cpp -> Cpp
106− convert (CppApp fn [dict]) | isDict semiringNumber dict && isFn fnZero fn = CppNumericLiteral (Left 0)
107− | isDict semiringNumber dict && isFn fnOne fn = CppNumericLiteral (Left 1)
108− | isDict semiringInt dict && isFn fnZero fn = CppNumericLiteral (Left 0)
109− | isDict semiringInt dict && isFn fnOne fn = CppNumericLiteral (Left 1)
110− | isDict boundedBoolean dict && isFn fnBottom fn = CppBooleanLiteral False
111− | isDict boundedBoolean dict && isFn fnTop fn = CppBooleanLiteral True
103+ convert (CppApp fn [dict])
104+ | isDict' [semiringNumber, semiringInt] dict && isFn fnZero fn = CppNumericLiteral (Left 0)
105+ | isDict' [semiringNumber, semiringInt] dict && isFn fnOne fn = CppNumericLiteral (Left 1)
106+ | isDict boundedBoolean dict && isFn fnBottom fn = CppBooleanLiteral False
107+ | isDict boundedBoolean dict && isFn fnTop fn = CppBooleanLiteral True
112108 convert (CppApp fn [dict, x, y])
113109 | isDict semiringInt dict && isFn fnAdd fn = CppBinary Add x y
114110 | isDict semiringInt dict && isFn fnMultiply fn = CppBinary Multiply x y
115− | isDict moduloSemiringInt dict && isFn fnDivide fn = CppBinary Divide x y
111+ | isDict euclideanRingInt dict && isFn fnDivide fn = CppBinary Divide x y
116112 | isDict ringInt dict && isFn fnSubtract fn = CppBinary Subtract x y
117113 convert (CppApp (CppApp (CppApp fn [dict]) [x]) [y])
118114 | isDict semiringInt dict && isFn fnAdd fn = CppBinary Add x y
119115 | isDict semiringInt dict && isFn fnMultiply fn = CppBinary Multiply x y
120− | isDict moduloSemiringInt dict && isFn fnDivide fn = CppBinary Divide x y
116+ | isDict euclideanRingInt dict && isFn fnDivide fn = CppBinary Divide x y
121117 | isDict ringInt dict && isFn fnSubtract fn = CppBinary Subtract x y
122−
123118 convert other = other
124− fnZero = (C.prelude, C.zero)
125− fnOne = (C.prelude, C.one)
126− fnBottom = (C.prelude, C.bottom)
127− fnTop = (C.prelude, C.top)
128− fnAdd = (C.prelude, (C.+))
129− fnDivide = (C.prelude, (C./))
130− fnMultiply = (C.prelude, (C.*))
131− fnSubtract = (C.prelude, (C.-))
119+ fnZero = (C.dataSemiring, C.zero)
120+ fnOne = (C.dataSemiring, C.one)
121+ fnBottom = (C.dataBounded, C.bottom)
122+ fnTop = (C.dataBounded, C.top)
123+ fnAdd = (C.dataSemiring, C.add)
124+ fnDivide = (C.dataEuclideanRing, C.div)
125+ fnMultiply = (C.dataSemiring, C.mul)
126+ fnSubtract = (C.dataRing, C.sub)
132127
133128inlineOperator :: (String, String) -> (Cpp -> Cpp -> Cpp) -> Cpp -> Cpp
134129inlineOperator (m, op) f = everywhereOnCpp convert
@@ -137,49 +132,60 @@ inlineOperator (m, op) f = everywhereOnCpp convert
137132 convert (CppApp op' [x, y]) | isOp op' = f x y
138133 convert (CppApp (CppApp op' [x]) [y]) | isOp op' = f x y
139134 convert other = other
140− isOp (CppAccessor (CppVar longForm) (CppVar m')) = m == m' && longForm == identToCpp (Op op)
135+ isOp (CppAccessor (CppVar longForm) (CppVar m')) = m == m' && longForm == identToCpp (Ident op)
141136 isOp (CppIndexer (CppStringLiteral op') (CppVar m')) = m == m' && op == op'
142137 isOp _ = False
143138
144139inlineCommonOperators :: Cpp -> Cpp
145140inlineCommonOperators = applyAll $
146− [ binary semiringNumber (C.+) Add
147− , binary semiringNumber (C.*) Multiply
148−
149− , binary ringNumber (C.-) Subtract
150− , unary ringNumber C.negate CppNegate
151− , binary ringInt (C.-) Subtract
152− , unary ringInt C.negate CppNegate
153−
154− , binary moduloSemiringNumber (C./) Divide
155− , binary moduloSemiringInt C.mod Modulus
156−
157− , binary eqNumber (C.==) Equal
158− , binary eqNumber (C./=) NotEqual
159− , binary eqInt (C.==) Equal
160− , binary eqInt (C./=) NotEqual
161− , binary eqString (C.==) Equal
162− , binary eqString (C./=) NotEqual
163− , binary eqBoolean (C.==) Equal
164− , binary eqBoolean (C./=) NotEqual
165−
166− , binary ordNumber (C.<) LessThan
167− , binary ordNumber (C.>) GreaterThan
168− , binary ordNumber (C.<=) LessThanOrEqual
169− , binary ordNumber (C.>=) GreaterThanOrEqual
170− , binary ordInt (C.<) LessThan
171− , binary ordInt (C.>) GreaterThan
172− , binary ordInt (C.<=) LessThanOrEqual
173− , binary ordInt (C.>=) GreaterThanOrEqual
174−
175− , binary semigroupString (C.<>) Add
176− , binary semigroupString (C.++) Add
177−
178− , binary booleanAlgebraBoolean (C.&&) And
179− , binary booleanAlgebraBoolean (C.||) Or
180− , binaryFunction booleanAlgebraBoolean C.conj And
181− , binaryFunction booleanAlgebraBoolean C.disj Or
182− , unary booleanAlgebraBoolean C.not CppNot
141+ [ binary semiringNumber opAdd Add
142+ , binary semiringNumber opMul Multiply
143+
144+ , binary ringNumber opSub Subtract
145+ , unary ringNumber opNegate Negate
146+ , binary ringInt opSub Subtract
147+ , unary ringInt opNegate Negate
148+
149+ , binary euclideanRingNumber opDiv Divide
150+ , binary euclideanRingInt opMod Modulus
151+
152+ , binary eqNumber opEq EqualTo
153+ , binary eqNumber opNotEq NotEqualTo
154+ , binary eqInt opEq EqualTo
155+ , binary eqInt opNotEq NotEqualTo
156+ , binary eqString opEq EqualTo
157+ , binary eqString opNotEq NotEqualTo
158+ , binary eqChar opEq EqualTo
159+ , binary eqChar opNotEq NotEqualTo
160+ , binary eqBoolean opEq EqualTo
161+ , binary eqBoolean opNotEq NotEqualTo
162+
163+ , binary ordBoolean opLessThan LessThan
164+ , binary ordBoolean opLessThanOrEq LessThanOrEqualTo
165+ , binary ordBoolean opGreaterThan GreaterThan
166+ , binary ordBoolean opGreaterThanOrEq GreaterThanOrEqualTo
167+ , binary ordChar opLessThan LessThan
168+ , binary ordChar opLessThanOrEq LessThanOrEqualTo
169+ , binary ordChar opGreaterThan GreaterThan
170+ , binary ordChar opGreaterThanOrEq GreaterThanOrEqualTo
171+ , binary ordInt opLessThan LessThan
172+ , binary ordInt opLessThanOrEq LessThanOrEqualTo
173+ , binary ordInt opGreaterThan GreaterThan
174+ , binary ordInt opGreaterThanOrEq GreaterThanOrEqualTo
175+ , binary ordNumber opLessThan LessThan
176+ , binary ordNumber opLessThanOrEq LessThanOrEqualTo
177+ , binary ordNumber opGreaterThan GreaterThan
178+ , binary ordNumber opGreaterThanOrEq GreaterThanOrEqualTo
179+ , binary ordString opLessThan LessThan
180+ , binary ordString opLessThanOrEq LessThanOrEqualTo
181+ , binary ordString opGreaterThan GreaterThan
182+ , binary ordString opGreaterThanOrEq GreaterThanOrEqualTo
183+
184+ , binary semigroupString opAppend Add
185+
186+ , binary heytingAlgebraBoolean opConj And
187+ , binary heytingAlgebraBoolean opDisj Or
188+ , unary heytingAlgebraBoolean opNot Not
183189
184190 , binary' C.dataIntBits (C..|.) BitwiseOr
185191 , binary' C.dataIntBits (C..&.) BitwiseAnd
@@ -187,43 +193,33 @@ inlineCommonOperators = applyAll $
187193 , binary' C.dataIntBits C.shl ShiftLeft
188194 , binary' C.dataIntBits C.shr ShiftRight
189195 -- , binary' C.dataIntBits C.zshr ZeroFillShiftRight
190− , unary' C.dataIntBits C.complement CppBitwiseNot
191− ] -- ++ -- DISABLE mkFn/runFn inlining
196+ , unary' C.dataIntBits C.complement BitwiseNot
197+ ] ++
198+ []
192199 -- [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
193200 where
194− binary :: (String, String) -> String -> BinaryOp -> Cpp -> Cpp
195− binary dict opString op = everywhereOnCpp convert
201+ binary :: (String, String) -> (String, String) -> BinaryOperator -> Cpp -> Cpp
202+ binary dict fns op = everywhereOnCpp convert
196203 where
197204 convert :: Cpp -> Cpp
198− convert (CppApp fn [dict', CppStringLiteral x, CppStringLiteral y])
199− | isDict dict dict' && isPreludeFn opString fn = CppStringLiteral (x ++ y)
200− convert (CppApp fn [dict', x, y]) | isDict dict dict' && isPreludeFn opString fn = CppBinary op x y
201− convert (CppApp (CppApp (CppApp fn [dict']) [CppStringLiteral x]) [CppStringLiteral y])
202− | isDict dict dict' && isPreludeFn opString fn = CppStringLiteral (x ++ y)
203− convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isDict dict dict' && isPreludeFn opString fn = CppBinary op x y
205+ convert (CppApp fn [dict', x, y]) | isDict dict dict' && isFn fns fn = CppBinary op x y
206+ convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isDict dict dict' && isFn fns fn = CppBinary op x y
204207 convert other = other
205− binary' :: String -> String -> BinaryOp -> Cpp -> Cpp
208+ binary' :: String -> String -> BinaryOperator -> Cpp -> Cpp
206209 binary' moduleName opString op = everywhereOnCpp convert
207210 where
208211 convert :: Cpp -> Cpp
209212 convert (CppApp fn [x, y]) | isFn (moduleName, opString) fn = CppBinary op x y
210213 convert (CppApp (CppApp fn [x]) [y]) | isFn (moduleName, opString) fn = CppBinary op x y
211214 convert other = other
212− binaryFunction :: (String, String) -> String -> BinaryOp -> Cpp -> Cpp
213− binaryFunction dict fnName op = everywhereOnCpp convert
215+ unary :: (String, String) -> (String, String) -> UnaryOperator -> Cpp -> Cpp
216+ unary dicts fns op = everywhereOnCpp convert
214217 where
215218 convert :: Cpp -> Cpp
216− convert (CppApp fn [dict', x, y]) | isPreludeFn fnName fn && isDict dict dict' = CppBinary op x y
217− convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isPreludeFn fnName fn && isDict dict dict' = CppBinary op x y
219+ convert (CppApp fn [dict', x]) | isDict dicts dict' && isFn fns fn = CppUnary op x
220+ convert (CppApp (CppApp fn [dict']) [x]) | isDict dicts dict' && isFn fns fn = CppUnary op x
218221 convert other = other
219− unary :: (String, String) -> String -> CppUnaryOp -> Cpp -> Cpp
220− unary dict fnName op = everywhereOnCpp convert
221− where
222− convert :: Cpp -> Cpp
223− convert (CppApp fn [dict', x]) | isPreludeFn fnName fn && isDict dict dict' = CppUnary op x
224− convert (CppApp (CppApp fn [dict']) [x]) | isPreludeFn fnName fn && isDict dict dict' = CppUnary op x
225− convert other = other
226− unary' :: String -> String -> CppUnaryOp -> Cpp -> Cpp
222+ unary' :: String -> String -> UnaryOperator -> Cpp -> Cpp
227223 unary' moduleName fnName op = everywhereOnCpp convert
228224 where
229225 convert :: Cpp -> Cpp
@@ -233,8 +229,8 @@ inlineCommonOperators = applyAll $
233229 -- mkFn 0 = everywhereOnCpp convert
234230 -- where
235231 -- convert :: Cpp -> Cpp
236− -- convert (CppApp mkFnN [CppLambda caps [_] _ (CppBlock cpp)]) | isNFn C.mkFn 0 mkFnN =
237− -- CppLambda caps [] Nothing (CppBlock cpp)
232+ -- convert (CppApp mkFnN [CppLambda _ [_] _ (CppBlock cpp)]) | isNFn C.mkFn 0 mkFnN =
233+ -- CppLambda [CppCaptureAll] [] Nothing (CppBlock cpp)
238234 -- convert other = other
239235 -- mkFn n = everywhereOnCpp convert
240236 -- where
@@ -244,14 +240,14 @@ inlineCommonOperators = applyAll $
244240 -- Just (args, cpp) -> CppLambda [CppCaptureAll] args Nothing (CppBlock cpp)
245241 -- Nothing -> orig
246242 -- convert other = other
247− -- collectArgs :: Int -> [(String, Maybe CppType)] -> Cpp -> Maybe ([(String, Maybe CppType)], [Cpp])
243+ -- collectArgs :: Int -> [String] -> Cpp -> Maybe ([String], [Cpp])
248244 -- collectArgs 1 acc (CppLambda _ [oneArg] _ (CppBlock cpp)) | length acc == n - 1 = Just (reverse (oneArg : acc), cpp)
249245 -- collectArgs m acc (CppLambda _ [oneArg] _ (CppBlock [CppReturn ret])) = collectArgs (m - 1) (oneArg : acc) ret
250246 -- collectArgs _ _ _ = Nothing
251247 --
252248 -- isNFn :: String -> Int -> Cpp -> Bool
253249 -- isNFn prefix n (CppVar name) = name == (prefix ++ show n)
254− -- isNFn prefix n (CppAccessor (CppVar name) (CppVar dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
250+ -- isNFn prefix n (CppAccessor _ name (CppVar dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
255251 -- isNFn _ _ _ = False
256252 --
257253 -- runFn :: Int -> Cpp -> Cpp
@@ -267,78 +263,137 @@ inlineCommonOperators = applyAll $
267263
268264-- (f <<< g $ x) = f (g x)
269265-- (f <<< g) = \x -> f (g x)
270−inlineFnComposition :: (Applicative m, MonadSupply m) => Cpp -> m Cpp
266+inlineFnComposition :: (MonadSupply m) => Cpp -> m Cpp
271267inlineFnComposition = everywhereOnCppTopDownM convert
272268 where
273269 convert :: (MonadSupply m) => Cpp -> m Cpp
274− convert (CppApp fn [dict', x, y]) | isFnCompose dict' fn = do
275− arg <- freshName
276− return $ CppLambda [CppCaptureAll] [(arg, Just (CppAny [CppConst, CppRef]))] (Just $ CppAny []) (CppBlock [CppReturn $ CppApp x [CppApp y [CppVar arg]]])
277− convert (CppApp (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) [z]) | isFnCompose dict' fn =
278− return $ CppApp x [CppApp y [z]]
279− convert (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) | isFnCompose dict' fn = do
280− arg <- freshName
281− return $ CppLambda [CppCaptureAll] [(arg, Just (CppAny [CppConst, CppRef]))] (Just $ CppAny []) (CppBlock [CppReturn $ CppApp x [CppApp y [CppVar arg]]])
270+ convert (CppApp fn [dict', x, y, z])
271+ | isFnCompose dict' fn = return $ CppApp x [CppApp y [z]]
272+ | isFnComposeFlipped dict' fn = return $ CppApp y [CppApp x [z]]
273+ convert (CppApp (CppApp (CppApp (CppApp fn [dict']) [x]) [y]) [z])
274+ | isFnCompose dict' fn = return $ CppApp x [CppApp y [z]]
275+ | isFnComposeFlipped dict' fn = return $ CppApp y [CppApp x [z]]
276+ convert (CppApp fn [dict', x, y])
277+ | isFnCompose dict' fn = do
278+ arg <- freshName
279+ return $ CppLambda [CppCaptureAll] [(arg, constAnyRef)] Nothing (CppBlock [CppReturn $ CppApp x [CppApp y [CppVar arg]]])
280+ | isFnComposeFlipped dict' fn = do
281+ arg <- freshName
282+ return $ CppLambda [CppCaptureAll] [(arg, constAnyRef)] Nothing (CppBlock [CppReturn $ CppApp y [CppApp x [CppVar arg]]])
282283 convert other = return other
283284 isFnCompose :: Cpp -> Cpp -> Bool
284− isFnCompose dict' fn = isDict semigroupoidFn dict' && (isPreludeFn (C.<<<) fn || isPreludeFn (C.compose) fn)
285−
286−isDict :: (String, String) -> Cpp -> Bool
287−isDict (moduleName, dictName) (CppAccessor (CppVar x) (CppVar y)) = x == dictName && y == moduleName
288−isDict _ _ = False
289−
290−isFn :: (String, String) -> Cpp -> Bool
291−isFn (moduleName, fnName) (CppAccessor (CppVar x) (CppVar y)) = x == (identToCpp (Ident fnName)) && y == moduleName
292−isFn (moduleName, fnName) (CppIndexer (CppStringLiteral x) (CppVar y)) = x == fnName && y == moduleName
293−isFn _ _ = False
294−
295−isPreludeFn :: String -> Cpp -> Bool
296−isPreludeFn fnName = isFn (C.prelude, fnName)
285+ isFnCompose dict' fn = isDict semigroupoidFn dict' && isFn fnCompose fn
286+ isFnComposeFlipped :: Cpp -> Cpp -> Bool
287+ isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isFn fnComposeFlipped fn
288+ fnCompose :: (String, String)
289+ fnCompose = (C.controlSemigroupoid, C.compose)
290+ fnComposeFlipped :: (String, String)
291+ fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
297292
298293semiringNumber :: (String, String)
299−semiringNumber = (C.prelude, C.semiringNumber)
294+semiringNumber = (C.dataSemiring, C.semiringNumber)
300295
301296semiringInt :: (String, String)
302−semiringInt = (C.prelude, C.semiringInt)
297+semiringInt = (C.dataSemiring, C.semiringInt)
303298
304299ringNumber :: (String, String)
305−ringNumber = (C.prelude, C.ringNumber)
300+ringNumber = (C.dataRing, C.ringNumber)
306301
307302ringInt :: (String, String)
308−ringInt = (C.prelude, C.ringInt)
303+ringInt = (C.dataRing, C.ringInt)
309304
310−moduloSemiringNumber :: (String, String)
311−moduloSemiringNumber = (C.prelude, C.moduloSemiringNumber)
305+euclideanRingNumber :: (String, String)
306+euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
312307
313−moduloSemiringInt :: (String, String)
314−moduloSemiringInt = (C.prelude, C.moduloSemiringInt)
308+euclideanRingInt :: (String, String)
309+euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
315310
316311eqNumber :: (String, String)
317−eqNumber = (C.prelude, C.eqNumber)
312+eqNumber = (C.dataEq, C.eqNumber)
318313
319314eqInt :: (String, String)
320−eqInt = (C.prelude, C.eqInt)
315+eqInt = (C.dataEq, C.eqInt)
321316
322317eqString :: (String, String)
323−eqString = (C.prelude, C.eqNumber)
318+eqString = (C.dataEq, C.eqString)
319+
320+eqChar :: (String, String)
321+eqChar = (C.dataEq, C.eqChar)
324322
325323eqBoolean :: (String, String)
326−eqBoolean = (C.prelude, C.eqNumber)
324+eqBoolean = (C.dataEq, C.eqBoolean)
325+
326+ordBoolean :: (String, String)
327+ordBoolean = (C.dataOrd, C.ordBoolean)
327328
328329ordNumber :: (String, String)
329−ordNumber = (C.prelude, C.ordNumber)
330+ordNumber = (C.dataOrd, C.ordNumber)
330331
331332ordInt :: (String, String)
332−ordInt = (C.prelude, C.ordInt)
333+ordInt = (C.dataOrd, C.ordInt)
334+
335+ordString :: (String, String)
336+ordString = (C.dataOrd, C.ordString)
337+
338+ordChar :: (String, String)
339+ordChar = (C.dataOrd, C.ordChar)
333340
334341semigroupString :: (String, String)
335−semigroupString = (C.prelude, C.semigroupString)
342+semigroupString = (C.dataSemigroup, C.semigroupString)
336343
337344boundedBoolean :: (String, String)
338−boundedBoolean = (C.prelude, C.boundedBoolean)
345+boundedBoolean = (C.dataBounded, C.boundedBoolean)
339346
340−booleanAlgebraBoolean :: (String, String)
341−booleanAlgebraBoolean = (C.prelude, C.booleanAlgebraBoolean)
347+heytingAlgebraBoolean :: (String, String)
348+heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
342349
343350semigroupoidFn :: (String, String)
344−semigroupoidFn = (C.prelude, C.semigroupoidFn)
351+semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
352+
353+opAdd :: (String, String)
354+opAdd = (C.dataSemiring, C.add)
355+
356+opMul :: (String, String)
357+opMul = (C.dataSemiring, C.mul)
358+
359+opEq :: (String, String)
360+opEq = (C.dataEq, C.eq)
361+
362+opNotEq :: (String, String)
363+opNotEq = (C.dataEq, C.notEq)
364+
365+opLessThan :: (String, String)
366+opLessThan = (C.dataOrd, C.lessThan)
367+
368+opLessThanOrEq :: (String, String)
369+opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
370+
371+opGreaterThan :: (String, String)
372+opGreaterThan = (C.dataOrd, C.greaterThan)
373+
374+opGreaterThanOrEq :: (String, String)
375+opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
376+
377+opAppend :: (String, String)
378+opAppend = (C.dataSemigroup, C.append)
379+
380+opSub :: (String, String)
381+opSub = (C.dataRing, C.sub)
382+
383+opNegate :: (String, String)
384+opNegate = (C.dataRing, C.negate)
385+
386+opDiv :: (String, String)
387+opDiv = (C.dataEuclideanRing, C.div)
388+
389+opMod :: (String, String)
390+opMod = (C.dataEuclideanRing, C.mod)
391+
392+opConj :: (String, String)
393+opConj = (C.dataHeytingAlgebra, C.conj)
394+
395+opDisj :: (String, String)
396+opDisj = (C.dataHeytingAlgebra, C.disj)
397+
398+opNot :: (String, String)
399+opNot = (C.dataHeytingAlgebra, C.not)
src/Language/PureScript/CodeGen/Cpp/Optimizer/MagicDo.hs+77−42
@@ -13,21 +13,22 @@
1313-- and bind for the Eff monad, as well as some of its actions.
1414--
1515-----------------------------------------------------------------------------
16+module Language.PureScript.CodeGen.Cpp.Optimizer.MagicDo (magicDo) where
1617
17−module Language.PureScript.CodeGen.Cpp.Optimizer.MagicDo (
18− magicDo
19−) where
18+import Prelude.Compat
19+
20+import Data.List (nub)
21+import Data.Maybe (fromJust, isJust)
2022
2123import Language.PureScript.CodeGen.Cpp.AST
22−import Language.PureScript.CodeGen.Cpp.Common
24+import Language.PureScript.CodeGen.Cpp.Optimizer.Common
2325import Language.PureScript.CodeGen.Cpp.Types
24−import Language.PureScript.Names
2526import Language.PureScript.Options
2627import qualified Language.PureScript.Constants as C
2728
2829magicDo :: Options -> Cpp -> Cpp
2930magicDo opts | optionsNoMagicDo opts = id
30− | otherwise = magicDo'
31+ | otherwise = {- inlineST . -} magicDo' -- TODO: fix and test with Collatz.purs
3132
3233-- |
3334-- Inline type class dictionaries for >>= and return for the Eff monad
@@ -52,59 +53,48 @@ magicDo' = everywhereOnCpp undo . everywhereOnCppTopDown convert
5253 fnName = "__do"
5354 -- Desugar monomorphic calls to >>= and return for the Eff monad
5455 convert :: Cpp -> Cpp
55− -- Desugar return
56− convert (CppApp (CppApp ret [effDict, val]) []) | isRetPoly ret && isEffDict C.monadEffDictionary effDict = val
57− convert (CppApp (CppApp ret [val]) []) | isReturn ret = val
58− -- Desugar pure
59− convert (CppApp (CppApp pure' [effDict, val]) []) | isPurePoly pure' && isEffDict C.applicativeEffDictionary effDict = val
56+ -- Desugar pure & return
57+ convert (CppApp (CppApp pure' [dict, val]) []) | isPure (CppApp pure' [dict]) = val
6058 convert (CppApp (CppApp pure' [val]) []) | isPure pure' = val
6159 -- Desugar >>
62− convert (CppApp bind [effDict, m, CppLambda _ [] rty (CppBlock cpp)]) | isBindPoly bind && isEffDict C.bindEffDictionary effDict =
60+ convert (CppApp bind [dict, m, CppLambda _ [] rty (CppBlock cpp)]) | isBind (CppApp bind [dict]) =
6361 CppFunction fnName [] rty [] $ CppBlock (CppApp m [] : map applyReturns cpp )
6462 convert (CppApp (CppApp bind [m]) [CppLambda _ [] rty (CppBlock cpp)]) | isBind bind =
6563 CppFunction fnName [] rty [] $ CppBlock (CppApp m [] : map applyReturns cpp )
6664 -- Desugar >>=
67− convert (CppApp bind [effDict, m, CppLambda _ [arg] rty (CppBlock cpp)]) | isBindPoly bind && isEffDict C.bindEffDictionary effDict =
68− CppFunction fnName [] rty [] $ CppBlock (CppVariableIntroduction arg [] (Just (CppApp m [])) : map applyReturns cpp)
65+ convert (CppApp bind [dict, m, CppLambda _ [arg] rty (CppBlock cpp)]) | isBind (CppApp bind [dict]) =
66+ CppFunction fnName [] rty [] $ CppBlock (app' : map applyReturns cpp)
67+ where
68+ app' | fst arg == C.__unused = CppApp m []
69+ | otherwise = CppVariableIntroduction arg [] (Just (CppApp m []))
6970 convert (CppApp (CppApp bind [m]) [CppLambda _ [arg] rty (CppBlock cpp)]) | isBind bind =
70− CppFunction fnName [] rty [] $ CppBlock (CppVariableIntroduction arg [] (Just (CppApp m [])) : map applyReturns cpp)
71+ CppFunction fnName [] rty [] $ CppBlock (app' : map applyReturns cpp)
72+ where
73+ app' | fst arg == C.__unused = CppApp m []
74+ | otherwise = CppVariableIntroduction arg [] (Just (CppApp m []))
7175 -- Desugar untilE
7276 convert (CppApp (CppApp f [arg]) []) | isEffFunc C.untilE f =
73− CppApp (CppLambda [CppCaptureAll] [] (Just $ CppAny []) (CppBlock [ CppWhile (CppUnary CppNot (CppApp arg [])) (CppBlock []), CppReturn $ CppObjectLiteral []])) []
77+ CppApp (CppLambda [CppCaptureAll] [] Nothing (CppBlock [ CppWhile (CppUnary Not (CppApp arg [])) (CppBlock []), CppReturn $ CppObjectLiteral CppRecord []])) []
7478 -- Desugar whileE
7579 convert (CppApp (CppApp f [arg1, arg2]) []) | isEffFunc C.whileE f =
76− CppApp (CppLambda [CppCaptureAll] [] (Just $ CppAny []) (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral []])) []
80+ CppApp (CppLambda [CppCaptureAll] [] Nothing (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral CppRecord []])) []
7781 convert (CppApp (CppApp (CppApp f [arg1]) [arg2]) []) | isEffFunc C.whileE f =
78− CppApp (CppLambda [CppCaptureAll] [] (Just $ CppAny []) (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral []])) []
82+ CppApp (CppLambda [CppCaptureAll] [] Nothing (CppBlock [ CppWhile (CppApp arg1 []) (CppBlock [ CppApp arg2 [] ]), CppReturn $ CppObjectLiteral CppRecord []])) []
7983 convert other = other
8084 -- Check if an expression represents a monomorphic call to >>= for the Eff monad
81− isBind (CppApp bindPoly [effDict]) | isBindPoly bindPoly && isEffDict C.bindEffDictionary effDict = True
85+ isBind (CppApp fn [dict]) | isDict (C.eff, C.bindEffDictionary) dict && isBindPoly fn = True
8286 isBind _ = False
83− -- Check if an expression represents a monomorphic call to return for the Eff monad
84− isReturn (CppApp retPoly [effDict]) | isRetPoly retPoly && isEffDict C.monadEffDictionary effDict = True
85− isReturn _ = False
86− -- Check if an expression represents a monomorphic call to pure for the Eff applicative
87− isPure (CppApp purePoly [effDict]) | isPurePoly purePoly && isEffDict C.applicativeEffDictionary effDict = True
87+ -- Check if an expression represents a monomorphic call to pure or return for the Eff applicative
88+ isPure (CppApp fn [dict]) | isDict (C.eff, C.applicativeEffDictionary) dict && isPurePoly fn = True
8889 isPure _ = False
8990 -- Check if an expression represents the polymorphic >>= function
90− isBindPoly (CppAccessor (CppVar prop) (CppVar prelude)) = prelude == C.prelude && (prop `elem` map identToCpp [Ident C.bind, Op (C.>>=)])
91− isBindPoly (CppIndexer (CppStringLiteral bind) (CppVar prelude)) = prelude == C.prelude && (bind `elem` [C.bind, (C.>>=)])
92− isBindPoly _ = False
93− -- Check if an expression represents the polymorphic return function
94− isRetPoly (CppAccessor (CppVar returnEscaped) (CppVar prelude)) = prelude == C.prelude && returnEscaped == C.returnEscaped
95− isRetPoly (CppIndexer (CppStringLiteral return') (CppVar prelude)) = prelude == C.prelude && return' == C.return
96− isRetPoly _ = False
97− -- Check if an expression represents the polymorphic pure function
98− isPurePoly (CppAccessor (CppVar pure') (CppVar prelude)) = prelude == C.prelude && pure' == C.pure'
99− isPurePoly (CppIndexer (CppStringLiteral pure') (CppVar prelude)) = prelude == C.prelude && pure' == C.pure'
100− isPurePoly _ = False
101− -- Check if an expression represents a function in the Ef module
91+ isBindPoly = isFn (C.controlBind, C.bind)
92+ -- Check if an expression represents the polymorphic pure or return function
93+ isPurePoly = isFn (C.controlApplicative, C.pure')
94+ -- Check if an expression represents a function in the Eff module
10295 isEffFunc name (CppAccessor (CppVar name') (CppVar eff)) = eff == C.eff && name == name'
10396 isEffFunc _ _ = False
104− -- Check if an expression represents the Monad Eff dictionary
105− isEffDict name (CppVar ident) | ident == name = True
106− isEffDict name (CppAccessor (CppVar prop) (CppVar eff)) = eff == C.eff && prop == name
107− isEffDict _ _ = False
97+
10898 -- Remove __do function applications which remain after desugaring
10999 undo :: Cpp -> Cpp
110100 undo (CppReturn (CppApp (CppFunction ident [] _ _ body) [])) | ident == fnName = body
@@ -121,5 +111,50 @@ magicDo' = everywhereOnCpp undo . everywhereOnCppTopDown convert
121111-- |
122112-- Inline functions in the ST module
123113--
124−-- TODO: various issues in C++ backend -- revisit later
125−--
114+inlineST :: Cpp -> Cpp
115+inlineST = everywhereOnCpp convertBlock
116+ where
117+ -- Look for runST blocks and inline the STRefs there.
118+ -- If all STRefs are used in the scope of the same runST, only using { read, write, modify }STRef then
119+ -- we can be more aggressive about inlining, and actually turn STRefs into local variables.
120+ convertBlock (CppApp f [arg]) | isSTFunc C.runST f =
121+ let refs = nub . findSTRefsIn $ arg
122+ usages = findAllSTUsagesIn arg
123+ allUsagesAreLocalVars = all (\u -> let v = toVar u in isJust v && fromJust v `elem` refs) usages
124+ localVarsDoNotEscape = all (\r -> length (r `appearingIn` arg) == length (filter (\u -> let v = toVar u in v == Just r) usages)) refs
125+ in everywhereOnCpp (convert (allUsagesAreLocalVars && localVarsDoNotEscape)) arg
126+ convertBlock other = other
127+ -- Convert a block in a safe way, preserving object wrappers of references,
128+ -- or in a more aggressive way, turning wrappers into local variables depending on the
129+ -- agg(ressive) parameter.
130+ convert agg (CppApp f [arg]) | isSTFunc C.newSTRef f =
131+ CppLambda [CppCaptureAll] [] Nothing (CppBlock [CppReturn $ if agg then arg else CppObjectLiteral CppRecord [(C.stRefValue, arg)]])
132+ convert agg (CppApp (CppApp f [ref]) []) | isSTFunc C.readSTRef f =
133+ if agg then ref else CppAccessor (CppVar C.stRefValue) ref
134+ convert agg (CppApp (CppApp (CppApp f [ref]) [arg]) []) | isSTFunc C.writeSTRef f =
135+ if agg then CppAssignment ref arg else CppAssignment (CppAccessor (CppVar C.stRefValue) ref) arg
136+ convert agg (CppApp (CppApp (CppApp f [ref]) [func]) []) | isSTFunc C.modifySTRef f =
137+ if agg then CppAssignment ref (CppApp func [ref]) else CppAssignment (CppAccessor (CppVar C.stRefValue) ref) (CppApp func [CppAccessor (CppVar C.stRefValue) ref])
138+ convert _ other = other
139+ -- Check if an expression represents a function in the ST module
140+ isSTFunc name (CppAccessor (CppVar name') (CppVar st)) = st == C.st && name == name'
141+ isSTFunc _ _ = False
142+ -- Find all ST Refs initialized in this block
143+ findSTRefsIn = everythingOnCpp (++) isSTRef
144+ where
145+ isSTRef (CppVariableIntroduction (ident, _) _ (Just (CppApp (CppApp f [_]) []))) | isSTFunc C.newSTRef f = [ident]
146+ isSTRef _ = []
147+ -- Find all STRefs used as arguments to readSTRef, writeSTRef, modifySTRef
148+ findAllSTUsagesIn = everythingOnCpp (++) isSTUsage
149+ where
150+ isSTUsage (CppApp (CppApp f [ref]) []) | isSTFunc C.readSTRef f = [ref]
151+ isSTUsage (CppApp (CppApp (CppApp f [ref]) [_]) []) | isSTFunc C.writeSTRef f || isSTFunc C.modifySTRef f = [ref]
152+ isSTUsage _ = []
153+ -- Find all uses of a variable
154+ appearingIn ref = everythingOnCpp (++) isVar
155+ where
156+ isVar e@(CppVar v) | v == ref = [e]
157+ isVar _ = []
158+ -- Convert a Cpp value to a String if it is a CppVar
159+ toVar (CppVar v) = Just v
160+ toVar _ = Nothing
src/Language/PureScript/CodeGen/Cpp/Optimizer/TCO.hs+2
@@ -15,6 +15,8 @@
1515
1616module Language.PureScript.CodeGen.Cpp.Optimizer.TCO (tco) where
1717
18+import Prelude.Compat
19+
1820import Data.List
1921import Data.Monoid
2022
src/Language/PureScript/CodeGen/Cpp/Optimizer/Unused.hs+2
@@ -15,6 +15,8 @@
1515
1616module Language.PureScript.CodeGen.Cpp.Optimizer.Unused where
1717
18+import Prelude.Compat
19+
1820import Language.PureScript.CodeGen.Cpp.AST
1921import Language.PureScript.CodeGen.Cpp.Optimizer.Common
2022
src/Language/PureScript/CodeGen/Cpp/Types.hs+12−1
@@ -18,6 +18,8 @@
1818
1919module Language.PureScript.CodeGen.Cpp.Types where
2020
21+import Prelude.Compat
22+
2123import Data.List
2224
2325import Language.PureScript.CodeGen.Cpp.Common
@@ -68,6 +70,12 @@ data CppValueQual
6870data CppCaptureType = CppCaptureAll
6971 deriving (Show, Read, Eq)
7072
73+-- |
74+-- C++ object/map literal type
75+--
76+data CppObjectType = CppInstance | CppRecord
77+ deriving (Show, Eq)
78+
7179runType :: CppType -> String
7280runType (CppPrimitive t) = t
7381runType CppAuto = "auto"
@@ -98,7 +106,7 @@ boolType :: CppType
98106boolType = CppPrimitive "bool"
99107
100108intType :: CppType
101−intType = CppPrimitive "integer"
109+intType = CppPrimitive "int"
102110
103111doubleType :: CppType
104112doubleType = CppPrimitive "double"
@@ -123,3 +131,6 @@ thunkMarkerType = CppPrimitive "any::as_thunk"
123131
124132ctorKey :: String
125133ctorKey = "constructor"
134+
135+constAnyRef :: Maybe CppType
136+constAnyRef = Just $ CppAny [CppConst, CppRef]
src/Language/PureScript/CodeGen/JS.hs+20−23
@@ -1,8 +1,3 @@
1−{-# LANGUAGE GADTs #-}
2−{-# LANGUAGE ViewPatterns #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE ScopedTypeVariables #-}
5−
61-- |
72-- This module generates code in the simplified Javascript intermediate representation from Purescript code
83--
@@ -12,29 +7,30 @@ module Language.PureScript.CodeGen.JS
127 , moduleToJs
138 ) where
149
15−import Prelude ()
1610import Prelude.Compat
1711
18−import Data.List ((\\), delete, intersect)
19−import Data.Maybe (isNothing, fromMaybe)
20−import qualified Data.Map as M
21−import qualified Data.Foldable as F
22−import qualified Data.Traversable as T
23−
2412import Control.Arrow ((&&&))
2513import Control.Monad (replicateM, forM, void)
2614import Control.Monad.Error.Class (MonadError(..))
2715import Control.Monad.Reader (MonadReader, asks)
2816import Control.Monad.Supply.Class
2917
30−import Language.PureScript.Crash
18+import Data.List ((\\), delete, intersect)
19+import Data.Maybe (isNothing, fromMaybe)
20+import qualified Data.Foldable as F
21+import qualified Data.Map as M
22+import qualified Data.Traversable as T
23+
3124import Language.PureScript.AST.SourcePos
3225import Language.PureScript.CodeGen.JS.AST as AST
3326import Language.PureScript.CodeGen.JS.Common as Common
27+import Language.PureScript.CodeGen.JS.Optimizer
3428import Language.PureScript.CoreFn
29+import Language.PureScript.Crash
30+import Language.PureScript.Errors (ErrorMessageHint(..), SimpleErrorMessage(..),
31+ MultipleErrors(..), rethrow,
32+ errorMessage, rethrowWithPosition, addHint)
3533import Language.PureScript.Names
36−import Language.PureScript.Errors
37−import Language.PureScript.CodeGen.JS.Optimizer
3834import Language.PureScript.Options
3935import Language.PureScript.Traversals (sndM)
4036import qualified Language.PureScript.Constants as C
@@ -109,9 +105,8 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
109105 --
110106 importToJs :: M.Map ModuleName (Ann, ModuleName) -> ModuleName -> m JS
111107 importToJs mnLookup mn' = do
112− path <- asks optionsRequirePath
113108 let ((ss, _, _, _), mnSafe) = fromMaybe (internalError "Missing value in mnLookup") $ M.lookup mn' mnLookup
114− let moduleBody = JSApp Nothing (JSVar Nothing "require") [JSStringLiteral Nothing (fromMaybe ".." path </> runModuleName mn')]
109+ let moduleBody = JSApp Nothing (JSVar Nothing "require") [JSStringLiteral Nothing (".." </> runModuleName mn')]
115110 withPos ss $ JSVariableIntroduction Nothing (moduleNameToJs mnSafe) (Just moduleBody)
116111
117112 -- |
@@ -180,7 +175,6 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
180175 --
181176 accessor :: Ident -> JS -> JS
182177 accessor (Ident prop) = accessorString prop
183− accessor (Op op) = JSIndexer Nothing (JSStringLiteral Nothing op)
184178 accessor (GenIdent _ _) = internalError "GenIdent in accessor"
185179
186180 accessorString :: String -> JS -> JS
@@ -288,15 +282,18 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
288282 extendObj obj sts = do
289283 newObj <- freshName
290284 key <- freshName
285+ evaluatedObj <- freshName
291286 let
292287 jsKey = JSVar Nothing key
293288 jsNewObj = JSVar Nothing newObj
294− block = JSBlock Nothing (objAssign:copy:extend ++ [JSReturn Nothing jsNewObj])
289+ jsEvaluatedObj = JSVar Nothing evaluatedObj
290+ block = JSBlock Nothing (evaluate:objAssign:copy:extend ++ [JSReturn Nothing jsNewObj])
291+ evaluate = JSVariableIntroduction Nothing evaluatedObj (Just obj)
295292 objAssign = JSVariableIntroduction Nothing newObj (Just $ JSObjectLiteral Nothing [])
296− copy = JSForIn Nothing key obj $ JSBlock Nothing [JSIfElse Nothing cond assign Nothing]
297− cond = JSApp Nothing (JSAccessor Nothing "hasOwnProperty" obj) [jsKey]
298− assign = JSBlock Nothing [JSAssignment Nothing (JSIndexer Nothing jsKey jsNewObj) (JSIndexer Nothing jsKey obj)]
299− stToAssign (s, js) = JSAssignment Nothing (JSAccessor Nothing s jsNewObj) js
293+ copy = JSForIn Nothing key jsEvaluatedObj $ JSBlock Nothing [JSIfElse Nothing cond assign Nothing]
294+ cond = JSApp Nothing (JSAccessor Nothing "hasOwnProperty" jsEvaluatedObj) [jsKey]
295+ assign = JSBlock Nothing [JSAssignment Nothing (JSIndexer Nothing jsKey jsNewObj) (JSIndexer Nothing jsKey jsEvaluatedObj)]
296+ stToAssign (s, js) = JSAssignment Nothing (accessorString s jsNewObj) js
300297 extend = map stToAssign sts
301298 return $ JSApp Nothing (JSFunction Nothing Nothing [] block) []
302299
src/Language/PureScript/CodeGen/JS/AST.hs+4−5
@@ -3,14 +3,13 @@
33--
44module Language.PureScript.CodeGen.JS.AST where
55
6−import Prelude ()
76import Prelude.Compat
87
98import Control.Monad.Identity
109
10+import Language.PureScript.AST (SourceSpan(..))
1111import Language.PureScript.Comments
1212import Language.PureScript.Traversals
13−import Language.PureScript.AST (SourceSpan(..))
1413
1514-- |
1615-- Built-in unary operators
@@ -36,7 +35,7 @@ data UnaryOperator
3635 -- Constructor
3736 --
3837 | JSNew
39− deriving (Show, Read, Eq)
38+ deriving (Show, Eq)
4039
4140-- |
4241-- Built-in binary operators
@@ -118,7 +117,7 @@ data BinaryOperator
118117 -- Bitwise right shift with zero-fill
119118 --
120119 | ZeroFillShiftRight
121− deriving (Show, Read, Eq)
120+ deriving (Show, Eq)
122121
123122-- |
124123-- Data type for simplified Javascript expressions
@@ -239,7 +238,7 @@ data JS
239238 -- |
240239 -- Commented Javascript
241240 --
242− | JSComment (Maybe SourceSpan) [Comment] JS deriving (Show, Read, Eq)
241+ | JSComment (Maybe SourceSpan) [Comment] JS deriving (Show, Eq)
243242
244243withSourceSpan :: SourceSpan -> JS -> JS
245244withSourceSpan withSpan = go
src/Language/PureScript/CodeGen/JS/Common.hs+3−2
@@ -3,6 +3,8 @@
33--
44module Language.PureScript.CodeGen.JS.Common where
55
6+import Prelude.Compat
7+
68import Data.Char
79import Data.List (intercalate)
810
@@ -27,14 +29,13 @@ identToJs :: Ident -> String
2729identToJs (Ident name)
2830 | nameIsJsReserved name || nameIsJsBuiltIn name = "$$" ++ name
2931 | otherwise = concatMap identCharToString name
30−identToJs (Op op) = concatMap identCharToString op
3132identToJs (GenIdent _ _) = internalError "GenIdent in identToJs"
3233
3334-- |
3435-- Test if a string is a valid JS identifier without escaping.
3536--
3637identNeedsEscaping :: String -> Bool
37−identNeedsEscaping s = s /= identToJs (Ident s)
38+identNeedsEscaping s = s /= identToJs (Ident s) || null s
3839
3940-- |
4041-- Attempts to find a human-readable name for a symbol, if none has been specified returns the
src/Language/PureScript/CodeGen/JS/Optimizer.hs+7−11
@@ -1,5 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−
31-- |
42-- This module optimizes code in the simplified-Javascript intermediate representation.
53--
@@ -23,32 +21,30 @@
2321--
2422module Language.PureScript.CodeGen.JS.Optimizer (optimize) where
2523
26−import Prelude ()
2724import Prelude.Compat
2825
2926import Control.Monad.Reader (MonadReader, ask, asks)
3027import Control.Monad.Supply.Class (MonadSupply)
3128
3229import Language.PureScript.CodeGen.JS.AST
33−import Language.PureScript.Options
34−import qualified Language.PureScript.Constants as C
35−
30+import Language.PureScript.CodeGen.JS.Optimizer.Blocks
3631import Language.PureScript.CodeGen.JS.Optimizer.Common
37−import Language.PureScript.CodeGen.JS.Optimizer.TCO
38−import Language.PureScript.CodeGen.JS.Optimizer.MagicDo
3932import Language.PureScript.CodeGen.JS.Optimizer.Inliner
33+import Language.PureScript.CodeGen.JS.Optimizer.MagicDo
34+import Language.PureScript.CodeGen.JS.Optimizer.TCO
4035import Language.PureScript.CodeGen.JS.Optimizer.Unused
41−import Language.PureScript.CodeGen.JS.Optimizer.Blocks
36+import Language.PureScript.Options
37+import qualified Language.PureScript.Constants as C
4238
4339-- |
4440-- Apply a series of optimizer passes to simplified Javascript code
4541--
46−optimize :: (Monad m, MonadReader Options m, MonadSupply m) => JS -> m JS
42+optimize :: (MonadReader Options m, MonadSupply m) => JS -> m JS
4743optimize js = do
4844 noOpt <- asks optionsNoOptimizations
4945 if noOpt then return js else optimize' js
5046
51−optimize' :: (Monad m, MonadReader Options m, MonadSupply m) => JS -> m JS
47+optimize' :: (MonadReader Options m, MonadSupply m) => JS -> m JS
5248optimize' js = do
5349 opts <- ask
5450 js' <- untilFixedPoint (inlineFnComposition . tidyUp . applyAll
src/Language/PureScript/CodeGen/JS/Optimizer/Blocks.hs+2−12
@@ -1,23 +1,13 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.Blocks
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- Optimizer steps for simplifying Javascript blocks
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.CodeGen.JS.Optimizer.Blocks
175 ( collapseNestedBlocks
186 , collapseNestedIfs
197 ) where
208
9+import Prelude.Compat
10+
2111import Language.PureScript.CodeGen.JS.AST
2212
2313-- |
src/Language/PureScript/CodeGen/JS/Optimizer/Common.hs+6−5
@@ -3,6 +3,8 @@
33--
44module Language.PureScript.CodeGen.JS.Optimizer.Common where
55
6+import Prelude.Compat
7+
68import Data.Maybe (fromMaybe)
79
810import Language.PureScript.Crash
@@ -66,13 +68,12 @@ removeFromBlock go (JSBlock ss sts) = JSBlock ss (go sts)
6668removeFromBlock _ js = js
6769
6870isFn :: (String, String) -> JS -> Bool
69−isFn (moduleName, fnName) (JSAccessor _ x (JSVar _ y)) = x == fnName && y == moduleName
70−isFn (moduleName, fnName) (JSIndexer _ (JSStringLiteral _ x) (JSVar _ y)) = x == fnName && y == moduleName
71+isFn (moduleName, fnName) (JSAccessor _ x (JSVar _ y)) =
72+ x == fnName && y == moduleName
73+isFn (moduleName, fnName) (JSIndexer _ (JSStringLiteral _ x) (JSVar _ y)) =
74+ x == fnName && y == moduleName
7175isFn _ _ = False
7276
73−isFn' :: [(String, String)] -> JS -> Bool
74−isFn' xs js = any (`isFn` js) xs
75−
7677isDict :: (String, String) -> JS -> Bool
7778isDict (moduleName, dictName) (JSAccessor _ x (JSVar _ y)) = x == dictName && y == moduleName
7879isDict _ _ = False
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs+105−108
@@ -12,15 +12,13 @@ module Language.PureScript.CodeGen.JS.Optimizer.Inliner
1212 , evaluateIifes
1313 ) where
1414
15−import Prelude ()
1615import Prelude.Compat
1716
1817import Control.Monad.Supply.Class (MonadSupply, freshName)
18+
1919import Data.Maybe (fromMaybe)
2020
2121import Language.PureScript.CodeGen.JS.AST
22−import Language.PureScript.CodeGen.JS.Common
23−import Language.PureScript.Names
2422import Language.PureScript.CodeGen.JS.Optimizer.Common
2523import qualified Language.PureScript.Constants as C
2624
@@ -82,24 +80,24 @@ inlineCommonValues = everywhereOnJS convert
8280 where
8381 convert :: JS -> JS
8482 convert (JSApp ss fn [dict])
85− | isDict' (semiringNumber ++ semiringInt) dict && isFn' fnZero fn = JSNumericLiteral ss (Left 0)
86− | isDict' (semiringNumber ++ semiringInt) dict && isFn' fnOne fn = JSNumericLiteral ss (Left 1)
87− | isDict' boundedBoolean dict && isFn' fnBottom fn = JSBooleanLiteral ss False
88− | isDict' boundedBoolean dict && isFn' fnTop fn = JSBooleanLiteral ss True
83+ | isDict' [semiringNumber, semiringInt] dict && isFn fnZero fn = JSNumericLiteral ss (Left 0)
84+ | isDict' [semiringNumber, semiringInt] dict && isFn fnOne fn = JSNumericLiteral ss (Left 1)
85+ | isDict boundedBoolean dict && isFn fnBottom fn = JSBooleanLiteral ss False
86+ | isDict boundedBoolean dict && isFn fnTop fn = JSBooleanLiteral ss True
8987 convert (JSApp ss (JSApp _ (JSApp _ fn [dict]) [x]) [y])
90− | isDict' semiringInt dict && isFn' fnAdd fn = intOp ss Add x y
91− | isDict' semiringInt dict && isFn' fnMultiply fn = intOp ss Multiply x y
92− | isDict' moduloSemiringInt dict && isFn' fnDivide fn = intOp ss Divide x y
93− | isDict' ringInt dict && isFn' fnSubtract fn = intOp ss Subtract x y
88+ | isDict semiringInt dict && isFn fnAdd fn = intOp ss Add x y
89+ | isDict semiringInt dict && isFn fnMultiply fn = intOp ss Multiply x y
90+ | isDict euclideanRingInt dict && isFn fnDivide fn = intOp ss Divide x y
91+ | isDict ringInt dict && isFn fnSubtract fn = intOp ss Subtract x y
9492 convert other = other
95− fnZero = [(C.prelude, C.zero), (C.dataSemiring, C.zero)]
96− fnOne = [(C.prelude, C.one), (C.dataSemiring, C.one)]
97− fnBottom = [(C.prelude, C.bottom), (C.dataBounded, C.bottom)]
98− fnTop = [(C.prelude, C.top), (C.dataBounded, C.top)]
99− fnAdd = [(C.prelude, (C.+)), (C.prelude, C.add), (C.dataSemiring, (C.+)), (C.dataSemiring, C.add)]
100− fnDivide = [(C.prelude, (C./)), (C.prelude, C.div), (C.dataModuloSemiring, C.div)]
101− fnMultiply = [(C.prelude, (C.*)), (C.prelude, C.mul), (C.dataSemiring, (C.*)), (C.dataSemiring, C.mul)]
102− fnSubtract = [(C.prelude, (C.-)), (C.prelude, C.sub), (C.dataRing, C.sub)]
93+ fnZero = (C.dataSemiring, C.zero)
94+ fnOne = (C.dataSemiring, C.one)
95+ fnBottom = (C.dataBounded, C.bottom)
96+ fnTop = (C.dataBounded, C.top)
97+ fnAdd = (C.dataSemiring, C.add)
98+ fnDivide = (C.dataEuclideanRing, C.div)
99+ fnMultiply = (C.dataSemiring, C.mul)
100+ fnSubtract = (C.dataRing, C.sub)
103101 intOp ss op x y = JSBinary ss BitwiseOr (JSBinary ss op x y) (JSNumericLiteral ss (Left 0))
104102
105103inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
@@ -108,7 +106,6 @@ inlineOperator (m, op) f = everywhereOnJS convert
108106 convert :: JS -> JS
109107 convert (JSApp _ (JSApp _ op' [x]) [y]) | isOp op' = f x y
110108 convert other = other
111− isOp (JSAccessor _ longForm (JSVar _ m')) = m == m' && longForm == identToJs (Op op)
112109 isOp (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) = m == m' && op == op'
113110 isOp _ = False
114111
@@ -122,8 +119,8 @@ inlineCommonOperators = applyAll $
122119 , binary ringInt opSub Subtract
123120 , unary ringInt opNegate Negate
124121
125− , binary moduloSemiringNumber opDiv Divide
126− , binary moduloSemiringInt opMod Modulus
122+ , binary euclideanRingNumber opDiv Divide
123+ , binary euclideanRingInt opMod Modulus
127124
128125 , binary eqNumber opEq EqualTo
129126 , binary eqNumber opNotEq NotEqualTo
@@ -159,9 +156,9 @@ inlineCommonOperators = applyAll $
159156
160157 , binary semigroupString opAppend Add
161158
162− , binary booleanAlgebraBoolean opConj And
163− , binary booleanAlgebraBoolean opDisj Or
164− , unary booleanAlgebraBoolean opNot Not
159+ , binary heytingAlgebraBoolean opConj And
160+ , binary heytingAlgebraBoolean opDisj Or
161+ , unary heytingAlgebraBoolean opNot Not
165162
166163 , binary' C.dataIntBits (C..|.) BitwiseOr
167164 , binary' C.dataIntBits (C..&.) BitwiseAnd
@@ -173,11 +170,11 @@ inlineCommonOperators = applyAll $
173170 ] ++
174171 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
175172 where
176− binary :: [(String, String)] -> [(String, String)] -> BinaryOperator -> JS -> JS
173+ binary :: (String, String) -> (String, String) -> BinaryOperator -> JS -> JS
177174 binary dict fns op = everywhereOnJS convert
178175 where
179176 convert :: JS -> JS
180− convert (JSApp ss (JSApp _ (JSApp _ fn [dict']) [x]) [y]) | isDict' dict dict' && isFn' fns fn = JSBinary ss op x y
177+ convert (JSApp ss (JSApp _ (JSApp _ fn [dict']) [x]) [y]) | isDict dict dict' && isFn fns fn = JSBinary ss op x y
181178 convert other = other
182179 binary' :: String -> String -> BinaryOperator -> JS -> JS
183180 binary' moduleName opString op = everywhereOnJS convert
@@ -185,11 +182,11 @@ inlineCommonOperators = applyAll $
185182 convert :: JS -> JS
186183 convert (JSApp ss (JSApp _ fn [x]) [y]) | isFn (moduleName, opString) fn = JSBinary ss op x y
187184 convert other = other
188− unary :: [(String, String)] -> [(String, String)] -> UnaryOperator -> JS -> JS
185+ unary :: (String, String) -> (String, String) -> UnaryOperator -> JS -> JS
189186 unary dicts fns op = everywhereOnJS convert
190187 where
191188 convert :: JS -> JS
192− convert (JSApp ss (JSApp _ fn [dict']) [x]) | isDict' dicts dict' && isFn' fns fn = JSUnary ss op x
189+ convert (JSApp ss (JSApp _ fn [dict']) [x]) | isDict dicts dict' && isFn fns fn = JSUnary ss op x
193190 convert other = other
194191 unary' :: String -> String -> UnaryOperator -> JS -> JS
195192 unary' moduleName fnName op = everywhereOnJS convert
@@ -219,7 +216,7 @@ inlineCommonOperators = applyAll $
219216
220217 isNFn :: String -> Int -> JS -> Bool
221218 isNFn prefix n (JSVar _ name) = name == (prefix ++ show n)
222− isNFn prefix n (JSAccessor _ name (JSVar _ dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
219+ isNFn prefix n (JSAccessor _ name (JSVar _ dataFunctionUncurried)) | dataFunctionUncurried == C.dataFunctionUncurried = name == (prefix ++ show n)
223220 isNFn _ _ _ = False
224221
225222 runFn :: Int -> JS -> JS
@@ -251,118 +248,118 @@ inlineFnComposition = everywhereOnJSTopDownM convert
251248 return $ JSFunction ss Nothing [arg] (JSBlock ss [JSReturn Nothing $ JSApp Nothing y [JSApp Nothing x [JSVar Nothing arg]]])
252249 convert other = return other
253250 isFnCompose :: JS -> JS -> Bool
254− isFnCompose dict' fn = isDict' semigroupoidFn dict' && isFn' fnCompose fn
251+ isFnCompose dict' fn = isDict semigroupoidFn dict' && isFn fnCompose fn
255252 isFnComposeFlipped :: JS -> JS -> Bool
256− isFnComposeFlipped dict' fn = isDict' semigroupoidFn dict' && isFn' fnComposeFlipped fn
257− fnCompose :: [(String, String)]
258− fnCompose = [(C.prelude, C.compose), (C.prelude, (C.<<<)), (C.controlSemigroupoid, C.compose)]
259− fnComposeFlipped :: [(String, String)]
260− fnComposeFlipped = [(C.prelude, (C.>>>)), (C.controlSemigroupoid, C.composeFlipped)]
253+ isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isFn fnComposeFlipped fn
254+ fnCompose :: (String, String)
255+ fnCompose = (C.controlSemigroupoid, C.compose)
256+ fnComposeFlipped :: (String, String)
257+ fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
261258
262−semiringNumber :: [(String, String)]
263−semiringNumber = [(C.prelude, C.semiringNumber), (C.dataSemiring, C.semiringNumber)]
259+semiringNumber :: (String, String)
260+semiringNumber = (C.dataSemiring, C.semiringNumber)
264261
265−semiringInt :: [(String, String)]
266−semiringInt = [(C.prelude, C.semiringInt), (C.dataSemiring, C.semiringInt)]
262+semiringInt :: (String, String)
263+semiringInt = (C.dataSemiring, C.semiringInt)
267264
268−ringNumber :: [(String, String)]
269−ringNumber = [(C.prelude, C.ringNumber), (C.dataRing, C.ringNumber)]
265+ringNumber :: (String, String)
266+ringNumber = (C.dataRing, C.ringNumber)
270267
271−ringInt :: [(String, String)]
272−ringInt = [(C.prelude, C.ringInt), (C.dataRing, C.ringInt)]
268+ringInt :: (String, String)
269+ringInt = (C.dataRing, C.ringInt)
273270
274−moduloSemiringNumber :: [(String, String)]
275−moduloSemiringNumber = [(C.prelude, C.moduloSemiringNumber), (C.dataModuloSemiring, C.moduloSemiringNumber)]
271+euclideanRingNumber :: (String, String)
272+euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
276273
277−moduloSemiringInt :: [(String, String)]
278−moduloSemiringInt = [(C.prelude, C.moduloSemiringInt), (C.dataModuloSemiring, C.moduloSemiringInt)]
274+euclideanRingInt :: (String, String)
275+euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
279276
280−eqNumber :: [(String, String)]
281−eqNumber = [(C.prelude, C.eqNumber), (C.dataEq, C.eqNumber)]
277+eqNumber :: (String, String)
278+eqNumber = (C.dataEq, C.eqNumber)
282279
283−eqInt :: [(String, String)]
284−eqInt = [(C.prelude, C.eqInt), (C.dataEq, C.eqInt)]
280+eqInt :: (String, String)
281+eqInt = (C.dataEq, C.eqInt)
285282
286−eqString :: [(String, String)]
287−eqString = [(C.prelude, C.eqString), (C.dataEq, C.eqString)]
283+eqString :: (String, String)
284+eqString = (C.dataEq, C.eqString)
288285
289−eqChar :: [(String, String)]
290−eqChar = [(C.prelude, C.eqChar), (C.dataEq, C.eqChar)]
286+eqChar :: (String, String)
287+eqChar = (C.dataEq, C.eqChar)
291288
292−eqBoolean :: [(String, String)]
293−eqBoolean = [(C.prelude, C.eqBoolean), (C.dataEq, C.eqBoolean)]
289+eqBoolean :: (String, String)
290+eqBoolean = (C.dataEq, C.eqBoolean)
294291
295−ordBoolean :: [(String, String)]
296−ordBoolean = [(C.prelude, C.ordBoolean), (C.dataOrd, C.ordBoolean)]
292+ordBoolean :: (String, String)
293+ordBoolean = (C.dataOrd, C.ordBoolean)
297294
298−ordNumber :: [(String, String)]
299−ordNumber = [(C.prelude, C.ordNumber), (C.dataOrd, C.ordNumber)]
295+ordNumber :: (String, String)
296+ordNumber = (C.dataOrd, C.ordNumber)
300297
301−ordInt :: [(String, String)]
302−ordInt = [(C.prelude, C.ordInt), (C.dataOrd, C.ordInt)]
298+ordInt :: (String, String)
299+ordInt = (C.dataOrd, C.ordInt)
303300
304−ordString :: [(String, String)]
305−ordString = [(C.prelude, C.ordString), (C.dataOrd, C.ordString)]
301+ordString :: (String, String)
302+ordString = (C.dataOrd, C.ordString)
306303
307−ordChar :: [(String, String)]
308−ordChar = [(C.prelude, C.ordChar), (C.dataOrd, C.ordChar)]
304+ordChar :: (String, String)
305+ordChar = (C.dataOrd, C.ordChar)
309306
310−semigroupString :: [(String, String)]
311−semigroupString = [(C.prelude, C.semigroupString), (C.dataSemigroup, C.semigroupString)]
307+semigroupString :: (String, String)
308+semigroupString = (C.dataSemigroup, C.semigroupString)
312309
313−boundedBoolean :: [(String, String)]
314−boundedBoolean = [(C.prelude, C.boundedBoolean), (C.dataBounded, C.boundedBoolean)]
310+boundedBoolean :: (String, String)
311+boundedBoolean = (C.dataBounded, C.boundedBoolean)
315312
316−booleanAlgebraBoolean :: [(String, String)]
317−booleanAlgebraBoolean = [(C.prelude, C.booleanAlgebraBoolean), (C.dataBooleanAlgebra, C.booleanAlgebraBoolean)]
313+heytingAlgebraBoolean :: (String, String)
314+heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
318315
319−semigroupoidFn :: [(String, String)]
320−semigroupoidFn = [(C.prelude, C.semigroupoidFn), (C.controlSemigroupoid, C.semigroupoidFn)]
316+semigroupoidFn :: (String, String)
317+semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
321318
322−opAdd :: [(String, String)]
323−opAdd = [(C.prelude, (C.+)), (C.prelude, C.add), (C.dataSemiring, C.add)]
319+opAdd :: (String, String)
320+opAdd = (C.dataSemiring, C.add)
324321
325−opMul :: [(String, String)]
326−opMul = [(C.prelude, (C.*)), (C.prelude, C.mul), (C.dataSemiring, C.mul)]
322+opMul :: (String, String)
323+opMul = (C.dataSemiring, C.mul)
327324
328−opEq :: [(String, String)]
329−opEq = [(C.prelude, (C.==)), (C.prelude, C.eq), (C.dataEq, C.eq)]
325+opEq :: (String, String)
326+opEq = (C.dataEq, C.eq)
330327
331−opNotEq :: [(String, String)]
332−opNotEq = [(C.prelude, (C./=)), (C.dataEq, C.notEq)]
328+opNotEq :: (String, String)
329+opNotEq = (C.dataEq, C.notEq)
333330
334−opLessThan :: [(String, String)]
335−opLessThan = [(C.prelude, (C.<)), (C.dataOrd, C.lessThan)]
331+opLessThan :: (String, String)
332+opLessThan = (C.dataOrd, C.lessThan)
336333
337−opLessThanOrEq :: [(String, String)]
338−opLessThanOrEq = [(C.prelude, (C.<=)), (C.dataOrd, C.lessThanOrEq)]
334+opLessThanOrEq :: (String, String)
335+opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
339336
340−opGreaterThan :: [(String, String)]
341−opGreaterThan = [(C.prelude, (C.>)), (C.dataOrd, C.greaterThan)]
337+opGreaterThan :: (String, String)
338+opGreaterThan = (C.dataOrd, C.greaterThan)
342339
343−opGreaterThanOrEq :: [(String, String)]
344−opGreaterThanOrEq = [(C.prelude, (C.>=)), (C.dataOrd, C.greaterThanOrEq)]
340+opGreaterThanOrEq :: (String, String)
341+opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
345342
346−opAppend :: [(String, String)]
347−opAppend = [(C.prelude, (C.<>)), (C.prelude, (C.++)), (C.prelude, C.append), (C.dataSemigroup, C.append)]
343+opAppend :: (String, String)
344+opAppend = (C.dataSemigroup, C.append)
348345
349−opSub :: [(String, String)]
350−opSub = [(C.prelude, (C.-)), (C.prelude, C.sub), (C.dataRing, C.sub)]
346+opSub :: (String, String)
347+opSub = (C.dataRing, C.sub)
351348
352−opNegate :: [(String, String)]
353−opNegate = [(C.prelude, C.negate), (C.dataRing, C.negate)]
349+opNegate :: (String, String)
350+opNegate = (C.dataRing, C.negate)
354351
355−opDiv :: [(String, String)]
356−opDiv = [(C.prelude, (C./)), (C.prelude, C.div), (C.dataModuloSemiring, C.div)]
352+opDiv :: (String, String)
353+opDiv = (C.dataEuclideanRing, C.div)
357354
358−opMod :: [(String, String)]
359−opMod = [(C.prelude, C.mod), (C.dataModuloSemiring, C.mod)]
355+opMod :: (String, String)
356+opMod = (C.dataEuclideanRing, C.mod)
360357
361−opConj :: [(String, String)]
362−opConj = [(C.prelude, (C.&&)), (C.prelude, C.conj), (C.dataBooleanAlgebra, C.conj)]
358+opConj :: (String, String)
359+opConj = (C.dataHeytingAlgebra, C.conj)
363360
364−opDisj :: [(String, String)]
365−opDisj = [(C.prelude, (C.||)), (C.prelude, C.disj), (C.dataBooleanAlgebra, C.disj)]
361+opDisj :: (String, String)
362+opDisj = (C.dataHeytingAlgebra, C.disj)
366363
367−opNot :: [(String, String)]
368−opNot = [(C.prelude, C.not), (C.dataBooleanAlgebra, C.not)]
364+opNot :: (String, String)
365+opNot = (C.dataHeytingAlgebra, C.not)
src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+4−2
@@ -4,6 +4,8 @@
44--
55module Language.PureScript.CodeGen.JS.Optimizer.MagicDo (magicDo) where
66
7+import Prelude.Compat
8+
79import Data.List (nub)
810import Data.Maybe (fromJust, isJust)
911
@@ -61,9 +63,9 @@ magicDo' = everywhereOnJS undo . everywhereOnJSTopDown convert
6163 isPure (JSApp _ fn [dict]) | isDict (C.eff, C.applicativeEffDictionary) dict && isPurePoly fn = True
6264 isPure _ = False
6365 -- Check if an expression represents the polymorphic >>= function
64− isBindPoly = isFn' [(C.prelude, C.bind), (C.prelude, (C.>>=)), (C.controlBind, C.bind)]
66+ isBindPoly = isFn (C.controlBind, C.bind)
6567 -- Check if an expression represents the polymorphic pure or return function
66− isPurePoly = isFn' [(C.prelude, C.pure'), (C.prelude, C.return), (C.controlApplicative, C.pure')]
68+ isPurePoly = isFn (C.controlApplicative, C.pure')
6769 -- Check if an expression represents a function in the Eff module
6870 isEffFunc name (JSAccessor _ name' (JSVar _ eff)) = eff == C.eff && name == name'
6971 isEffFunc _ _ = False
src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+2−12
@@ -1,20 +1,10 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.TCO
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- This module implements tail call elimination.
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.CodeGen.JS.Optimizer.TCO (tco) where
175
6+import Prelude.Compat
7+
188import Data.Monoid
199
2010import Language.PureScript.Options
src/Language/PureScript/CodeGen/JS/Optimizer/Unused.hs+2−13
@@ -1,27 +1,16 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CodeGen.JS.Optimizer.Unused
4−-- Copyright : (c) Phil Freeman 2013-14
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- Removes unused variables
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.CodeGen.JS.Optimizer.Unused
175 ( removeCodeAfterReturnStatements
186 , removeUnusedArg
197 , removeUndefinedApp
208 ) where
219
10+import Prelude.Compat
11+
2212import Language.PureScript.CodeGen.JS.AST
2313import Language.PureScript.CodeGen.JS.Optimizer.Common
24−
2514import qualified Language.PureScript.Constants as C
2615
2716removeCodeAfterReturnStatements :: JS -> JS
src/Language/PureScript/Comments.hs+3−1
@@ -5,11 +5,13 @@
55--
66module Language.PureScript.Comments where
77
8+import Prelude.Compat
9+
810import Data.Aeson.TH
911
1012data Comment
1113 = LineComment String
1214 | BlockComment String
13− deriving (Show, Read, Eq, Ord)
15+ deriving (Show, Eq, Ord)
1416
1517$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''Comment)
src/Language/PureScript/Constants.hs+33−8
@@ -1,8 +1,10 @@
1−-- |
2−-- Various constants which refer to things in the Prelude
3−--
1+-- | Various constants which refer to things in the Prelude
42module Language.PureScript.Constants where
53
4+import Prelude.Compat
5+
6+import Language.PureScript.Names
7+
68-- Operators
79
810($) :: String
@@ -247,6 +249,12 @@ moduloSemiringNumber = "moduloSemiringNumber"
247249moduloSemiringInt :: String
248250moduloSemiringInt = "moduloSemiringInt"
249251
252+euclideanRingNumber :: String
253+euclideanRingNumber = "euclideanRingNumber"
254+
255+euclideanRingInt :: String
256+euclideanRingInt = "euclideanRingInt"
257+
250258ordBoolean :: String
251259ordBoolean = "ordBoolean"
252260
@@ -283,6 +291,9 @@ boundedBoolean = "boundedBoolean"
283291booleanAlgebraBoolean :: String
284292booleanAlgebraBoolean = "booleanAlgebraBoolean"
285293
294+heytingAlgebraBoolean :: String
295+heytingAlgebraBoolean = "heytingAlgebraBoolean"
296+
286297semigroupString :: String
287298semigroupString = "semigroupString"
288299
@@ -308,6 +319,17 @@ toSignature = "toSignature"
308319main :: String
309320main = "main"
310321
322+-- Prim
323+
324+partial :: String
325+partial = "Partial"
326+
327+pattern Partial :: Qualified (ProperName 'ClassName)
328+pattern Partial = Qualified (Just (ModuleName [ProperName "Prim"])) (ProperName "Partial")
329+
330+pattern Fail :: Qualified (ProperName 'ClassName)
331+pattern Fail = Qualified (Just (ModuleName [ProperName "Prim"])) (ProperName "Fail")
332+
311333-- Code Generation
312334
313335__superclass_ :: String
@@ -348,11 +370,8 @@ dataBounded = "Data_Bounded"
348370dataSemigroup :: String
349371dataSemigroup = "Data_Semigroup"
350372
351−dataModuloSemiring :: String
352−dataModuloSemiring = "Data_ModuloSemiring"
353−
354−dataBooleanAlgebra :: String
355−dataBooleanAlgebra = "Data_BooleanAlgebra"
373+dataHeytingAlgebra :: String
374+dataHeytingAlgebra = "Data_HeytingAlgebra"
356375
357376dataEq :: String
358377dataEq = "Data_Eq"
@@ -366,8 +385,14 @@ dataSemiring = "Data_Semiring"
366385dataRing :: String
367386dataRing = "Data_Ring"
368387
388+dataEuclideanRing :: String
389+dataEuclideanRing = "Data_EuclideanRing"
390+
369391dataFunction :: String
370392dataFunction = "Data_Function"
371393
394+dataFunctionUncurried :: String
395+dataFunctionUncurried = "Data_Function_Uncurried"
396+
372397dataIntBits :: String
373398dataIntBits = "Data_Int_Bits"
src/Language/PureScript/CoreFn.hs+1−1
@@ -5,11 +5,11 @@ module Language.PureScript.CoreFn (
55 module C
66) where
77
8+import Language.PureScript.AST.Literals as C
89import Language.PureScript.CoreFn.Ann as C
910import Language.PureScript.CoreFn.Binders as C
1011import Language.PureScript.CoreFn.Desugar as C
1112import Language.PureScript.CoreFn.Expr as C
12−import Language.PureScript.AST.Literals as C
1313import Language.PureScript.CoreFn.Meta as C
1414import Language.PureScript.CoreFn.Module as C
1515import Language.PureScript.CoreFn.Traversals as C
src/Language/PureScript/CoreFn/Ann.hs+25−37
@@ -1,37 +1,25 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CoreFn.Ann
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | Type alias for basic annotations
12−--
13−-----------------------------------------------------------------------------
14−
15−module Language.PureScript.CoreFn.Ann where
16−
17−import Language.PureScript.AST.SourcePos
18−import Language.PureScript.CoreFn.Meta
19−import Language.PureScript.Types
20−import Language.PureScript.Comments
21−
22−-- |
23−-- Type alias for basic annotations
24−--
25−type Ann = (Maybe SourceSpan, [Comment], Maybe Type, Maybe Meta)
26−
27−-- |
28−-- Initial annotation with no metadata
29−--
30−nullAnn :: Ann
31−nullAnn = (Nothing, [], Nothing, Nothing)
32−
33−-- |
34−-- Remove the comments from an annotation
35−--
36−removeComments :: Ann -> Ann
37−removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
1+module Language.PureScript.CoreFn.Ann where
2+
3+import Prelude.Compat
4+
5+import Language.PureScript.AST.SourcePos
6+import Language.PureScript.Comments
7+import Language.PureScript.CoreFn.Meta
8+import Language.PureScript.Types
9+
10+-- |
11+-- Type alias for basic annotations
12+--
13+type Ann = (Maybe SourceSpan, [Comment], Maybe Type, Maybe Meta)
14+
15+-- |
16+-- Initial annotation with no metadata
17+--
18+nullAnn :: Ann
19+nullAnn = (Nothing, [], Nothing, Nothing)
20+
21+-- |
22+-- Remove the comments from an annotation
23+--
24+removeComments :: Ann -> Ann
25+removeComments (ss, _, ty, meta) = (ss, [], ty, meta)
src/Language/PureScript/CoreFn/Binders.hs+3−3
@@ -1,10 +1,10 @@
1−{-# LANGUAGE DeriveFunctor #-}
2−
31-- |
42-- The core functional representation for binders
53--
64module Language.PureScript.CoreFn.Binders where
75
6+import Prelude.Compat
7+
88import Language.PureScript.AST.Literals
99import Language.PureScript.Names
1010
@@ -31,7 +31,7 @@ data Binder a
3131 -- |
3232 -- A binder which binds its input to an identifier
3333 --
34− | NamedBinder a Ident (Binder a) deriving (Show, Read, Functor)
34+ | NamedBinder a Ident (Binder a) deriving (Show, Functor)
3535
3636
3737extractBinderAnn :: Binder a -> a
src/Language/PureScript/CoreFn/Desugar.hs+17−25
@@ -1,30 +1,28 @@
11module Language.PureScript.CoreFn.Desugar (moduleToCoreFn) where
22
3−import Prelude ()
43import Prelude.Compat
54
5+import Control.Arrow (second, (***))
66
77import Data.Function (on)
88import Data.List (sort, sortBy, nub)
99import Data.Maybe (mapMaybe)
1010import qualified Data.Map as M
1111
12−import Control.Arrow (second, (***))
13−
14−import Language.PureScript.Crash
12+import Language.PureScript.AST.Literals
1513import Language.PureScript.AST.SourcePos
1614import Language.PureScript.AST.Traversals
15+import Language.PureScript.Comments
1716import Language.PureScript.CoreFn.Ann
1817import Language.PureScript.CoreFn.Binders
1918import Language.PureScript.CoreFn.Expr
20−import Language.PureScript.AST.Literals
2119import Language.PureScript.CoreFn.Meta
2220import Language.PureScript.CoreFn.Module
21+import Language.PureScript.Crash
2322import Language.PureScript.Environment
2423import Language.PureScript.Names
2524import Language.PureScript.Sugar.TypeClasses (typeClassMemberName, superClassDictionaryNames)
2625import Language.PureScript.Types
27−import Language.PureScript.Comments
2826import qualified Language.PureScript.AST as A
2927
3028-- |
@@ -72,12 +70,6 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
7270 declToCoreFn ss _ (A.DataBindingGroupDeclaration ds) = concatMap (declToCoreFn ss []) ds
7371 declToCoreFn ss com (A.ValueDeclaration name _ _ (Right e)) =
7472 [NonRec (ssA ss) name (exprToCoreFn ss com Nothing e)]
75− declToCoreFn ss com (A.FixityDeclaration _ name (Just (Qualified mn' (A.AliasValue name')))) =
76− let meta = getValueMeta (Qualified mn' name')
77− in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) (Qualified mn' name'))]
78− declToCoreFn ss com (A.FixityDeclaration _ name (Just (Qualified mn' (A.AliasConstructor name')))) =
79− let meta = Just $ getConstructorMeta (Qualified mn' name')
80− in [NonRec (ssA ss) (Op name) (Var (ss, com, Nothing, meta) (Qualified mn' (properToIdent name')))]
8173 declToCoreFn ss _ (A.BindingGroupDeclaration ds) =
8274 [Rec $ map (\(name, _, e) -> ((ssA ss, name), exprToCoreFn ss [] Nothing e)) ds]
8375 declToCoreFn ss com (A.TypeClassDeclaration name _ supers members) =
@@ -206,31 +198,31 @@ moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =
206198findQualModules :: [A.Declaration] -> [(Ann, ModuleName)]
207199findQualModules decls =
208200 let (f, _, _, _, _) = everythingOnValues (++) fqDecls fqValues fqBinders (const []) (const [])
209− in f `concatMap` decls
201+ in map (nullAnn,) $ f `concatMap` decls
210202 where
211− fqDecls :: A.Declaration -> [(Ann, ModuleName)]
212− fqDecls (A.TypeInstanceDeclaration _ _ q _ _) = getQual q
213− fqDecls (A.FixityDeclaration _ _ (Just q)) = getQual q
203+ fqDecls :: A.Declaration -> [ModuleName]
204+ fqDecls (A.TypeInstanceDeclaration _ _ q _ _) = getQual' q
205+ fqDecls (A.ValueFixityDeclaration _ q _) = getQual' q
206+ fqDecls (A.TypeFixityDeclaration _ q _) = getQual' q
214207 fqDecls _ = []
215208
216− fqValues :: A.Expr -> [(Ann, ModuleName)]
217− fqValues (A.Var q) = getQual q
218− fqValues (A.Constructor q) = getQual q
209+ fqValues :: A.Expr -> [ModuleName]
210+ fqValues (A.Var q) = getQual' q
211+ fqValues (A.Constructor q) = getQual' q
219212 fqValues _ = []
220213
221− fqBinders :: A.Binder -> [(Ann, ModuleName)]
222− fqBinders (A.ConstructorBinder q _) = getQual q
214+ fqBinders :: A.Binder -> [ModuleName]
215+ fqBinders (A.ConstructorBinder q _) = getQual' q
223216 fqBinders _ = []
224217
225− getQual :: Qualified a -> [(Ann, ModuleName)]
226− getQual (Qualified (Just mn) _) = [(nullAnn, mn)]
227− getQual _ = []
218+ getQual' :: Qualified a -> [ModuleName]
219+ getQual' = maybe [] return . getQual
228220
229221-- |
230222-- Desugars import declarations from AST to CoreFn representation.
231223--
232224importToCoreFn :: A.Declaration -> Maybe (Ann, ModuleName)
233−importToCoreFn (A.ImportDeclaration name _ _ _) = Just (nullAnn, name)
225+importToCoreFn (A.ImportDeclaration name _ _) = Just (nullAnn, name)
234226importToCoreFn (A.PositionedDeclaration ss _ d) =
235227 ((,) (Just ss, [], Nothing, Nothing) . snd) <$> importToCoreFn d
236228importToCoreFn _ = Nothing
src/Language/PureScript/CoreFn/Expr.hs+6−6
@@ -1,14 +1,14 @@
1−{-# LANGUAGE DeriveFunctor #-}
2−
31-- |
42-- The core functional representation
53--
64module Language.PureScript.CoreFn.Expr where
75
6+import Prelude.Compat
7+
88import Control.Arrow ((***))
99
10−import Language.PureScript.CoreFn.Binders
1110import Language.PureScript.AST.Literals
11+import Language.PureScript.CoreFn.Binders
1212import Language.PureScript.Names
1313
1414-- |
@@ -51,7 +51,7 @@ data Expr a
5151 -- A let binding
5252 --
5353 | Let a [Bind a] (Expr a)
54− deriving (Show, Read, Functor)
54+ deriving (Show, Functor)
5555
5656-- |
5757-- A let or module binding.
@@ -64,7 +64,7 @@ data Bind a
6464 -- |
6565 -- Mutually recursive binding group for several values
6666 --
67− | Rec [((a, Ident), Expr a)] deriving (Show, Read, Functor)
67+ | Rec [((a, Ident), Expr a)] deriving (Show, Functor)
6868
6969-- |
7070-- A guard is just a boolean-valued expression that appears alongside a set of binders
@@ -83,7 +83,7 @@ data CaseAlternative a = CaseAlternative
8383 -- The result expression or a collect of guarded expressions
8484 --
8585 , caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a)
86− } deriving (Show, Read)
86+ } deriving (Show)
8787
8888instance Functor CaseAlternative where
8989
src/Language/PureScript/CoreFn/Meta.hs+4−2
@@ -3,6 +3,8 @@
33--
44module Language.PureScript.CoreFn.Meta where
55
6+import Prelude.Compat
7+
68import Language.PureScript.Names
79
810-- |
@@ -24,7 +26,7 @@ data Meta
2426 -- |
2527 -- The contained reference is for a foreign member
2628 --
27− | IsForeign deriving (Show, Read, Eq)
29+ | IsForeign deriving (Show, Eq)
2830
2931-- |
3032-- Data constructor metadata
@@ -37,4 +39,4 @@ data ConstructorType
3739 -- |
3840 -- The constructor is for a type with multiple construcors
3941 --
40− | SumType deriving (Show, Read, Eq)
42+ | SumType deriving (Show, Eq)
src/Language/PureScript/CoreFn/Module.hs+6−15
@@ -1,24 +1,15 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.CoreFn.Module
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | The CoreFn module representation
12−--
13−-----------------------------------------------------------------------------
14−
151module Language.PureScript.CoreFn.Module where
162
3+import Prelude.Compat
4+
175import Language.PureScript.Comments
186import Language.PureScript.CoreFn.Expr
197import Language.PureScript.Names
208import Language.PureScript.Types
219
10+-- |
11+-- The CoreFn module representation
12+--
2213data Module a = Module
2314 { moduleComments :: [Comment]
2415 , moduleName :: ModuleName
@@ -26,6 +17,6 @@ data Module a = Module
2617 , moduleExports :: [Ident]
2718 , moduleForeign :: [ForeignDecl]
2819 , moduleDecls :: [Bind a]
29− } deriving (Show, Read)
20+ } deriving (Show)
3021
3122type ForeignDecl = (Ident, Type)
src/Language/PureScript/CoreFn/Traversals.hs+3−1
@@ -3,11 +3,13 @@
33--
44module Language.PureScript.CoreFn.Traversals where
55
6+import Prelude.Compat
7+
68import Control.Arrow (second, (***), (+++))
79
10+import Language.PureScript.AST.Literals
811import Language.PureScript.CoreFn.Binders
912import Language.PureScript.CoreFn.Expr
10−import Language.PureScript.AST.Literals
1113
1214everywhereOnValues :: (Bind a -> Bind a) ->
1315 (Expr a -> Expr a) ->
src/Language/PureScript/Crash.hs+11−9
@@ -1,9 +1,11 @@
1−module Language.PureScript.Crash where
2−
3−-- | Exit with an error message and a crash report link.
4−internalError :: String -> a
5−internalError =
6− error
7− . ("An internal error ocurred during compilation: " ++)
8− . (++ "\nPlease report this at https://github.com/purescript/purescript/issues")
9− . show
1+module Language.PureScript.Crash where
2+
3+import Prelude.Compat
4+
5+-- | Exit with an error message and a crash report link.
6+internalError :: String -> a
7+internalError =
8+ error
9+ . ("An internal error ocurred during compilation: " ++)
10+ . (++ "\nPlease report this at https://github.com/purescript/purescript/issues")
11+ . show
src/Language/PureScript/Docs.hs+4−4
@@ -6,9 +6,9 @@ module Language.PureScript.Docs (
66 module Docs
77) where
88
9−import Language.PureScript.Docs.Types as Docs
10−import Language.PureScript.Docs.RenderedCode.Types as Docs
11−import Language.PureScript.Docs.RenderedCode.Render as Docs
129import Language.PureScript.Docs.Convert as Docs
13−import Language.PureScript.Docs.Render as Docs
1410import Language.PureScript.Docs.ParseAndBookmark as Docs
11+import Language.PureScript.Docs.Render as Docs
12+import Language.PureScript.Docs.RenderedCode.Render as Docs
13+import Language.PureScript.Docs.RenderedCode.Types as Docs
14+import Language.PureScript.Docs.Types as Docs
src/Language/PureScript/Docs/AsMarkdown.hs+18−24
@@ -1,6 +1,3 @@
1−{-# LANGUAGE RecordWildCards #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
41module Language.PureScript.Docs.AsMarkdown
52 ( renderModulesAsMarkdown
63 , Docs
@@ -9,19 +6,18 @@ module Language.PureScript.Docs.AsMarkdown
96 , codeToString
107 ) where
118
12−import Prelude ()
139import Prelude.Compat
1410
1511import Control.Monad (unless, zipWithM_)
16−import Control.Monad.Writer (Writer, tell, execWriter)
1712import Control.Monad.Error.Class (MonadError)
13+import Control.Monad.Writer (Writer, tell, execWriter)
14+
1815import Data.Foldable (for_)
1916import Data.List (partition)
2017
21−import qualified Language.PureScript as P
22−
23−import Language.PureScript.Docs.Types
2418import Language.PureScript.Docs.RenderedCode
19+import Language.PureScript.Docs.Types
20+import qualified Language.PureScript as P
2521import qualified Language.PureScript.Docs.Convert as Convert
2622import qualified Language.PureScript.Docs.Render as Render
2723
@@ -63,8 +59,6 @@ declAsMarkdown mn decl@Declaration{..} = do
6359 zipWithM_ (\f c -> tell' (childToString f c)) (First : repeat NotFirst) children
6460 spacer
6561
66− for_ declFixity (\fixity -> fixityAsMarkdown fixity >> spacer)
67−
6862 for_ declComments tell'
6963
7064 unless (null instances) $ do
@@ -86,19 +80,19 @@ codeToString = outputWith elemAsMarkdown
8680 elemAsMarkdown (Keyword x) = x
8781 elemAsMarkdown Space = " "
8882
89−fixityAsMarkdown :: P.Fixity -> Docs
90−fixityAsMarkdown (P.Fixity associativity precedence) =
91− tell' $ concat [ "_"
92− , associativityStr
93− , " / precedence "
94− , show precedence
95− , "_"
96− ]
97− where
98− associativityStr = case associativity of
99− P.Infixl -> "left-associative"
100− P.Infixr -> "right-associative"
101− P.Infix -> "non-associative"
83+-- fixityAsMarkdown :: P.Fixity -> Docs
84+-- fixityAsMarkdown (P.Fixity associativity precedence) =
85+-- tell' $ concat [ "_"
86+-- , associativityStr
87+-- , " / precedence "
88+-- , show precedence
89+-- , "_"
90+-- ]
91+-- where
92+-- associativityStr = case associativity of
93+-- P.Infixl -> "left-associative"
94+-- P.Infixr -> "right-associative"
95+-- P.Infix -> "non-associative"
10296
10397childToString :: First -> ChildDeclaration -> String
10498childToString f decl@ChildDeclaration{..} =
@@ -116,7 +110,7 @@ childToString f decl@ChildDeclaration{..} =
116110data First
117111 = First
118112 | NotFirst
119− deriving (Show, Read, Eq, Ord)
113+ deriving (Show, Eq, Ord)
120114
121115type Docs = Writer [String] ()
122116
src/Language/PureScript/Docs/Convert.hs+12−14
@@ -1,6 +1,4 @@
1−{-# LANGUAGE TupleSections #-}
21{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE FlexibleContexts #-}
42
53-- | Functions for converting PureScript ASTs into values of the data types
64-- from Language.PureScript.Docs.
@@ -11,24 +9,23 @@ module Language.PureScript.Docs.Convert
119 , collectBookmarks
1210 ) where
1311
14−import Prelude ()
1512import Prelude.Compat
1613
1714import Control.Arrow ((&&&), second)
1815import Control.Category ((>>>))
1916import Control.Monad
17+import Control.Monad.Error.Class (MonadError)
2018import Control.Monad.State (runStateT)
2119import Control.Monad.Writer.Strict (runWriterT)
22−import Control.Monad.Error.Class (MonadError)
2320import qualified Data.Map as Map
2421
25−import Text.Parsec (eof)
26−import qualified Language.PureScript as P
27−import qualified Language.PureScript.Constants as C
28−
2922import Language.PureScript.Docs.Convert.ReExports (updateReExports)
3023import Language.PureScript.Docs.Convert.Single (convertSingleModule, collectBookmarks)
3124import Language.PureScript.Docs.Types
25+import qualified Language.PureScript as P
26+import qualified Language.PureScript.Constants as C
27+
28+import Text.Parsec (eof)
3229
3330-- |
3431-- Like convertModules, except that it takes a list of modules, together with
@@ -107,8 +104,9 @@ typeCheckIfNecessary modules convertedModules =
107104 else pure convertedModules
108105
109106 where
110− hasWildcards =
111− any ((==) (ValueDeclaration P.TypeWildcard) . declInfo) . modDeclarations
107+ hasWildcards = any (isWild . declInfo) . modDeclarations
108+ isWild (ValueDeclaration P.TypeWildcard{}) = True
109+ isWild _ = False
112110
113111 go = do
114112 checkEnv <- snd <$> typeCheck modules
@@ -147,7 +145,7 @@ insertValueTypes ::
147145insertValueTypes env m =
148146 m { modDeclarations = map go (modDeclarations m) }
149147 where
150− go (d@Declaration { declInfo = ValueDeclaration P.TypeWildcard }) =
148+ go (d@Declaration { declInfo = ValueDeclaration P.TypeWildcard{} }) =
151149 let
152150 ident = parseIdent (declTitle d)
153151 ty = lookupName ident
@@ -160,7 +158,7 @@ insertValueTypes env m =
160158 either (err . ("failed to parse Ident: " ++)) id . runParser P.parseIdent
161159
162160 lookupName name =
163− let key = (modName m, name)
161+ let key = P.Qualified (Just (modName m)) name
164162 in case Map.lookup key (P.names env) of
165163 Just (ty, _, _) ->
166164 ty
@@ -187,8 +185,8 @@ partiallyDesugar = P.evalSupplyT 0 . desugar'
187185 where
188186 desugar' =
189187 traverse P.desugarDoModule
190− >=> P.desugarCasesModule
191− >=> P.desugarTypeDeclarationsModule
188+ >=> traverse P.desugarCasesModule
189+ >=> traverse P.desugarTypeDeclarationsModule
192190 >=> ignoreWarnings . P.desugarImportsWithEnv []
193191
194192 ignoreWarnings = fmap fst . runWriterT
src/Language/PureScript/Docs/Convert/ReExports.hs+81−67
@@ -1,29 +1,24 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−
51module Language.PureScript.Docs.Convert.ReExports
62 ( updateReExports
73 ) where
84
9−import Prelude ()
105import Prelude.Compat
116
7+import Control.Arrow ((&&&), second)
128import Control.Monad
13−import Control.Monad.Trans.State.Strict (execState)
9+import Control.Monad.Reader.Class (MonadReader, ask)
1410import Control.Monad.State.Class (MonadState, gets, modify)
1511import Control.Monad.Trans.Reader (runReaderT)
16−import Control.Monad.Reader.Class (MonadReader, ask)
17−import Control.Arrow ((&&&), first, second)
12+import Control.Monad.Trans.State.Strict (execState)
13+
1814import Data.Either
19−import Data.Maybe (mapMaybe)
2015import Data.Map (Map)
21−import qualified Data.Map as Map
16+import Data.Maybe (mapMaybe)
2217import Data.Monoid ((<>))
23−
24−import qualified Language.PureScript as P
18+import qualified Data.Map as Map
2519
2620import Language.PureScript.Docs.Types
21+import qualified Language.PureScript as P
2722
2823-- |
2924-- Given:
@@ -40,8 +35,7 @@ updateReExports ::
4035 [P.ModuleName] ->
4136 Map P.ModuleName Module ->
4237 Map P.ModuleName Module
43−updateReExports env order modules =
44− execState action modules
38+updateReExports env order = execState action
4539 where
4640 action =
4741 void (traverse go order)
@@ -102,39 +96,50 @@ getReExports env mn =
10296-- * Filters type class declarations to ensure that only re-exported type
10397-- class members are listed.
10498--
105−collectDeclarations ::
99+collectDeclarations :: forall m.
106100 (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m) =>
107101 P.Imports ->
108102 P.Exports ->
109103 m [(P.ModuleName, [Declaration])]
110104collectDeclarations imports exports = do
111− valsAndMembers <- collect lookupValueDeclaration impVals expVals
112− typeClasses <- collect lookupTypeClassDeclaration impTCs expTCs
113− types <- collect lookupTypeDeclaration impTypes expTypes
114− typeOps <- collect lookupTypeOpDeclaration impTypeOps expTypeOps
105+ valsAndMembers <- collect lookupValueDeclaration impVals expVals
106+ valOps <- collect lookupValueOpDeclaration impValOps expValOps
107+ typeClasses <- collect lookupTypeClassDeclaration impTCs expTCs
108+ types <- collect lookupTypeDeclaration impTypes expTypes
109+ typeOps <- collect lookupTypeOpDeclaration impTypeOps expTypeOps
115110
116111 (vals, classes) <- handleTypeClassMembers valsAndMembers typeClasses
117112
118113 let filteredTypes = filterDataConstructors expCtors types
119− let filteredClasses = filterTypeClassMembers (map fst expVals) classes
114+ let filteredClasses = filterTypeClassMembers (Map.keys expVals) classes
120115
121− pure (Map.toList (Map.unionsWith (<>) [filteredTypes, typeOps, filteredClasses, vals]))
116+ pure (Map.toList (Map.unionsWith (<>) [filteredTypes, filteredClasses, vals, valOps, typeOps]))
122117
123118 where
119+
120+ collect
121+ :: (Eq a, Show a)
122+ => (P.ModuleName -> a -> m (P.ModuleName, [b]))
123+ -> [P.ImportRecord a]
124+ -> Map a P.ModuleName
125+ -> m (Map P.ModuleName [b])
124126 collect lookup' imps exps = do
125− imps' <- traverse (findImport imps) exps
127+ imps' <- traverse (findImport imps) $ Map.toList exps
126128 Map.fromListWith (<>) <$> traverse (uncurry lookup') imps'
127129
128130 expVals = P.exportedValues exports
129131 impVals = concat (Map.elems (P.importedValues imports))
130132
131− expTypes = map (first fst) (P.exportedTypes exports)
133+ expValOps = P.exportedValueOps exports
134+ impValOps = concat (Map.elems (P.importedValueOps imports))
135+
136+ expTypes = Map.map snd (P.exportedTypes exports)
132137 impTypes = concat (Map.elems (P.importedTypes imports))
133138
134139 expTypeOps = P.exportedTypeOps exports
135140 impTypeOps = concat (Map.elems (P.importedTypeOps imports))
136141
137− expCtors = concatMap (snd . fst) (P.exportedTypes exports)
142+ expCtors = concatMap fst (Map.elems (P.exportedTypes exports))
138143
139144 expTCs = P.exportedTypeClasses exports
140145 impTCs = concat (Map.elems (P.importedTypeClasses imports))
@@ -226,6 +231,20 @@ lookupValueDeclaration importedFrom ident = do
226231 thd :: (a, b, c) -> c
227232 thd (_, _, x) = x
228233
234+lookupValueOpDeclaration
235+ :: (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m)
236+ => P.ModuleName
237+ -> P.OpName 'P.ValueOpName
238+ -> m (P.ModuleName, [Declaration])
239+lookupValueOpDeclaration importedFrom op = do
240+ decls <- lookupModuleDeclarations "lookupValueOpDeclaration" importedFrom
241+ case filter (\d -> declTitle d == P.showOp op && isValueAlias d) decls of
242+ [d] ->
243+ pure (importedFrom, [d])
244+ other ->
245+ internalErrorInModule
246+ ("lookupValueOpDeclaration: unexpected result for: " ++ show other)
247+
229248-- |
230249-- Extract a particular type declaration. For data declarations, constructors
231250-- are only included in the output if they are listed in the arguments.
@@ -247,16 +266,15 @@ lookupTypeDeclaration importedFrom ty = do
247266 internalErrorInModule
248267 ("lookupTypeDeclaration: unexpected result: " ++ show other)
249268
250−lookupTypeOpDeclaration ::
251− (MonadState (Map P.ModuleName Module) m,
252− MonadReader P.ModuleName m) =>
253− P.ModuleName ->
254− P.Ident ->
255− m (P.ModuleName, [Declaration])
269+lookupTypeOpDeclaration
270+ :: (MonadState (Map P.ModuleName Module) m,MonadReader P.ModuleName m)
271+ => P.ModuleName
272+ -> P.OpName 'P.TypeOpName
273+ -> m (P.ModuleName, [Declaration])
256274lookupTypeOpDeclaration importedFrom tyOp = do
257275 decls <- lookupModuleDeclarations "lookupTypeOpDeclaration" importedFrom
258276 let
259− ds = filter (\d -> declTitle d == ("type " ++ P.showIdent tyOp) && isTypeAlias d) decls
277+ ds = filter (\d -> declTitle d == ("type " ++ P.showOp tyOp) && isTypeAlias d) decls
260278 case ds of
261279 [d] ->
262280 pure (importedFrom, [d])
@@ -264,12 +282,11 @@ lookupTypeOpDeclaration importedFrom tyOp = do
264282 internalErrorInModule
265283 ("lookupTypeOpDeclaration: unexpected result: " ++ show other)
266284
267−lookupTypeClassDeclaration ::
268− (MonadState (Map P.ModuleName Module) m,
269− MonadReader P.ModuleName m) =>
270− P.ModuleName ->
271− P.ProperName 'P.ClassName ->
272− m (P.ModuleName, [Declaration])
285+lookupTypeClassDeclaration
286+ :: (MonadState (Map P.ModuleName Module) m, MonadReader P.ModuleName m)
287+ => P.ModuleName
288+ -> P.ProperName 'P.ClassName
289+ -> m (P.ModuleName, [Declaration])
273290lookupTypeClassDeclaration importedFrom tyClass = do
274291 decls <- lookupModuleDeclarations "lookupTypeClassDeclaration" importedFrom
275292 let
@@ -374,10 +391,10 @@ instance Monoid TypeClassEnv where
374391--
375392-- Returns a tuple of (values, type classes).
376393--
377−handleEnv ::
378− (MonadReader P.ModuleName m) =>
379− TypeClassEnv ->
380− m ([Declaration], [Declaration])
394+handleEnv
395+ :: (MonadReader P.ModuleName m)
396+ => TypeClassEnv
397+ -> m ([Declaration], [Declaration])
381398handleEnv TypeClassEnv{..} =
382399 envUnhandledMembers
383400 |> foldM go (envValues, mkMap envTypeClasses)
@@ -405,7 +422,6 @@ handleEnv TypeClassEnv{..} =
405422 , declComments = cdeclComments
406423 , declSourceSpan = cdeclSourceSpan
407424 , declChildren = []
408− , declFixity = Nothing
409425 , declInfo = ValueDeclaration (addConstraint constraint typ)
410426 }
411427 _ ->
@@ -426,10 +442,10 @@ splitMap = foldl go (Map.empty, Map.empty) . Map.toList
426442-- Given a list of exported constructor names, remove any data constructor
427443-- names in the provided Map of declarations which are not in the list.
428444--
429−filterDataConstructors ::
430− [P.ProperName 'P.ConstructorName] ->
431− Map P.ModuleName [Declaration] ->
432− Map P.ModuleName [Declaration]
445+filterDataConstructors
446+ :: [P.ProperName 'P.ConstructorName]
447+ -> Map P.ModuleName [Declaration]
448+ -> Map P.ModuleName [Declaration]
433449filterDataConstructors =
434450 filterExportedChildren isDataConstructor P.runProperName
435451
@@ -438,27 +454,25 @@ filterDataConstructors =
438454-- type class member names in the provided Map of declarations which are not in
439455-- the list.
440456--
441−filterTypeClassMembers ::
442− [P.Ident] ->
443− Map P.ModuleName [Declaration] ->
444− Map P.ModuleName [Declaration]
457+filterTypeClassMembers
458+ :: [P.Ident]
459+ -> Map P.ModuleName [Declaration]
460+ -> Map P.ModuleName [Declaration]
445461filterTypeClassMembers =
446462 filterExportedChildren isTypeClassMember P.showIdent
447463
448−filterExportedChildren ::
449− (Functor f) =>
450− (ChildDeclaration -> Bool) ->
451− (name -> String) ->
452− [name] ->
453− f [Declaration] ->
454− f [Declaration]
455−filterExportedChildren isTargetedKind runName expNames =
456− fmap filterDecls
464+filterExportedChildren
465+ :: (Functor f)
466+ => (ChildDeclaration -> Bool)
467+ -> (name -> String)
468+ -> [name]
469+ -> f [Declaration]
470+ -> f [Declaration]
471+filterExportedChildren isTargetedKind runName expNames = fmap filterDecls
457472 where
458473 filterDecls =
459− map (filterChildren (\c -> not (isTargetedKind c) ||
460− cdeclTitle c `elem` expNames'))
461−
474+ map $ filterChildren $ \c ->
475+ not (isTargetedKind c) || cdeclTitle c `elem` expNames'
462476 expNames' = map runName expNames
463477
464478allDeclarations :: Module -> [Declaration]
@@ -471,10 +485,10 @@ x |> f = f x
471485internalError :: String -> a
472486internalError = P.internalError . ("Docs.Convert.ReExports: " ++)
473487
474−internalErrorInModule ::
475− (MonadReader P.ModuleName m) =>
476− String ->
477− m a
488+internalErrorInModule
489+ :: (MonadReader P.ModuleName m)
490+ => String
491+ -> m a
478492internalErrorInModule msg = do
479493 mn <- ask
480494 internalError
@@ -489,7 +503,7 @@ typeClassConstraintFor :: Declaration -> Maybe P.Constraint
489503typeClassConstraintFor Declaration{..} =
490504 case declInfo of
491505 TypeClassDeclaration tyArgs _ ->
492− Just (P.Qualified Nothing (P.ProperName declTitle), mkConstraint tyArgs)
506+ Just (P.Constraint (P.Qualified Nothing (P.ProperName declTitle)) (mkConstraint tyArgs) Nothing)
493507 _ ->
494508 Nothing
495509 where
src/Language/PureScript/Docs/Convert/Single.hs+16−52
@@ -1,26 +1,19 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
4−{-# LANGUAGE ViewPatterns #-}
5−{-# LANGUAGE FlexibleContexts #-}
6−
71module Language.PureScript.Docs.Convert.Single
82 ( convertSingleModule
93 , collectBookmarks
104 ) where
115
12−import Prelude ()
136import Prelude.Compat
14−import Data.Maybe (mapMaybe, isNothing)
157
16−import Control.Monad
178import Control.Category ((>>>))
18−import Data.Either
19−import Data.List (nub, isPrefixOf, isSuffixOf)
9+import Control.Monad
2010
21−import qualified Language.PureScript as P
11+import Data.Either
12+import Data.List (nub)
13+import Data.Maybe (mapMaybe)
2214
2315import Language.PureScript.Docs.Types
16+import qualified Language.PureScript as P
2417
2518-- |
2619-- Convert a single Module, but ignore re-exports; any re-exported types or
@@ -35,7 +28,6 @@ convertSingleModule m@(P.Module _ coms moduleName _ _) =
3528 P.exportedDeclarations
3629 >>> mapMaybe (\d -> getDeclarationTitle d >>= convertDeclaration d)
3730 >>> augmentDeclarations
38− >>> map addDefaultFixity
3931
4032-- | The data type for an intermediate stage which we go through during
4133-- converting.
@@ -65,12 +57,8 @@ type IntermediateDeclaration
6557-- since they appear at the top level in the AST, and since they might need to
6658-- appear as children in two places (for example, if a data type defined in a
6759-- module is an instance of a type class also defined in that module).
68−--
69−-- The AugmentFixity constructor allows us to augment operator definitions
70−-- with their associativity and precedence.
7160data DeclarationAugment
7261 = AugmentChild ChildDeclaration
73− | AugmentFixity P.Fixity
7462
7563-- | Augment top-level declarations; the second pass. See the comments under
7664-- the type synonym IntermediateDeclaration for more information.
@@ -84,28 +72,8 @@ augmentDeclarations (partitionEithers -> (augments, toplevels)) =
8472 then augmentWith a d
8573 else d) ds
8674
87− augmentWith a d =
88− case a of
89− AugmentChild child ->
90− d { declChildren = declChildren d ++ [child] }
91− AugmentFixity fixity ->
92− d { declFixity = Just fixity }
93−
94−-- | Add the default operator fixity for operators which do not have associated
95−-- fixity declarations.
96−--
97−-- TODO: This may no longer be necessary after issue 806 is resolved, hopefully
98−-- in 0.9.
99−addDefaultFixity :: Declaration -> Declaration
100−addDefaultFixity decl@Declaration{..}
101− | isOp declTitle && isNothing declFixity =
102− decl { declFixity = Just defaultFixity }
103− | otherwise =
104− decl
105− where
106− isOp :: String -> Bool
107− isOp str = "(" `isPrefixOf` str && ")" `isSuffixOf` str
108− defaultFixity = P.Fixity P.Infixl (-1)
75+ augmentWith (AugmentChild child) d =
76+ d { declChildren = declChildren d ++ [child] }
10977
11078getDeclarationTitle :: P.Declaration -> Maybe String
11179getDeclarationTitle (P.ValueDeclaration name _ _ _) = Just (P.showIdent name)
@@ -115,8 +83,8 @@ getDeclarationTitle (P.ExternDataDeclaration name _) = Just (P.runProperName nam
11583getDeclarationTitle (P.TypeSynonymDeclaration name _ _) = Just (P.runProperName name)
11684getDeclarationTitle (P.TypeClassDeclaration name _ _ _) = Just (P.runProperName name)
11785getDeclarationTitle (P.TypeInstanceDeclaration name _ _ _ _) = Just (P.showIdent name)
118−getDeclarationTitle (P.FixityDeclaration _ name (Just (P.Qualified _ P.AliasType{}))) = Just ("type (" ++ name ++ ")")
119−getDeclarationTitle (P.FixityDeclaration _ name _) = Just ("(" ++ name ++ ")")
86+getDeclarationTitle (P.TypeFixityDeclaration _ _ op) = Just ("type " ++ P.showOp op)
87+getDeclarationTitle (P.ValueFixityDeclaration _ _ op) = Just (P.showOp op)
12088getDeclarationTitle (P.PositionedDeclaration _ _ d) = getDeclarationTitle d
12189getDeclarationTitle _ = Nothing
12290
@@ -127,7 +95,6 @@ mkDeclaration title info =
12795 , declComments = Nothing
12896 , declSourceSpan = Nothing
12997 , declChildren = []
130− , declFixity = Nothing
13198 , declInfo = info
13299 }
133100
@@ -137,10 +104,10 @@ basicDeclaration title info = Just $ Right $ mkDeclaration title info
137104convertDeclaration :: P.Declaration -> String -> Maybe IntermediateDeclaration
138105convertDeclaration (P.ValueDeclaration _ _ _ (Right (P.TypedValue _ _ ty))) title =
139106 basicDeclaration title (ValueDeclaration ty)
140−convertDeclaration (P.ValueDeclaration {}) title =
107+convertDeclaration P.ValueDeclaration{} title =
141108 -- If no explicit type declaration was provided, insert a wildcard, so that
142109 -- the actual type will be added during type checking.
143− basicDeclaration title (ValueDeclaration P.TypeWildcard)
110+ basicDeclaration title (ValueDeclaration P.TypeWildcard{})
144111convertDeclaration (P.ExternDeclaration _ ty) title =
145112 basicDeclaration title (ValueDeclaration ty)
146113convertDeclaration (P.DataDeclaration dtype _ args ctors) title =
@@ -177,10 +144,10 @@ convertDeclaration (P.TypeInstanceDeclaration _ constraints className tys _) tit
177144
178145 childDecl = ChildDeclaration title Nothing Nothing (ChildInstance constraints classApp)
179146 classApp = foldl P.TypeApp (P.TypeConstructor (fmap P.coerceProperName className)) tys
180−convertDeclaration (P.FixityDeclaration fixity _ Nothing) title =
181− Just (Left ([title], AugmentFixity fixity))
182−convertDeclaration (P.FixityDeclaration fixity _ (Just alias)) title =
183− Just $ Right $ (mkDeclaration title (AliasDeclaration alias fixity)) { declFixity = Just fixity }
147+convertDeclaration (P.ValueFixityDeclaration fixity (P.Qualified mn alias) _) title =
148+ Just $ Right $ mkDeclaration title (AliasDeclaration fixity (P.Qualified mn (Right alias)))
149+convertDeclaration (P.TypeFixityDeclaration fixity (P.Qualified mn alias) _) title =
150+ Just $ Right $ mkDeclaration title (AliasDeclaration fixity (P.Qualified mn (Left alias)))
184151convertDeclaration (P.PositionedDeclaration srcSpan com d') title =
185152 fmap (addComments . addSourceSpan) (convertDeclaration d' title)
186153 where
@@ -196,10 +163,7 @@ convertDeclaration (P.PositionedDeclaration srcSpan com d') title =
196163 Left (withAugmentChild (\d -> d { cdeclSourceSpan = Just srcSpan })
197164 augment)
198165
199− withAugmentChild f (t, a) =
200− case a of
201− AugmentChild d -> (t, AugmentChild (f d))
202− _ -> (t, a)
166+ withAugmentChild f (t, AugmentChild d) = (t, AugmentChild (f d))
203167convertDeclaration _ _ = Nothing
204168
205169convertComments :: [P.Comment] -> Maybe String
src/Language/PureScript/Docs/ParseAndBookmark.hs+7−11
@@ -1,26 +1,22 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
41module Language.PureScript.Docs.ParseAndBookmark
52 ( parseAndBookmark
63 ) where
74
8−import Prelude ()
95import Prelude.Compat
106
11−import qualified Data.Map as M
127import Control.Arrow (first)
13−
148import Control.Monad.Error.Class (MonadError(..))
159import Control.Monad.IO.Class (MonadIO(..))
1610
17−import Web.Bower.PackageMeta (PackageName)
11+import qualified Data.Map as M
12+
13+import Language.PureScript.Docs.Convert (collectBookmarks)
14+import Language.PureScript.Docs.Types
15+import qualified Language.PureScript as P
1816
1917import System.IO.UTF8 (readUTF8File)
2018
21−import qualified Language.PureScript as P
22−import Language.PureScript.Docs.Types
23−import Language.PureScript.Docs.Convert (collectBookmarks)
19+import Web.Bower.PackageMeta (PackageName)
2420
2521-- |
2622-- Given:
@@ -48,7 +44,7 @@ parseAndBookmark inputFiles depsFiles = do
4844 addBookmarks <$> parseFiles (inputFiles' ++ depsFiles')
4945
5046parseFiles ::
51− (MonadError P.MultipleErrors m, MonadIO m) =>
47+ (MonadError P.MultipleErrors m) =>
5248 [(FileInfo, FilePath)]
5349 -> m [(FileInfo, P.Module)]
5450parseFiles =
src/Language/PureScript/Docs/Render.hs+26−19
@@ -1,6 +1,5 @@
1−{-# LANGUAGE RecordWildCards #-}
2−
3−-- | Functions for creating `RenderedCode` values from data types in
1+-- |
2+-- Functions for creating `RenderedCode` values from data types in
43-- Language.PureScript.Docs.Types.
54--
65-- These functions are the ones that are used in markdown/html documentation
@@ -10,13 +9,15 @@
109
1110module Language.PureScript.Docs.Render where
1211
12+import Prelude.Compat
13+
1314import Data.Maybe (maybeToList)
1415import Data.Monoid ((<>))
15−import qualified Language.PureScript as P
1616
17−import Language.PureScript.Docs.Types
1817import Language.PureScript.Docs.RenderedCode
18+import Language.PureScript.Docs.Types
1919import Language.PureScript.Docs.Utils.MonoidExtras
20+import qualified Language.PureScript as P
2021
2122renderDeclaration :: Declaration -> RenderedCode
2223renderDeclaration = renderDeclarationWithOptions defaultRenderTypeOptions
@@ -58,27 +59,33 @@ renderDeclarationWithOptions opts Declaration{..} =
5859 syntax "("
5960 <> mintersperse (syntax "," <> sp) (map renderConstraint implies)
6061 <> syntax ")" <> sp <> syntax "<="
61− AliasDeclaration for@(P.Qualified _ alias) (P.Fixity associativity precedence) ->
62+
63+ AliasDeclaration (P.Fixity associativity precedence) for@(P.Qualified _ alias) ->
6264 [ keywordFixity associativity
6365 , syntax $ show precedence
64− , ident $ renderAlias for
66+ , ident $ renderQualAlias for
6567 , keyword "as"
6668 , ident $ adjustAliasName alias declTitle
6769 ]
6870
6971 where
72+ renderType' :: P.Type -> RenderedCode
7073 renderType' = renderTypeWithOptions opts
71− renderAlias (P.Qualified mn alias)
72− | mn == currentModule opts =
73− P.foldFixityAlias P.runIdent P.runProperName (("type " ++) . P.runProperName) alias
74− | otherwise =
75− P.foldFixityAlias
76− (P.showQualified P.runIdent . P.Qualified mn)
77− (P.showQualified P.runProperName . P.Qualified mn)
78− (("type " ++) . P.showQualified P.runProperName . P.Qualified mn)
79− alias
80−
81− adjustAliasName (P.AliasType{}) title = drop 6 (init title)
74+
75+ renderQualAlias :: FixityAlias -> String
76+ renderQualAlias (P.Qualified mn alias)
77+ | mn == currentModule opts = renderAlias id alias
78+ | otherwise = renderAlias (\f -> P.showQualified f . P.Qualified mn) alias
79+
80+ renderAlias
81+ :: (forall a. (a -> String) -> a -> String)
82+ -> Either (P.ProperName 'P.TypeName) (Either P.Ident (P.ProperName 'P.ConstructorName))
83+ -> String
84+ renderAlias f
85+ = either (("type " ++) . f P.runProperName)
86+ $ either (f P.runIdent) (f P.runProperName)
87+
88+ -- adjustAliasName (P.AliasType{}) title = drop 6 (init title)
8289 adjustAliasName _ title = tail (init title)
8390
8491renderChildDeclaration :: ChildDeclaration -> RenderedCode
@@ -107,7 +114,7 @@ renderConstraint :: P.Constraint -> RenderedCode
107114renderConstraint = renderConstraintWithOptions defaultRenderTypeOptions
108115
109116renderConstraintWithOptions :: RenderTypeOptions -> P.Constraint -> RenderedCode
110−renderConstraintWithOptions opts (pn, tys) =
117+renderConstraintWithOptions opts (P.Constraint pn tys _) =
111118 renderTypeWithOptions opts $ foldl P.TypeApp (P.TypeConstructor (fmap P.coerceProperName pn)) tys
112119
113120renderConstraints :: [P.Constraint] -> Maybe RenderedCode
src/Language/PureScript/Docs/RenderedCode.hs+8−11
@@ -1,11 +1,8 @@
1−
2−-- | Data types and functions for representing a simplified form of PureScript
3−-- code, intended for use in e.g. HTML documentation.
4−
5−module Language.PureScript.Docs.RenderedCode (
6− module RenderedCode
7−) where
8−
9−import Language.PureScript.Docs.RenderedCode.Types as RenderedCode
10−import Language.PureScript.Docs.RenderedCode.Render as RenderedCode
11−
1+
2+-- | Data types and functions for representing a simplified form of PureScript
3+-- code, intended for use in e.g. HTML documentation.
4+
5+module Language.PureScript.Docs.RenderedCode (module RenderedCode) where
6+
7+import Language.PureScript.Docs.RenderedCode.Types as RenderedCode
8+import Language.PureScript.Docs.RenderedCode.Render as RenderedCode
src/Language/PureScript/Docs/RenderedCode/Render.hs+29−28
@@ -1,38 +1,36 @@
11-- | Functions for producing RenderedCode values from PureScript Type values.
22
3−module Language.PureScript.Docs.RenderedCode.Render (
4− renderType,
5− renderTypeAtom,
6− renderRow,
7− renderKind,
8− RenderTypeOptions(..),
9− defaultRenderTypeOptions,
10− renderTypeWithOptions
11−) where
12−
13−import Prelude ()
3+module Language.PureScript.Docs.RenderedCode.Render
4+ ( renderType
5+ , renderTypeAtom
6+ , renderRow
7+ , renderKind
8+ , RenderTypeOptions(..)
9+ , defaultRenderTypeOptions
10+ , renderTypeWithOptions
11+ ) where
12+
1413import Prelude.Compat
1514
16−import Data.Monoid ((<>))
1715import Data.Maybe (fromMaybe)
16+import Data.Monoid ((<>))
1817
1918import Control.Arrow ((<+>))
20−import Control.PatternArrows
19+import Control.PatternArrows as PA
2120
2221import Language.PureScript.Crash
23−import Language.PureScript.Names
24−import Language.PureScript.Types
25−import Language.PureScript.Kinds
26−import Language.PureScript.Pretty.Kinds
27−import Language.PureScript.Environment
28−
2922import Language.PureScript.Docs.RenderedCode.Types
3023import Language.PureScript.Docs.Utils.MonoidExtras
24+import Language.PureScript.Environment
25+import Language.PureScript.Kinds
26+import Language.PureScript.Names
27+import Language.PureScript.Pretty.Kinds
28+import Language.PureScript.Types
3129
3230typeLiterals :: Pattern () Type RenderedCode
3331typeLiterals = mkPattern match
3432 where
35− match TypeWildcard =
33+ match TypeWildcard{} =
3634 Just (syntax "_")
3735 match (TypeVar var) =
3836 Just (ident var)
@@ -51,12 +49,12 @@ typeLiterals = mkPattern match
5149 match (BinaryNoParensType op l r) =
5250 Just $ renderTypeAtom l <> sp <> renderTypeAtom op <> sp <> renderTypeAtom r
5351 match (TypeOp (Qualified mn op)) =
54− Just (ident' (runIdent op) (maybeToContainingModule mn))
52+ Just (ident' (runOpName op) (maybeToContainingModule mn))
5553 match _ =
5654 Nothing
5755
5856renderConstraint :: Constraint -> RenderedCode
59−renderConstraint (pn, tys) =
57+renderConstraint (Constraint pn tys _) =
6058 let instApp = foldl TypeApp (TypeConstructor (fmap coerceProperName pn)) tys
6159 in renderType instApp
6260
@@ -161,7 +159,7 @@ dePrim other = other
161159
162160convert :: RenderTypeOptions -> Type -> Type
163161convert _ (TypeApp (TypeApp f arg) ret) | f == tyFunction = PrettyPrintFunction arg ret
164−convert opts (TypeApp o r) | o == tyObject && prettyPrintObjects opts = PrettyPrintObject r
162+convert opts (TypeApp o r) | o == tyRecord && prettyPrintObjects opts = PrettyPrintObject r
165163convert _ other = other
166164
167165convertForAlls :: Type -> Type
@@ -184,9 +182,10 @@ renderKind = kind . prettyPrintKind
184182-- Render code representing a Type, as it should appear inside parentheses
185183--
186184renderTypeAtom :: Type -> RenderedCode
187−renderTypeAtom =
188− fromMaybe (internalError "Incomplete pattern") . pattern matchTypeAtom () . preprocessType defaultRenderTypeOptions
189−
185+renderTypeAtom
186+ = fromMaybe (internalError "Incomplete pattern")
187+ . PA.pattern matchTypeAtom ()
188+ . preprocessType defaultRenderTypeOptions
190189
191190-- |
192191-- Render code representing a Type
@@ -207,5 +206,7 @@ defaultRenderTypeOptions =
207206 }
208207
209208renderTypeWithOptions :: RenderTypeOptions -> Type -> RenderedCode
210−renderTypeWithOptions opts =
211− fromMaybe (internalError "Incomplete pattern") . pattern matchType () . preprocessType opts
209+renderTypeWithOptions opts
210+ = fromMaybe (internalError "Incomplete pattern")
211+ . PA.pattern matchType ()
212+ . preprocessType opts
src/Language/PureScript/Docs/RenderedCode/Types.hs+3−3
@@ -32,13 +32,13 @@ module Language.PureScript.Docs.RenderedCode.Types
3232 , keywordFixity
3333 ) where
3434
35−import Prelude ()
3635import Prelude.Compat
3736
38−import qualified Data.Aeson as A
39−import Data.Aeson.BetterErrors
4037import Control.Monad.Error.Class (MonadError(..))
4138
39+import Data.Aeson.BetterErrors
40+import qualified Data.Aeson as A
41+
4242import qualified Language.PureScript as P
4343
4444-- |
src/Language/PureScript/Docs/Types.hs+24−26
@@ -1,7 +1,4 @@
1−{-# LANGUAGE RecordWildCards #-}
21{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE TupleSections #-}
4−{-# LANGUAGE RankNTypes #-}
52
63module Language.PureScript.Docs.Types
74 ( module Language.PureScript.Docs.Types
@@ -9,25 +6,27 @@ module Language.PureScript.Docs.Types
96 )
107 where
118
12−import Prelude ()
139import Prelude.Compat
1410
1511import Control.Arrow (first, (***))
1612import Control.Monad (when)
17−import Data.Maybe (mapMaybe)
18−import Data.Version
13+
1914import Data.Aeson ((.=))
20−import qualified Data.Aeson as A
2115import Data.Aeson.BetterErrors
22−import Text.ParserCombinators.ReadP (readP_to_S)
23−import Data.Text (Text)
2416import Data.ByteString.Lazy (ByteString)
17+import Data.Either (isLeft, isRight)
18+import Data.Maybe (mapMaybe)
19+import Data.Text (Text)
20+import Data.Version
21+import qualified Data.Aeson as A
2522import qualified Data.Text as T
2623
27−import Web.Bower.PackageMeta hiding (Version, displayError)
28−
2924import qualified Language.PureScript as P
3025
26+import Text.ParserCombinators.ReadP (readP_to_S)
27+
28+import Web.Bower.PackageMeta hiding (Version, displayError)
29+
3130import Language.PureScript.Docs.RenderedCode as ReExports
3231 (RenderedCode, asRenderedCode,
3332 ContainingModule(..), asContainingModule,
@@ -86,7 +85,6 @@ data Declaration = Declaration
8685 , declComments :: Maybe String
8786 , declSourceSpan :: Maybe P.SourceSpan
8887 , declChildren :: [ChildDeclaration]
89− , declFixity :: Maybe P.Fixity -- TODO: remove in 0.9
9088 , declInfo :: DeclarationInfo
9189 }
9290 deriving (Show, Eq, Ord)
@@ -133,9 +131,11 @@ data DeclarationInfo
133131 -- An operator alias declaration, with the member the alias is for and the
134132 -- operator's fixity.
135133 --
136− | AliasDeclaration (P.Qualified P.FixityAlias) P.Fixity
134+ | AliasDeclaration P.Fixity FixityAlias
137135 deriving (Show, Eq, Ord)
138136
137+type FixityAlias = P.Qualified (Either (P.ProperName 'P.TypeName) (Either P.Ident (P.ProperName 'P.ConstructorName)))
138+
139139declInfoToString :: DeclarationInfo -> String
140140declInfoToString (ValueDeclaration _) = "value"
141141declInfoToString (DataDeclaration _ _) = "data"
@@ -167,14 +167,13 @@ isType Declaration{..} =
167167isValueAlias :: Declaration -> Bool
168168isValueAlias Declaration{..} =
169169 case declInfo of
170− (AliasDeclaration (P.Qualified _ P.AliasConstructor{}) _) -> True
171− (AliasDeclaration (P.Qualified _ P.AliasValue{}) _) -> True
170+ AliasDeclaration _ (P.Qualified _ d) -> isRight d
172171 _ -> False
173172
174173isTypeAlias :: Declaration -> Bool
175174isTypeAlias Declaration{..} =
176175 case declInfo of
177− (AliasDeclaration (P.Qualified _ P.AliasType{}) _) -> True
176+ AliasDeclaration _ (P.Qualified _ d) -> isLeft d
178177 _ -> False
179178
180179-- | Discard any children which do not satisfy the given predicate.
@@ -364,7 +363,6 @@ asDeclaration =
364363 <*> key "comments" (perhaps asString)
365364 <*> key "sourceSpan" (perhaps asSourceSpan)
366365 <*> key "children" (eachInArray asChildDeclaration)
367− <*> key "fixity" (perhaps asFixity)
368366 <*> key "info" asDeclarationInfo
369367
370368asReExport :: Parse PackageError (P.ModuleName, [Declaration])
@@ -385,6 +383,9 @@ asFixity =
385383 P.Fixity <$> key "associativity" asAssociativity
386384 <*> key "precedence" asIntegral
387385
386+asFixityAlias :: Parse PackageError FixityAlias
387+asFixityAlias = fromAesonParser
388+
388389parseAssociativity :: String -> Maybe P.Associativity
389390parseAssociativity str = case str of
390391 "infix" -> Just P.Infix
@@ -413,14 +414,11 @@ asDeclarationInfo = do
413414 TypeClassDeclaration <$> key "arguments" asTypeArguments
414415 <*> key "superclasses" (eachInArray asConstraint)
415416 "alias" ->
416− AliasDeclaration <$> key "for" asAliasFor
417− <*> key "fixity" asFixity
417+ AliasDeclaration <$> key "fixity" asFixity
418+ <*> key "alias" asFixityAlias
418419 other ->
419420 throwCustomError (InvalidDeclarationType other)
420421
421−asAliasFor :: Parse e (P.Qualified P.FixityAlias)
422−asAliasFor = fromAesonParser
423−
424422asTypeArguments :: Parse PackageError [(String, Maybe P.Kind)]
425423asTypeArguments = eachInArray asTypeArgument
426424 where
@@ -465,8 +463,9 @@ asSourcePos = P.SourcePos <$> nth 0 asIntegral
465463 <*> nth 1 asIntegral
466464
467465asConstraint :: Parse PackageError P.Constraint
468−asConstraint = (,) <$> nth 0 asQualifiedProperName
469− <*> nth 1 (eachInArray asType)
466+asConstraint = P.Constraint <$> key "constraintClass" asQualifiedProperName
467+ <*> key "constraintArgs" (eachInArray asType)
468+ <*> pure Nothing
470469
471470asQualifiedProperName :: Parse e (P.Qualified (P.ProperName a))
472471asQualifiedProperName = fromAesonParser
@@ -538,7 +537,6 @@ instance A.ToJSON Declaration where
538537 , "comments" .= declComments
539538 , "sourceSpan" .= declSourceSpan
540539 , "children" .= declChildren
541− , "fixity" .= declFixity
542540 , "info" .= declInfo
543541 ]
544542
@@ -559,7 +557,7 @@ instance A.ToJSON DeclarationInfo where
559557 ExternDataDeclaration kind -> ["kind" .= kind]
560558 TypeSynonymDeclaration args ty -> ["arguments" .= args, "type" .= ty]
561559 TypeClassDeclaration args super -> ["arguments" .= args, "superclasses" .= super]
562− AliasDeclaration for fixity -> ["for" .= for, "fixity" .= fixity]
560+ AliasDeclaration fixity alias -> ["fixity" .= fixity, "alias" .= alias]
563561
564562instance A.ToJSON ChildDeclarationInfo where
565563 toJSON info = A.object $ "declType" .= childDeclInfoToString info : props
src/Language/PureScript/Environment.hs+28−24
@@ -3,11 +3,13 @@
33
44module Language.PureScript.Environment where
55
6−import Data.Maybe (fromMaybe)
6+import Prelude.Compat
7+
78import Data.Aeson.TH
9+import Data.Maybe (fromMaybe)
10+import qualified Data.Aeson as A
811import qualified Data.Map as M
912import qualified Data.Text as T
10−import qualified Data.Aeson as A
1113
1214import Language.PureScript.Crash
1315import Language.PureScript.Kinds
@@ -23,7 +25,7 @@ data Environment = Environment {
2325 -- |
2426 -- Value names currently in scope
2527 --
26− names :: M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
28+ names :: M.Map (Qualified Ident) (Type, NameKind, NameVisibility)
2729 -- |
2830 -- Type names currently in scope
2931 --
@@ -44,7 +46,7 @@ data Environment = Environment {
4446 -- Type classes
4547 --
4648 , typeClasses :: M.Map (Qualified (ProperName 'ClassName)) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
47− } deriving (Show, Read)
49+ } deriving (Show)
4850
4951-- |
5052-- The initial environment with no values and only the default javascript types defined
@@ -63,7 +65,7 @@ data NameVisibility
6365 -- |
6466 -- The name is defined in the another binding group, or has been made visible by a function binder
6567 --
66− | Defined deriving (Show, Read, Eq)
68+ | Defined deriving (Show, Eq)
6769
6870-- |
6971-- A flag for whether a name is for an private or public value - only public values will be
@@ -83,7 +85,7 @@ data NameKind
8385 -- A name for member introduced by foreign import
8486 --
8587 | External
86− deriving (Show, Read, Eq)
88+ deriving (Show, Eq)
8789
8890-- |
8991-- The kinds of a type
@@ -109,7 +111,7 @@ data TypeKind
109111 -- A scoped type variable
110112 --
111113 | ScopedTypeVar
112− deriving (Show, Read, Eq)
114+ deriving (Show, Eq)
113115
114116-- |
115117-- The type ('data' or 'newtype') of a data type declaration
@@ -123,7 +125,7 @@ data DataDeclType
123125 -- A newtype constructor
124126 --
125127 | Newtype
126− deriving (Show, Read, Eq, Ord)
128+ deriving (Show, Eq, Ord)
127129
128130showDataDeclType :: DataDeclType -> String
129131showDataDeclType Data = "data"
@@ -194,16 +196,16 @@ tyArray :: Type
194196tyArray = primTy "Array"
195197
196198-- |
197−-- Type constructor for objects
199+-- Type constructor for records
198200--
199−tyObject :: Type
200−tyObject = primTy "Object"
201+tyRecord :: Type
202+tyRecord = primTy "Record"
201203
202204-- |
203−-- Check whether a type is an object
205+-- Check whether a type is a record
204206--
205207isObject :: Type -> Bool
206−isObject = isTypeOrApplied tyObject
208+isObject = isTypeOrApplied tyRecord
207209
208210-- |
209211-- Check whether a type is a function
@@ -230,14 +232,15 @@ primTypes :: M.Map (Qualified (ProperName 'TypeName)) (Kind, TypeKind)
230232primTypes =
231233 M.fromList
232234 [ (primName "Function", (FunKind Star (FunKind Star Star), ExternData))
233− , (primName "Array", (FunKind Star Star, ExternData))
234− , (primName "Object", (FunKind (Row Star) Star, ExternData))
235− , (primName "String", (Star, ExternData))
236− , (primName "Char", (Star, ExternData))
237− , (primName "Number", (Star, ExternData))
238− , (primName "Int", (Star, ExternData))
239− , (primName "Boolean", (Star, ExternData))
240− , (primName "Partial", (Star, ExternData))
235+ , (primName "Array", (FunKind Star Star, ExternData))
236+ , (primName "Record", (FunKind (Row Star) Star, ExternData))
237+ , (primName "String", (Star, ExternData))
238+ , (primName "Char", (Star, ExternData))
239+ , (primName "Number", (Star, ExternData))
240+ , (primName "Int", (Star, ExternData))
241+ , (primName "Boolean", (Star, ExternData))
242+ , (primName "Partial", (Star, ExternData))
243+ , (primName "Fail", (FunKind Symbol Star, ExternData))
241244 ]
242245
243246-- |
@@ -247,7 +250,9 @@ primTypes =
247250primClasses :: M.Map (Qualified (ProperName 'ClassName)) ([(String, Maybe Kind)], [(Ident, Type)], [Constraint])
248251primClasses =
249252 M.fromList
250− [ (primName "Partial", ([], [], [])) ]
253+ [ (primName "Partial", ([], [], []))
254+ , (primName "Fail", ([("message", Just Symbol)], [], []))
255+ ]
251256
252257-- |
253258-- Finds information about data constructors from the current environment.
@@ -268,7 +273,6 @@ isNewtypeConstructor e ctor = case lookupConstructor e ctor of
268273-- Finds information about values from the current environment.
269274--
270275lookupValue :: Environment -> Qualified Ident -> Maybe (Type, NameKind, NameVisibility)
271−lookupValue env (Qualified (Just mn) ident) = (mn, ident) `M.lookup` names env
272−lookupValue _ _ = Nothing
276+lookupValue env ident = ident `M.lookup` names env
273277
274278$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''TypeKind)
src/Language/PureScript/Errors.hs+410−554
@@ -1,201 +1,45 @@
11{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
2+{-# LANGUAGE NamedFieldPuns #-}
43
5−module Language.PureScript.Errors where
4+module Language.PureScript.Errors
5+ ( module Language.PureScript.AST
6+ , module Language.PureScript.Errors
7+ ) where
68
7−import Prelude ()
89import Prelude.Compat
910
10−import Data.Ord (comparing)
11+import Control.Arrow ((&&&))
12+import Control.Monad
13+import Control.Monad.Error.Class (MonadError(..))
14+import Control.Monad.Trans.State.Lazy
15+import Control.Monad.Writer
16+
1117import Data.Char (isSpace)
1218import Data.Either (lefts, rights)
13−import Data.List (intercalate, transpose, nub, nubBy, sortBy, partition)
1419import Data.Foldable (fold)
15−import Data.Maybe (maybeToList)
16−
20+import Data.Functor.Identity (Identity(..))
21+import Data.List (intercalate, transpose, nub, nubBy, sortBy, partition)
22+import Data.Maybe (maybeToList, fromMaybe, mapMaybe)
23+import Data.Ord (comparing)
1724import qualified Data.Map as M
1825
19−import Control.Monad
20−import Control.Monad.Writer
21−import Control.Monad.Error.Class (MonadError(..))
22−import Control.Monad.Trans.State.Lazy
23−import Control.Arrow ((&&&))
24−
25−import Language.PureScript.Crash
2626import Language.PureScript.AST
27+import Language.PureScript.Crash
28+import Language.PureScript.Names
2729import Language.PureScript.Pretty
28−import Language.PureScript.Pretty.Common (before)
30+import Language.PureScript.Traversals
2931import Language.PureScript.Types
30−import Language.PureScript.Names
31−import Language.PureScript.Kinds
32+import Language.PureScript.Pretty.Common (endWith)
3233import qualified Language.PureScript.Bundle as Bundle
34+import qualified Language.PureScript.Constants as C
3335
34−import qualified Text.PrettyPrint.Boxes as Box
36+import qualified System.Console.ANSI as ANSI
3537
3638import qualified Text.Parsec as P
3739import qualified Text.Parsec.Error as PE
40+import qualified Text.PrettyPrint.Boxes as Box
3841import Text.Parsec.Error (Message(..))
3942
40−-- | A type of error messages
41−data SimpleErrorMessage
42− = ErrorParsingFFIModule FilePath (Maybe Bundle.ErrorMessage)
43− | ErrorParsingModule P.ParseError
44− | MissingFFIModule ModuleName
45− | MultipleFFIModules ModuleName [FilePath]
46− | UnnecessaryFFIModule ModuleName FilePath
47− | MissingFFIImplementations ModuleName [Ident]
48− | UnusedFFIImplementations ModuleName [Ident]
49− | InvalidFFIIdentifier ModuleName String
50− | CannotGetFileInfo FilePath
51− | CannotReadFile FilePath
52− | CannotWriteFile FilePath
53− | InfiniteType Type
54− | InfiniteKind Kind
55− | MultipleFixities Ident
56− | OrphanTypeDeclaration Ident
57− | OrphanFixityDeclaration String
58− | RedefinedModule ModuleName [SourceSpan]
59− | RedefinedIdent Ident
60− | OverlappingNamesInLet
61− | UnknownModule ModuleName
62− | UnknownType (Qualified (ProperName 'TypeName))
63− | UnknownTypeOp (Qualified Ident)
64− | UnknownTypeClass (Qualified (ProperName 'ClassName))
65− | UnknownValue (Qualified Ident)
66− | UnknownDataConstructor (Qualified (ProperName 'ConstructorName)) (Maybe (Qualified (ProperName 'ConstructorName)))
67− | UnknownTypeConstructor (Qualified (ProperName 'TypeName))
68− | UnknownImportType ModuleName (ProperName 'TypeName)
69− | UnknownExportType (ProperName 'TypeName)
70− | UnknownImportTypeOp ModuleName Ident
71− | UnknownExportTypeOp Ident
72− | UnknownImportTypeClass ModuleName (ProperName 'ClassName)
73− | UnknownExportTypeClass (ProperName 'ClassName)
74− | UnknownImportValue ModuleName Ident
75− | UnknownExportValue Ident
76− | UnknownExportModule ModuleName
77− | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
78− | UnknownExportDataConstructor (ProperName 'TypeName) (ProperName 'ConstructorName)
79− | ScopeConflict String [ModuleName]
80− | ScopeShadowing String (Maybe ModuleName) [ModuleName]
81− | ConflictingTypeDecls (ProperName 'TypeName)
82− | ConflictingCtorDecls (ProperName 'ConstructorName)
83− | TypeConflictsWithClass (ProperName 'TypeName)
84− | CtorConflictsWithClass (ProperName 'ConstructorName)
85− | ClassConflictsWithType (ProperName 'ClassName)
86− | ClassConflictsWithCtor (ProperName 'ClassName)
87− | DuplicateModuleName ModuleName
88− | DuplicateClassExport (ProperName 'ClassName)
89− | DuplicateValueExport Ident
90− | DuplicateTypeOpExport Ident
91− | DuplicateTypeArgument String
92− | InvalidDoBind
93− | InvalidDoLet
94− | CycleInDeclaration Ident
95− | CycleInTypeSynonym (Maybe (ProperName 'TypeName))
96− | CycleInModules [ModuleName]
97− | NameIsUndefined Ident
98− | UndefinedTypeVariable (ProperName 'TypeName)
99− | PartiallyAppliedSynonym (Qualified (ProperName 'TypeName))
100− | EscapedSkolem (Maybe Expr)
101− | TypesDoNotUnify Type Type
102− | KindsDoNotUnify Kind Kind
103− | ConstrainedTypeUnified Type Type
104− | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
105− | NoInstanceFound (Qualified (ProperName 'ClassName)) [Type]
106− | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
107− | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
108− | CannotFindDerivingType (ProperName 'TypeName)
109− | DuplicateLabel String (Maybe Expr)
110− | DuplicateValueDeclaration Ident
111− | ArgListLengthsDiffer Ident
112− | OverlappingArgNames (Maybe Ident)
113− | MissingClassMember Ident
114− | ExtraneousClassMember Ident (Qualified (ProperName 'ClassName))
115− | ExpectedType Type Kind
116− | IncorrectConstructorArity (Qualified (ProperName 'ConstructorName))
117− | ExprDoesNotHaveType Expr Type
118− | PropertyIsMissing String
119− | AdditionalProperty String
120− | CannotApplyFunction Type Expr
121− | TypeSynonymInstance
122− | OrphanInstance Ident (Qualified (ProperName 'ClassName)) [Type]
123− | InvalidNewtype (ProperName 'TypeName)
124− | InvalidInstanceHead Type
125− | TransitiveExportError DeclarationRef [DeclarationRef]
126− | TransitiveDctorExportError DeclarationRef (ProperName 'ConstructorName)
127− | ShadowedName Ident
128− | ShadowedTypeVar String
129− | UnusedTypeVar String
130− | WildcardInferredType Type
131− | HoleInferredType String Type
132− | MissingTypeDeclaration Ident Type
133− | NotExhaustivePattern [[Binder]] Bool
134− | OverlappingPattern [[Binder]] Bool
135− | IncompleteExhaustivityCheck
136− | ClassOperator (ProperName 'ClassName) Ident
137− | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
138− | ImportHidingModule ModuleName
139− | UnusedImport ModuleName
140− | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
141− | UnusedDctorImport (ProperName 'TypeName)
142− | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
143− | DeprecatedOperatorDecl String
144− | DeprecatedOperatorSection Expr (Either Expr Expr)
145− | DeprecatedQualifiedSyntax ModuleName ModuleName
146− | DeprecatedClassImport ModuleName (ProperName 'ClassName)
147− | DeprecatedClassExport (ProperName 'ClassName)
148− | DuplicateSelectiveImport ModuleName
149− | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
150− | DuplicateImportRef String
151− | DuplicateExportRef String
152− | IntOutOfRange Integer String Integer Integer
153− | RedundantEmptyHidingImport ModuleName
154− | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
155− | ImplicitImport ModuleName [DeclarationRef]
156− | HidingImport ModuleName [DeclarationRef]
157− | CaseBinderLengthDiffers Int [Binder]
158− | IncorrectAnonymousArgument
159− | InvalidOperatorInBinder Ident Ident
160− | DeprecatedRequirePath
161− | CannotGeneralizeRecursiveFunction Ident Type
162− deriving (Show)
163−
164−-- | Error message hints, providing more detailed information about failure.
165−data ErrorMessageHint
166− = ErrorUnifyingTypes Type Type
167− | ErrorInExpression Expr
168− | ErrorInModule ModuleName
169− | ErrorInInstance (Qualified (ProperName 'ClassName)) [Type]
170− | ErrorInSubsumption Type Type
171− | ErrorCheckingAccessor Expr String
172− | ErrorCheckingType Expr Type
173− | ErrorCheckingKind Type
174− | ErrorCheckingGuard
175− | ErrorInferringType Expr
176− | ErrorInApplication Expr Type Expr
177− | ErrorInDataConstructor (ProperName 'ConstructorName)
178− | ErrorInTypeConstructor (ProperName 'TypeName)
179− | ErrorInBindingGroup [Ident]
180− | ErrorInDataBindingGroup
181− | ErrorInTypeSynonym (ProperName 'TypeName)
182− | ErrorInValueDeclaration Ident
183− | ErrorInTypeDeclaration Ident
184− | ErrorInForeignImport Ident
185− | PositionedError SourceSpan
186− deriving Show
187−
188−-- | Categories of hints
189−data HintCategory
190− = ExprHint
191− | KindHint
192− | CheckHint
193− | PositionHint
194− | OtherHint
195− deriving (Show, Eq)
196−
197−data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
198−
19943newtype ErrorSuggestion = ErrorSuggestion String
20044
20145-- | Get the source span for an error
@@ -241,42 +85,22 @@ errorCode em = case unwrapErrorMessage em of
24185 CannotWriteFile{} -> "CannotWriteFile"
24286 InfiniteType{} -> "InfiniteType"
24387 InfiniteKind{} -> "InfiniteKind"
244− MultipleFixities{} -> "MultipleFixities"
88+ MultipleValueOpFixities{} -> "MultipleValueOpFixities"
89+ MultipleTypeOpFixities{} -> "MultipleTypeOpFixities"
24590 OrphanTypeDeclaration{} -> "OrphanTypeDeclaration"
246− OrphanFixityDeclaration{} -> "OrphanFixityDeclaration"
24791 RedefinedModule{} -> "RedefinedModule"
24892 RedefinedIdent{} -> "RedefinedIdent"
24993 OverlappingNamesInLet -> "OverlappingNamesInLet"
250− UnknownModule{} -> "UnknownModule"
251− UnknownType{} -> "UnknownType"
252− UnknownTypeOp{} -> "UnknownTypeOp"
253− UnknownTypeClass{} -> "UnknownTypeClass"
254− UnknownValue{} -> "UnknownValue"
255− UnknownDataConstructor{} -> "UnknownDataConstructor"
256− UnknownTypeConstructor{} -> "UnknownTypeConstructor"
257− UnknownImportType{} -> "UnknownImportType"
258− UnknownImportTypeOp{} -> "UnknownImportTypeOp"
259− UnknownExportType{} -> "UnknownExportType"
260− UnknownExportTypeOp{} -> "UnknownExportTypeOp"
261− UnknownImportTypeClass{} -> "UnknownImportTypeClass"
262− UnknownExportTypeClass{} -> "UnknownExportTypeClass"
263− UnknownImportValue{} -> "UnknownImportValue"
264− UnknownExportValue{} -> "UnknownExportValue"
265− UnknownExportModule{} -> "UnknownExportModule"
94+ UnknownName{} -> "UnknownName"
95+ UnknownImport{} -> "UnknownImport"
26696 UnknownImportDataConstructor{} -> "UnknownImportDataConstructor"
97+ UnknownExport{} -> "UnknownExport"
26798 UnknownExportDataConstructor{} -> "UnknownExportDataConstructor"
26899 ScopeConflict{} -> "ScopeConflict"
269100 ScopeShadowing{} -> "ScopeShadowing"
270− ConflictingTypeDecls{} -> "ConflictingTypeDecls"
271− ConflictingCtorDecls{} -> "ConflictingCtorDecls"
272− TypeConflictsWithClass{} -> "TypeConflictsWithClass"
273− CtorConflictsWithClass{} -> "CtorConflictsWithClass"
274− ClassConflictsWithType{} -> "ClassConflictsWithType"
275− ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
101+ DeclConflict{} -> "DeclConflict"
102+ ExportConflict{} -> "ExportConflict"
276103 DuplicateModuleName{} -> "DuplicateModuleName"
277− DuplicateClassExport{} -> "DuplicateClassExport"
278− DuplicateValueExport{} -> "DuplicateValueExport"
279− DuplicateTypeOpExport{} -> "DuplicateTypeOpExport"
280104 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
281105 InvalidDoBind -> "InvalidDoBind"
282106 InvalidDoLet -> "InvalidDoLet"
@@ -319,27 +143,19 @@ errorCode em = case unwrapErrorMessage em of
319143 WildcardInferredType{} -> "WildcardInferredType"
320144 HoleInferredType{} -> "HoleInferredType"
321145 MissingTypeDeclaration{} -> "MissingTypeDeclaration"
322− NotExhaustivePattern{} -> "NotExhaustivePattern"
323146 OverlappingPattern{} -> "OverlappingPattern"
324147 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
325− ClassOperator{} -> "ClassOperator"
326148 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
327149 ImportHidingModule{} -> "ImportHidingModule"
328150 UnusedImport{} -> "UnusedImport"
329151 UnusedExplicitImport{} -> "UnusedExplicitImport"
330152 UnusedDctorImport{} -> "UnusedDctorImport"
331153 UnusedDctorExplicitImport{} -> "UnusedDctorExplicitImport"
332− DeprecatedOperatorDecl{} -> "DeprecatedOperatorDecl"
333− DeprecatedOperatorSection{} -> "DeprecatedOperatorSection"
334− DeprecatedQualifiedSyntax{} -> "DeprecatedQualifiedSyntax"
335− DeprecatedClassImport{} -> "DeprecatedClassImport"
336− DeprecatedClassExport{} -> "DeprecatedClassExport"
337154 DuplicateSelectiveImport{} -> "DuplicateSelectiveImport"
338155 DuplicateImport{} -> "DuplicateImport"
339156 DuplicateImportRef{} -> "DuplicateImportRef"
340157 DuplicateExportRef{} -> "DuplicateExportRef"
341158 IntOutOfRange{} -> "IntOutOfRange"
342− RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
343159 ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
344160 ImplicitImport{} -> "ImplicitImport"
345161 HidingImport{} -> "HidingImport"
@@ -377,18 +193,25 @@ onErrorMessages f = MultipleErrors . map f . runMultipleErrors
377193
378194-- | Add a hint to an error message
379195addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
380−addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint : hints) se
196+addHint hint = addHints [hint]
197+
198+-- | Add hints to an error message
199+addHints :: [ErrorMessageHint] -> MultipleErrors -> MultipleErrors
200+addHints hints = onErrorMessages $ \(ErrorMessage hints' se) -> ErrorMessage (hints ++ hints') se
381201
382202-- | A map from rigid type variable name/unknown variable pairs to new variables.
383203data TypeMap = TypeMap
384− { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
385− , umNextSkolem :: Int
386− , umUnknownMap :: M.Map Int Int
387− , umNextUnknown :: Int
204+ { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
205+ -- ^ a map from skolems to their new names, including source and naming info
206+ , umUnknownMap :: M.Map Int Int
207+ -- ^ a map from unification variables to their new names
208+ , umNextIndex :: Int
209+ -- ^ unknowns and skolems share a source of names during renaming, to
210+ -- avoid overlaps in error messages. This is the next label for either case.
388211 } deriving Show
389212
390213defaultUnknownMap :: TypeMap
391−defaultUnknownMap = TypeMap M.empty 0 M.empty 0
214+defaultUnknownMap = TypeMap M.empty M.empty 0
392215
393216-- | How critical the issue is
394217data Level = Error | Warning deriving Show
@@ -407,21 +230,24 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
407230 m <- get
408231 case M.lookup u (umUnknownMap m) of
409232 Nothing -> do
410− let u' = umNextUnknown m
411− put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextUnknown = u' + 1 }
233+ let u' = umNextIndex m
234+ put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextIndex = u' + 1 }
412235 return (TUnknown u')
413236 Just u' -> return (TUnknown u')
414237 replaceTypes (Skolem name s sko ss) = do
415238 m <- get
416239 case M.lookup s (umSkolemMap m) of
417240 Nothing -> do
418− let s' = umNextSkolem m
419− put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextSkolem = s' + 1 }
241+ let s' = umNextIndex m
242+ put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextIndex = s' + 1 }
420243 return (Skolem name s' sko ss)
421244 Just (_, s', _) -> return (Skolem name s' sko ss)
422245 replaceTypes other = return other
423246
424−onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
247+onTypesInErrorMessage :: (Type -> Type) -> ErrorMessage -> ErrorMessage
248+onTypesInErrorMessage f = runIdentity . onTypesInErrorMessageM (Identity . f)
249+
250+onTypesInErrorMessageM :: Applicative m => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
425251onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
426252 where
427253 gSimple (InfiniteType t) = InfiniteType <$> f t
@@ -430,17 +256,16 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
430256 gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
431257 gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
432258 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
433− gSimple (NoInstanceFound cl ts) = NoInstanceFound cl <$> traverse f ts
259+ gSimple (NoInstanceFound con) = NoInstanceFound <$> overConstraintArgs (traverse f) con
434260 gSimple (OverlappingInstances cl ts insts) = OverlappingInstances cl <$> traverse f ts <*> pure insts
435261 gSimple (PossiblyInfiniteInstance cl ts) = PossiblyInfiniteInstance cl <$> traverse f ts
436262 gSimple (CannotDerive cl ts) = CannotDerive cl <$> traverse f ts
437263 gSimple (ExpectedType ty k) = ExpectedType <$> f ty <*> pure k
438264 gSimple (OrphanInstance nm cl ts) = OrphanInstance nm cl <$> traverse f ts
439− gSimple (WildcardInferredType ty) = WildcardInferredType <$> f ty
440− gSimple (HoleInferredType name ty) = HoleInferredType name <$> f ty
265+ gSimple (WildcardInferredType ty ctx) = WildcardInferredType <$> f ty <*> traverse (sndM f) ctx
266+ gSimple (HoleInferredType name ty ctx) = HoleInferredType name <$> f ty <*> traverse (sndM f) ctx
441267 gSimple (MissingTypeDeclaration nm ty) = MissingTypeDeclaration nm <$> f ty
442268 gSimple (CannotGeneralizeRecursiveFunction nm ty) = CannotGeneralizeRecursiveFunction nm <$> f ty
443−
444269 gSimple other = pure other
445270
446271 gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
@@ -449,6 +274,7 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
449274 gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
450275 gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
451276 gHint (ErrorInInstance cl ts) = ErrorInInstance cl <$> traverse f ts
277+ gHint (ErrorSolvingConstraint con) = ErrorSolvingConstraint <$> overConstraintArgs (traverse f) con
452278 gHint other = pure other
453279
454280wikiUri :: ErrorMessage -> String
@@ -457,18 +283,16 @@ wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ error
457283-- TODO Other possible suggestions:
458284-- WildcardInferredType - source span not small enough
459285-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
460−-- DeprecatedClassExport, DeprecatedClassImport, DeprecatedOperatorSection, would want to replace smaller span?
461286errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
462287errorSuggestion err = case err of
463288 UnusedImport{} -> emptySuggestion
464− RedundantEmptyHidingImport{} -> emptySuggestion
465289 DuplicateImport{} -> emptySuggestion
466− DeprecatedQualifiedSyntax name qualName -> suggest $
467− "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
468290 UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
469291 ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
470292 ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
471293 HidingImport mn refs -> suggest $ importSuggestion mn refs Nothing
294+ MissingTypeDeclaration ident ty -> suggest $ showIdent ident ++ " :: " ++ prettyPrintType ty
295+ WildcardInferredType ty _ -> suggest $ prettyPrintType ty
472296 _ -> Nothing
473297
474298 where
@@ -477,26 +301,87 @@ errorSuggestion err = case err of
477301
478302 importSuggestion :: ModuleName -> [ DeclarationRef ] -> Maybe ModuleName -> String
479303 importSuggestion mn refs qual =
480− "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")" ++ qstr qual
304+ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (mapMaybe prettyPrintRef refs) ++ ")" ++ qstr qual
481305
482306 qstr :: Maybe ModuleName -> String
483307 qstr (Just mn) = " as " ++ runModuleName mn
484308 qstr Nothing = ""
485309
310+suggestionSpan :: ErrorMessage -> Maybe SourceSpan
311+suggestionSpan e =
312+ getSpan (unwrapErrorMessage e) <$> errorSpan e
313+ where
314+ startOnly SourceSpan{spanName, spanStart} = SourceSpan {spanName, spanStart, spanEnd = spanStart}
315+
316+ getSpan simple ss =
317+ case simple of
318+ MissingTypeDeclaration{} -> startOnly ss
319+ _ -> ss
320+
486321showSuggestion :: SimpleErrorMessage -> String
487322showSuggestion suggestion = case errorSuggestion suggestion of
488323 Just (ErrorSuggestion x) -> x
489324 _ -> ""
490325
326+ansiColor :: (ANSI.ColorIntensity, ANSI.Color) -> String
327+ansiColor (intesity, color) =
328+ ANSI.setSGRCode [ANSI.SetColor ANSI.Foreground intesity color]
329+
330+ansiColorReset :: String
331+ansiColorReset =
332+ ANSI.setSGRCode [ANSI.Reset]
333+
334+colorCode :: Maybe (ANSI.ColorIntensity, ANSI.Color) -> String -> String
335+colorCode codeColor code = case codeColor of
336+ Nothing -> code
337+ Just cc -> concat [ansiColor cc, code, ansiColorReset]
338+
339+colorCodeBox :: Maybe (ANSI.ColorIntensity, ANSI.Color) -> Box.Box -> Box.Box
340+colorCodeBox codeColor b = case codeColor of
341+ Nothing -> b
342+ Just cc
343+ | Box.rows b == 1 ->
344+ Box.text (ansiColor cc) Box.<> b `endWith` Box.text ansiColorReset
345+
346+ | otherwise -> Box.hcat Box.left -- making two boxes, one for each side of the box so that it will set each row it's own color and will reset it afterwards
347+ [ Box.vcat Box.top $ replicate (Box.rows b) $ Box.text $ ansiColor cc
348+ , b
349+ , Box.vcat Box.top $ replicate (Box.rows b) $ Box.text ansiColorReset
350+ ]
351+
352+
353+-- | Default color intesity and color for code
354+defaultCodeColor :: (ANSI.ColorIntensity, ANSI.Color)
355+defaultCodeColor = (ANSI.Dull, ANSI.Yellow)
356+
357+-- | `prettyPrintSingleError` Options
358+data PPEOptions = PPEOptions
359+ { ppeCodeColor :: Maybe (ANSI.ColorIntensity, ANSI.Color) -- ^ Color code with this color... or not
360+ , ppeFull :: Bool -- ^ Should write a full error message?
361+ , ppeLevel :: Level -- ^ Should this report an error or a warning?
362+ , ppeShowWiki :: Bool -- ^ Should show a link to error message's wiki page?
363+ }
364+
365+-- | Default options for PPEOptions
366+defaultPPEOptions :: PPEOptions
367+defaultPPEOptions = PPEOptions
368+ { ppeCodeColor = Just defaultCodeColor
369+ , ppeFull = False
370+ , ppeLevel = Error
371+ , ppeShowWiki = True
372+ }
373+
374+
491375-- |
492376-- Pretty print a single error, simplifying if necessary
493377--
494−prettyPrintSingleError :: Bool -> Level -> Bool -> ErrorMessage -> Box.Box
495−prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap $ do
378+prettyPrintSingleError :: PPEOptions -> ErrorMessage -> Box.Box
379+prettyPrintSingleError (PPEOptions codeColor full level showWiki) e = flip evalState defaultUnknownMap $ do
496380 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
497381 um <- get
498382 return (prettyPrintErrorMessage um em)
499383 where
384+ (markCode, markCodeBox) = (colorCode &&& colorCodeBox) codeColor
500385
501386 -- Pretty print an ErrorMessage
502387 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
@@ -505,9 +390,10 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
505390 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
506391 ] ++
507392 maybe [] (return . Box.moveDown 1) typeInformation ++
508− [ Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri e ++ " for more information, "
509− , line $ "or to contribute content related to this " ++ levelText ++ "."
510− ]
393+ [ Box.moveDown 1 $ paras
394+ [ line $ "See " ++ wikiUri e ++ " for more information, "
395+ , line $ "or to contribute content related to this " ++ levelText ++ "."
396+ ]
511397 | showWiki
512398 ]
513399 where
@@ -522,11 +408,11 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
522408 skolemInfo :: (String, Int, Maybe SourceSpan) -> Box.Box
523409 skolemInfo (name, s, ss) =
524410 paras $
525− line (name ++ show s ++ " is a rigid type variable")
411+ line (markCode (name ++ show s) ++ " is a rigid type variable")
526412 : foldMap (return . line . (" bound at " ++) . displayStartEndPos) ss
527413
528414 unknownInfo :: Int -> Box.Box
529− unknownInfo u = line $ "_" ++ show u ++ " is an unknown type"
415+ unknownInfo u = line $ markCode ("t" ++ show u) ++ " is an unknown type"
530416
531417 renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
532418 renderSimpleErrorMessage (CannotGetFileInfo path) =
@@ -545,35 +431,35 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
545431 paras $ [ line "Unable to parse foreign module:"
546432 , indent . line $ path
547433 ] ++
548− (map (indent . line) (concatMap Bundle.printErrorMessage (maybeToList extra)))
434+ map (indent . line) (concatMap Bundle.printErrorMessage (maybeToList extra))
549435 renderSimpleErrorMessage (ErrorParsingModule err) =
550436 paras [ line "Unable to parse module: "
551437 , prettyPrintParseError err
552438 ]
553439 renderSimpleErrorMessage (MissingFFIModule mn) =
554− line $ "The foreign module implementation for module " ++ runModuleName mn ++ " is missing."
440+ line $ "The foreign module implementation for module " ++ markCode (runModuleName mn) ++ " is missing."
555441 renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
556− paras [ line $ "An unnecessary foreign module implementation was provided for module " ++ runModuleName mn ++ ": "
442+ paras [ line $ "An unnecessary foreign module implementation was provided for module " ++ markCode (runModuleName mn) ++ ": "
557443 , indent . line $ path
558− , line $ "Module " ++ runModuleName mn ++ " does not contain any foreign import declarations, so a foreign module is not necessary."
444+ , line $ "Module " ++ markCode (runModuleName mn) ++ " does not contain any foreign import declarations, so a foreign module is not necessary."
559445 ]
560446 renderSimpleErrorMessage (MissingFFIImplementations mn idents) =
561− paras [ line $ "The following values are not defined in the foreign module for module " ++ runModuleName mn ++ ": "
447+ paras [ line $ "The following values are not defined in the foreign module for module " ++ markCode (runModuleName mn) ++ ": "
562448 , indent . paras $ map (line . runIdent) idents
563449 ]
564450 renderSimpleErrorMessage (UnusedFFIImplementations mn idents) =
565− paras [ line $ "The following definitions in the foreign module for module " ++ runModuleName mn ++ " are unused: "
451+ paras [ line $ "The following definitions in the foreign module for module " ++ markCode (runModuleName mn) ++ " are unused: "
566452 , indent . paras $ map (line . runIdent) idents
567453 ]
568454 renderSimpleErrorMessage (InvalidFFIIdentifier mn ident) =
569− paras [ line $ "In the FFI module for " ++ runModuleName mn ++ ":"
455+ paras [ line $ "In the FFI module for " ++ markCode (runModuleName mn) ++ ":"
570456 , indent . paras $
571− [ line $ "The identifier `" ++ ident ++ "` is not valid in PureScript."
457+ [ line $ "The identifier " ++ markCode ident ++ " is not valid in PureScript."
572458 , line "Note that exported identifiers in FFI modules must be valid PureScript identifiers."
573459 ]
574460 ]
575461 renderSimpleErrorMessage (MultipleFFIModules mn paths) =
576− paras [ line $ "Multiple foreign module implementations have been provided for module " ++ runModuleName mn ++ ": "
462+ paras [ line $ "Multiple foreign module implementations have been provided for module " ++ markCode (runModuleName mn) ++ ": "
577463 , indent . paras $ map line paths
578464 ]
579465 renderSimpleErrorMessage InvalidDoBind =
@@ -584,126 +470,78 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
584470 line "The same name was used more than once in a let binding."
585471 renderSimpleErrorMessage (InfiniteType ty) =
586472 paras [ line "An infinite type was inferred for an expression: "
587− , indent $ typeAsBox ty
473+ , markCodeBox $ indent $ typeAsBox ty
588474 ]
589475 renderSimpleErrorMessage (InfiniteKind ki) =
590476 paras [ line "An infinite kind was inferred for a type: "
591− , indent $ line $ prettyPrintKind ki
477+ , indent $ line $ markCode $ prettyPrintKind ki
592478 ]
593− renderSimpleErrorMessage (MultipleFixities name) =
594− line $ "There are multiple fixity/precedence declarations for " ++ showIdent name
479+ renderSimpleErrorMessage (MultipleValueOpFixities op) =
480+ line $ "There are multiple fixity/precedence declarations for operator " ++ markCode (showOp op)
481+ renderSimpleErrorMessage (MultipleTypeOpFixities op) =
482+ line $ "There are multiple fixity/precedence declarations for type operator " ++ markCode (showOp op)
595483 renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
596− line $ "The type declaration for " ++ showIdent nm ++ " should be followed by its definition."
597− renderSimpleErrorMessage (OrphanFixityDeclaration op) =
598− line $ "The fixity/precedence declaration for " ++ show op ++ " should appear in the same module as its definition."
484+ line $ "The type declaration for " ++ markCode (showIdent nm) ++ " should be followed by its definition."
599485 renderSimpleErrorMessage (RedefinedModule name filenames) =
600− paras [ line ("The module " ++ runModuleName name ++ " has been defined multiple times:")
486+ paras [ line ("The module " ++ markCode (runModuleName name) ++ " has been defined multiple times:")
601487 , indent . paras $ map (line . displaySourceSpan) filenames
602488 ]
603489 renderSimpleErrorMessage (RedefinedIdent name) =
604− line $ "The value " ++ showIdent name ++ " has been defined multiple times"
605− renderSimpleErrorMessage (UnknownModule mn) =
606− line $ "Unknown module " ++ runModuleName mn
607− renderSimpleErrorMessage (UnknownType name) =
608− line $ "Unknown type " ++ showQualified runProperName name
609− renderSimpleErrorMessage (UnknownTypeOp name) =
610− line $ "Unknown type operator " ++ showQualified showIdent name
611− renderSimpleErrorMessage (UnknownTypeClass name) =
612− line $ "Unknown type class " ++ showQualified runProperName name
613− renderSimpleErrorMessage (UnknownValue name) =
614− line $ "Unknown value " ++ showQualified showIdent name
615− renderSimpleErrorMessage (UnknownTypeConstructor name) =
616− line $ "Unknown type constructor " ++ showQualified runProperName name
617− renderSimpleErrorMessage (UnknownDataConstructor dc tc) =
618− line $ "Unknown data constructor " ++ showQualified runProperName dc ++ foldMap ((" for type constructor " ++) . showQualified runProperName) tc
619− renderSimpleErrorMessage (UnknownImportType mn name) =
620− paras [ line $ "Cannot import type " ++ runProperName name ++ " from module " ++ runModuleName mn
621− , line "It either does not exist or the module does not export it."
622− ]
623− renderSimpleErrorMessage (UnknownExportType name) =
624− line $ "Cannot export unknown type " ++ runProperName name
625− renderSimpleErrorMessage (UnknownImportTypeOp mn name) =
626− paras [ line $ "Cannot import type operator " ++ showIdent name ++ " from module " ++ runModuleName mn
490+ line $ "The value " ++ markCode (showIdent name) ++ " has been defined multiple times"
491+ renderSimpleErrorMessage (UnknownName name) =
492+ line $ "Unknown " ++ printName name
493+ renderSimpleErrorMessage (UnknownImport mn name) =
494+ paras [ line $ "Cannot import " ++ printName (Qualified Nothing name) ++ " from module " ++ markCode (runModuleName mn)
627495 , line "It either does not exist or the module does not export it."
628496 ]
629− renderSimpleErrorMessage (UnknownExportTypeOp name) =
630− line $ "Cannot export unknown type operator " ++ showIdent name
631− renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
632− paras [ line $ "Cannot import type class " ++ runProperName name ++ " from module " ++ runModuleName mn
633− , line "It either does not exist or the module does not export it."
634− ]
635− renderSimpleErrorMessage (UnknownExportTypeClass name) =
636− line $ "Cannot export unknown type class " ++ runProperName name
637− renderSimpleErrorMessage (UnknownImportValue mn name) =
638− paras [ line $ "Cannot import value " ++ showIdent name ++ " from module " ++ runModuleName mn
639− , line "It either does not exist or the module does not export it."
640− ]
641− renderSimpleErrorMessage (UnknownExportValue name) =
642− line $ "Cannot export unknown value " ++ showIdent name
643− renderSimpleErrorMessage (UnknownExportModule name) =
644− paras [ line $ "Cannot export unknown module " ++ runModuleName name
645− , line "It either does not exist or has not been imported by the current module."
646− ]
647497 renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
648− line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon
498+ line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ markCode (runProperName dcon) ++ " for type " ++ markCode (runProperName tcon)
499+ renderSimpleErrorMessage (UnknownExport name) =
500+ line $ "Cannot export unknown " ++ printName (Qualified Nothing name)
649501 renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
650− line $ "Cannot export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon ++ ", as it has not been declared."
502+ line $ "Cannot export data constructor " ++ markCode (runProperName dcon) ++ " for type " ++ markCode (runProperName tcon) ++ ", as it has not been declared."
651503 renderSimpleErrorMessage (ScopeConflict nm ms) =
652− paras [ line $ "Conflicting definitions are in scope for " ++ nm ++ " from the following modules:"
653− , indent $ paras $ map (line . runModuleName) ms
504+ paras [ line $ "Conflicting definitions are in scope for " ++ printName (Qualified Nothing nm) ++ " from the following modules:"
505+ , indent $ paras $ map (line . markCode . runModuleName) ms
654506 ]
655507 renderSimpleErrorMessage (ScopeShadowing nm exmn ms) =
656− paras [ line $ "Shadowed definitions are in scope for " ++ nm ++ " from the following open imports:"
657− , indent $ paras $ map (line . ("import " ++) . runModuleName) ms
508+ paras [ line $ "Shadowed definitions are in scope for " ++ printName (Qualified Nothing nm) ++ " from the following open imports:"
509+ , indent $ paras $ map (line . markCode . ("import " ++) . runModuleName) ms
658510 , line $ "These will be ignored and the " ++ case exmn of
659− Just exmn' -> "declaration from " ++ runModuleName exmn' ++ " will be used."
511+ Just exmn' -> "declaration from " ++ markCode (runModuleName exmn') ++ " will be used."
660512 Nothing -> "local declaration will be used."
661513 ]
662− renderSimpleErrorMessage (ConflictingTypeDecls nm) =
663− line $ "Conflicting type declarations for " ++ runProperName nm
664− renderSimpleErrorMessage (ConflictingCtorDecls nm) =
665− line $ "Conflicting data constructor declarations for " ++ runProperName nm
666− renderSimpleErrorMessage (TypeConflictsWithClass nm) =
667− line $ "Type " ++ runProperName nm ++ " conflicts with a type class declaration with the same name."
668− renderSimpleErrorMessage (CtorConflictsWithClass nm) =
669− line $ "Data constructor " ++ runProperName nm ++ " conflicts with a type class declaration with the same name."
670− renderSimpleErrorMessage (ClassConflictsWithType nm) =
671− line $ "Type class " ++ runProperName nm ++ " conflicts with a type declaration with the same name."
672− renderSimpleErrorMessage (ClassConflictsWithCtor nm) =
673− line $ "Type class " ++ runProperName nm ++ " conflicts with a data constructor declaration with the same name."
514+ renderSimpleErrorMessage (DeclConflict new existing) =
515+ line $ "Declaration for " ++ printName (Qualified Nothing new) ++ " conflicts with an existing " ++ nameType existing ++ " of the same name."
516+ renderSimpleErrorMessage (ExportConflict new existing) =
517+ line $ "Export for " ++ printName new ++ " conflicts with " ++ runName existing
674518 renderSimpleErrorMessage (DuplicateModuleName mn) =
675− line $ "Module " ++ runModuleName mn ++ " has been defined multiple times."
676− renderSimpleErrorMessage (DuplicateClassExport nm) =
677− line $ "Duplicate export declaration for type class " ++ runProperName nm
678− renderSimpleErrorMessage (DuplicateValueExport nm) =
679− line $ "Duplicate export declaration for value " ++ showIdent nm
680− renderSimpleErrorMessage (DuplicateTypeOpExport nm) =
681− line $ "Duplicate export declaration for type operator " ++ showIdent nm
519+ line $ "Module " ++ markCode (runModuleName mn) ++ " has been defined multiple times."
682520 renderSimpleErrorMessage (CycleInDeclaration nm) =
683− line $ "The value of " ++ showIdent nm ++ " is undefined here, so this reference is not allowed."
521+ line $ "The value of " ++ markCode (showIdent nm) ++ " is undefined here, so this reference is not allowed."
684522 renderSimpleErrorMessage (CycleInModules mns) =
685523 paras [ line "There is a cycle in module dependencies in these modules: "
686− , indent $ paras (map (line . runModuleName) mns)
524+ , indent $ paras (map (line . markCode . runModuleName) mns)
687525 ]
688526 renderSimpleErrorMessage (CycleInTypeSynonym name) =
689527 paras [ line $ case name of
690− Just pn -> "A cycle appears in the definition of type synonym " ++ runProperName pn
528+ Just pn -> "A cycle appears in the definition of type synonym " ++ markCode (runProperName pn)
691529 Nothing -> "A cycle appears in a set of type synonym definitions."
692530 , line "Cycles are disallowed because they can lead to loops in the type checker."
693531 , line "Consider using a 'newtype' instead."
694532 ]
695533 renderSimpleErrorMessage (NameIsUndefined ident) =
696− line $ "Value " ++ showIdent ident ++ " is undefined."
534+ line $ "Value " ++ markCode (showIdent ident) ++ " is undefined."
697535 renderSimpleErrorMessage (UndefinedTypeVariable name) =
698− line $ "Type variable " ++ runProperName name ++ " is undefined."
536+ line $ "Type variable " ++ markCode (runProperName name) ++ " is undefined."
699537 renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
700− paras [ line $ "Type synonym " ++ showQualified runProperName name ++ " is partially applied."
538+ paras [ line $ "Type synonym " ++ markCode (showQualified runProperName name) ++ " is partially applied."
701539 , line "Type synonyms must be applied to all of their type arguments."
702540 ]
703541 renderSimpleErrorMessage (EscapedSkolem binding) =
704542 paras $ [ line "A type variable has escaped its scope." ]
705543 <> foldMap (\expr -> [ line "Relevant expression: "
706− , indent $ prettyPrintValue valueDepth expr
544+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr
707545 ]) binding
708546 renderSimpleErrorMessage (TypesDoNotUnify u1 u2)
709547 = let (sorted1, sorted2) = sortRows u1 u2
@@ -725,39 +563,56 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
725563 , rowFromList (sortBy (comparing fst) sd2 ++ map (fst &&& snd . snd) common, r2)
726564 )
727565 in paras [ line "Could not match type"
728− , indent $ typeAsBox sorted1
566+ , markCodeBox $ indent $ typeAsBox sorted1
729567 , line "with type"
730− , indent $ typeAsBox sorted2
568+ , markCodeBox $ indent $ typeAsBox sorted2
731569 ]
732570
733571 renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
734572 paras [ line "Could not match kind"
735− , indent $ line $ prettyPrintKind k1
573+ , indent $ line $ markCode $ prettyPrintKind k1
736574 , line "with kind"
737− , indent $ line $ prettyPrintKind k2
575+ , indent $ line $ markCode $ prettyPrintKind k2
738576 ]
739577 renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
740578 paras [ line "Could not match constrained type"
741− , indent $ typeAsBox t1
579+ , markCodeBox $ indent $ typeAsBox t1
742580 , line "with type"
743− , indent $ typeAsBox t2
581+ , markCodeBox $ indent $ typeAsBox t2
744582 ]
745583 renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
746584 paras [ line "Overlapping type class instances found for"
747− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
748− , Box.vcat Box.left (map typeAtomAsBox ts)
749− ]
585+ , markCodeBox $ indent $ Box.hsep 1 Box.left
586+ [ line (showQualified runProperName nm)
587+ , Box.vcat Box.left (map typeAtomAsBox ts)
588+ ]
750589 , line "The following instances were found:"
751590 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
752591 , line "Overlapping type class instances can lead to different behavior based on the order of module imports, and for that reason are not recommended."
753592 , line "They may be disallowed completely in a future version of the compiler."
754593 ]
755594 renderSimpleErrorMessage OverlappingInstances{} = internalError "OverlappingInstances: empty instance list"
756− renderSimpleErrorMessage (NoInstanceFound nm ts) =
595+ renderSimpleErrorMessage (NoInstanceFound (Constraint C.Fail [ TypeLevelString message ] _)) =
596+ paras [ line "A custom type error occurred while solving type class constraints:"
597+ , indent . paras . map line . lines $ message
598+ ]
599+ renderSimpleErrorMessage (NoInstanceFound (Constraint C.Partial
600+ _
601+ (Just (PartialConstraintData bs b)))) =
602+ paras [ line "A case expression could not be determined to cover all inputs."
603+ , line "The following additional cases are required to cover all inputs:\n"
604+ , indent $ paras $
605+ Box.hsep 1 Box.left
606+ (map (paras . map (line . markCode)) (transpose bs))
607+ : [line "..." | not b]
608+ , line "Alternatively, add a Partial constraint to the type of the enclosing value."
609+ ]
610+ renderSimpleErrorMessage (NoInstanceFound (Constraint nm ts _)) =
757611 paras [ line "No type class instance was found for"
758− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
759− , Box.vcat Box.left (map typeAtomAsBox ts)
760− ]
612+ , markCodeBox $ indent $ Box.hsep 1 Box.left
613+ [ line (showQualified runProperName nm)
614+ , Box.vcat Box.left (map typeAtomAsBox ts)
615+ ]
761616 , paras [ line "The instance head contains unknown type variables. Consider adding a type annotation."
762617 | any containsUnknowns ts
763618 ]
@@ -770,130 +625,118 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
770625 go _ = False
771626 renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
772627 paras [ line "Type class instance for"
773− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
774− , Box.vcat Box.left (map typeAtomAsBox ts)
775− ]
628+ , markCodeBox $ indent $ Box.hsep 1 Box.left
629+ [ line (showQualified runProperName nm)
630+ , Box.vcat Box.left (map typeAtomAsBox ts)
631+ ]
776632 , line "is possibly infinite."
777633 ]
778634 renderSimpleErrorMessage (CannotDerive nm ts) =
779635 paras [ line "Cannot derive a type class instance for"
780− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
781− , Box.vcat Box.left (map typeAtomAsBox ts)
782− ]
636+ , markCodeBox $ indent $ Box.hsep 1 Box.left
637+ [ line (showQualified runProperName nm)
638+ , Box.vcat Box.left (map typeAtomAsBox ts)
639+ ]
783640 ]
784641 renderSimpleErrorMessage (CannotFindDerivingType nm) =
785− line $ "Cannot derive a type class instance, because the type declaration for " ++ runProperName nm ++ " could not be found."
642+ line $ "Cannot derive a type class instance, because the type declaration for " ++ markCode (runProperName nm) ++ " could not be found."
786643 renderSimpleErrorMessage (DuplicateLabel l expr) =
787− paras $ [ line $ "Label " ++ show l ++ " appears more than once in a row type." ]
644+ paras $ [ line $ "Label " ++ markCode l ++ " appears more than once in a row type." ]
788645 <> foldMap (\expr' -> [ line "Relevant expression: "
789− , indent $ prettyPrintValue valueDepth expr'
646+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr'
790647 ]) expr
791648 renderSimpleErrorMessage (DuplicateTypeArgument name) =
792− line $ "Type argument " ++ show name ++ " appears more than once."
649+ line $ "Type argument " ++ markCode name ++ " appears more than once."
793650 renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
794− line $ "Multiple value declarations exist for " ++ showIdent nm ++ "."
651+ line $ "Multiple value declarations exist for " ++ markCode (showIdent nm) ++ "."
795652 renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
796− line $ "Argument list lengths differ in declaration " ++ showIdent ident
653+ line $ "Argument list lengths differ in declaration " ++ markCode (showIdent ident)
797654 renderSimpleErrorMessage (OverlappingArgNames ident) =
798655 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration " ++) . showIdent) ident
799656 renderSimpleErrorMessage (MissingClassMember ident) =
800− line $ "Type class member " ++ showIdent ident ++ " has not been implemented."
657+ line $ "Type class member " ++ markCode (showIdent ident) ++ " has not been implemented."
801658 renderSimpleErrorMessage (ExtraneousClassMember ident className) =
802− line $ showIdent ident ++ " is not a member of type class " ++ showQualified runProperName className
659+ line $ "" ++ markCode (showIdent ident) ++ " is not a member of type class " ++ markCode (showQualified runProperName className)
803660 renderSimpleErrorMessage (ExpectedType ty kind) =
804− paras [ line "In a type-annotated expression x :: t, the type t must have kind *."
661+ paras [ line $ "In a type-annotated expression " ++ markCode "x :: t" ++ ", the type " ++ markCode "t" ++ " must have kind " ++ markCode "*" ++ "."
805662 , line "The error arises from the type"
806− , indent $ typeAsBox ty
663+ , markCodeBox $ indent $ typeAsBox ty
807664 , line "having the kind"
808− , indent $ line $ prettyPrintKind kind
665+ , indent $ line $ markCode $ prettyPrintKind kind
809666 , line "instead."
810667 ]
811668 renderSimpleErrorMessage (IncorrectConstructorArity nm) =
812− line $ "Data constructor " ++ showQualified runProperName nm ++ " was given the wrong number of arguments in a case expression."
669+ line $ "Data constructor " ++ markCode (showQualified runProperName nm) ++ " was given the wrong number of arguments in a case expression."
813670 renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
814671 paras [ line "Expression"
815− , indent $ prettyPrintValue valueDepth expr
672+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr
816673 , line "does not have type"
817− , indent $ typeAsBox ty
674+ , markCodeBox $ indent $ typeAsBox ty
818675 ]
819676 renderSimpleErrorMessage (PropertyIsMissing prop) =
820− line $ "Type of expression lacks required label " ++ show prop ++ "."
677+ line $ "Type of expression lacks required label " ++ markCode prop ++ "."
821678 renderSimpleErrorMessage (AdditionalProperty prop) =
822− line $ "Type of expression contains additional label " ++ show prop ++ "."
679+ line $ "Type of expression contains additional label " ++ markCode prop ++ "."
823680 renderSimpleErrorMessage (CannotApplyFunction fn arg) =
824681 paras [ line "A function of type"
825− , indent $ typeAsBox fn
682+ , markCodeBox $ indent $ typeAsBox fn
826683 , line "can not be applied to the argument"
827− , indent $ prettyPrintValue valueDepth arg
684+ , markCodeBox $ indent $ prettyPrintValue valueDepth arg
828685 ]
829686 renderSimpleErrorMessage TypeSynonymInstance =
830687 line "Type class instances for type synonyms are disallowed."
831688 renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
832− paras [ line $ "Type class instance " ++ showIdent nm ++ " for "
833− , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName cnm)
834− , Box.vcat Box.left (map typeAtomAsBox ts)
835− ]
689+ paras [ line $ "Type class instance " ++ markCode (showIdent nm) ++ " for "
690+ , markCodeBox $ indent $ Box.hsep 1 Box.left
691+ [ line (showQualified runProperName cnm)
692+ , Box.vcat Box.left (map typeAtomAsBox ts)
693+ ]
836694 , line "is an orphan instance."
837695 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
838696 , line "Consider moving the instance, if possible, or using a newtype wrapper."
839697 ]
840698 renderSimpleErrorMessage (InvalidNewtype name) =
841− paras [ line $ "Newtype " ++ runProperName name ++ " is invalid."
699+ paras [ line $ "Newtype " ++ markCode (runProperName name) ++ " is invalid."
842700 , line "Newtypes must define a single constructor with a single argument."
843701 ]
844702 renderSimpleErrorMessage (InvalidInstanceHead ty) =
845703 paras [ line "Type class instance head is invalid due to use of type"
846− , indent $ typeAsBox ty
704+ , markCodeBox $ indent $ typeAsBox ty
847705 , line "All types appearing in instance declarations must be of the form T a_1 .. a_n, where each type a_i is of the same form."
848706 ]
849707 renderSimpleErrorMessage (TransitiveExportError x ys) =
850− paras [ line $ "An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: "
851− , indent $ paras $ map (line . prettyPrintExport) ys
708+ paras [ line $ "An export for " ++ markCode (prettyPrintExport x) ++ " requires the following to also be exported: "
709+ , indent $ paras $ map (line . markCode . prettyPrintExport) ys
852710 ]
853711 renderSimpleErrorMessage (TransitiveDctorExportError x ctor) =
854− paras [ line $ "An export for " ++ prettyPrintExport x ++ " requires the following data constructor to also be exported: "
855− , indent $ line $ runProperName ctor
712+ paras [ line $ "An export for " ++ markCode (prettyPrintExport x) ++ " requires the following data constructor to also be exported: "
713+ , indent $ line $ markCode $ runProperName ctor
856714 ]
857715 renderSimpleErrorMessage (ShadowedName nm) =
858− line $ "Name '" ++ showIdent nm ++ "' was shadowed."
716+ line $ "Name " ++ markCode (showIdent nm) ++ " was shadowed."
859717 renderSimpleErrorMessage (ShadowedTypeVar tv) =
860− line $ "Type variable '" ++ tv ++ "' was shadowed."
718+ line $ "Type variable " ++ markCode tv ++ " was shadowed."
861719 renderSimpleErrorMessage (UnusedTypeVar tv) =
862− line $ "Type variable '" ++ tv ++ "' was declared but not used."
863− renderSimpleErrorMessage (ClassOperator className opName) =
864− paras [ line $ "Type class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
865− , line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
866− , indent . line $ showIdent opName ++ " = someMember"
867− ]
720+ line $ "Type variable " ++ markCode tv ++ " was declared but not used."
868721 renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
869− line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors."
722+ line $ "Importing type " ++ markCode (runProperName name ++ "(..)") ++ " from " ++ markCode (runModuleName mn) ++ " is misleading as it has no exported data constructors."
870723 renderSimpleErrorMessage (ImportHidingModule name) =
871− paras [ line "'hiding' imports cannot be used to hide modules."
872− , line $ "An attempt was made to hide the import of " ++ runModuleName name
873− ]
874− renderSimpleErrorMessage (WildcardInferredType ty) =
875− paras [ line "Wildcard type definition has the inferred type "
876− , indent $ typeAsBox ty
877− ]
878− renderSimpleErrorMessage (HoleInferredType name ty) =
879− paras [ line $ "Hole '" ++ name ++ "' has the inferred type "
880− , indent $ typeAsBox ty
881− ]
724+ paras [ line "hiding imports cannot be used to hide modules."
725+ , line $ "An attempt was made to hide the import of " ++ markCode (runModuleName name)
726+ ]
727+ renderSimpleErrorMessage (WildcardInferredType ty ctx) =
728+ paras $ [ line "Wildcard type definition has the inferred type "
729+ , markCodeBox $ indent $ typeAsBox ty
730+ ] ++ renderContext ctx
731+ renderSimpleErrorMessage (HoleInferredType name ty ctx) =
732+ paras $ [ line $ "Hole '" ++ markCode name ++ "' has the inferred type "
733+ , markCodeBox $ indent $ typeAsBox ty
734+ ] ++ renderContext ctx
882735 renderSimpleErrorMessage (MissingTypeDeclaration ident ty) =
883− paras [ line $ "No type declaration was provided for the top-level declaration of " ++ showIdent ident ++ "."
736+ paras [ line $ "No type declaration was provided for the top-level declaration of " ++ markCode (showIdent ident) ++ "."
884737 , line "It is good practice to provide type declarations as a form of documentation."
885− , line $ "The inferred type of " ++ showIdent ident ++ " was:"
886− , indent $ typeAsBox ty
887− ]
888− renderSimpleErrorMessage (NotExhaustivePattern bs b) =
889− paras [ line "A case expression could not be determined to cover all inputs."
890− , line "The following additional cases are required to cover all inputs:\n"
891− , indent $ paras $
892− Box.hsep 1 Box.left
893− (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
894− : [line "..." | not b]
895− , line "Or alternatively, add a Partial constraint to the type of the enclosing value."
896− , line "Non-exhaustive patterns for values without a `Partial` constraint will be disallowed in PureScript 0.9."
738+ , line $ "The inferred type of " ++ markCode (showIdent ident) ++ " was:"
739+ , markCodeBox $ indent $ typeAsBox ty
897740 ]
898741 renderSimpleErrorMessage (OverlappingPattern bs b) =
899742 paras $ [ line "A case expression contains unreachable cases:\n"
@@ -905,109 +748,51 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
905748 , line "You may want to decompose your data types into smaller types."
906749 ]
907750 renderSimpleErrorMessage (UnusedImport name) =
908− line $ "The import of module " ++ runModuleName name ++ " is redundant"
751+ line $ "The import of module " ++ markCode (runModuleName name) ++ " is redundant"
909752
910753 renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
911− paras [ line $ "The import of module " ++ runModuleName mn ++ " contains the following unused references:"
754+ paras [ line $ "The import of module " ++ markCode (runModuleName mn) ++ " contains the following unused references:"
912755 , indent $ paras $ map line names
913756 , line "It could be replaced with:"
914− , indent $ line $ showSuggestion msg ]
757+ , indent $ line $ markCode $ showSuggestion msg ]
915758
916759 renderSimpleErrorMessage (UnusedDctorImport name) =
917− line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
760+ line $ "The import of type " ++ markCode (runProperName name) ++ " includes data constructors but only the type is used"
918761
919762 renderSimpleErrorMessage (UnusedDctorExplicitImport name names) =
920− paras [ line $ "The import of type " ++ runProperName name ++ " includes the following unused data constructors:"
921− , indent $ paras $ map (line .runProperName) names ]
922−
923− renderSimpleErrorMessage (DeprecatedOperatorDecl name) =
924− paras [ line $ "The operator (" ++ name ++ ") was declared as a value rather than an alias for a named function."
925− , line "Operator aliases are declared by using a fixity declaration, for example:"
926− , indent $ line $ "infixl 9 someFunction as " ++ name
927− , line "Support for value-declared operators will be removed in PureScript 0.9."
928− ]
929−
930− renderSimpleErrorMessage (DeprecatedOperatorSection op val) =
931− paras [ line "An operator section uses legacy syntax. Operator sections are now written using anonymous function syntax:"
932− , indent $ foldr1 before $
933− case val of
934− Left l ->
935− [ line "("
936− , prettyPrintValue valueDepth l
937− , line " "
938− , renderOperator op
939− , line " _)"
940− ]
941− Right r ->
942− [ line "(_ "
943− , renderOperator op
944− , line " "
945− , prettyPrintValue valueDepth r
946− , line ")"
947− ]
948− , line "Support for legacy operator sections will be removed in PureScript 0.9."
949− ]
950− where
951− renderOperator (PositionedValue _ _ ex) = renderOperator ex
952− renderOperator (Var (Qualified _ (Op ident))) = line ident
953− renderOperator other = Box.hcat Box.top [ line "`", prettyPrintValue valueDepth other, line "`" ]
954− renderSimpleErrorMessage (DeprecatedQualifiedSyntax name qualName) =
955− paras [ line "Import uses the deprecated 'qualified' syntax:"
956− , indent $ line $ "import qualified " ++ runModuleName name ++ " as " ++ runModuleName qualName
957− , line "Should instead use the form:"
958− , indent $ line $ "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
959− , line "The deprecated syntax will be removed in PureScript 0.9."
960− ]
961−
962− renderSimpleErrorMessage (DeprecatedClassImport mn name) =
963− paras [ line $ "Class import from " ++ runModuleName mn ++ " uses deprecated syntax that omits the 'class' keyword:"
964− , indent $ line $ runProperName name
965− , line "Should instead use the form:"
966− , indent $ line $ "class " ++ runProperName name
967− , line "The deprecated syntax will be removed in PureScript 0.9."
968− ]
969−
970− renderSimpleErrorMessage (DeprecatedClassExport name) =
971− paras [ line "Class export uses deprecated syntax that omits the 'class' keyword:"
972− , indent $ line $ runProperName name
973− , line "Should instead use the form:"
974− , indent $ line $ "class " ++ runProperName name
975− , line "The deprecated syntax will be removed in PureScript 0.9."
976− ]
763+ paras [ line $ "The import of type " ++ markCode (runProperName name) ++ " includes the following unused data constructors:"
764+ , indent $ paras $ map (line . markCode . runProperName) names ]
977765
978766 renderSimpleErrorMessage (DuplicateSelectiveImport name) =
979− line $ "There is an existing import of " ++ runModuleName name ++ ", consider merging the import lists"
767+ line $ "There is an existing import of " ++ markCode (runModuleName name) ++ ", consider merging the import lists"
980768
981769 renderSimpleErrorMessage (DuplicateImport name imp qual) =
982− line $ "Duplicate import of " ++ prettyPrintImport name imp qual
770+ line $ "Duplicate import of " ++ markCode (prettyPrintImport name imp qual)
983771
984− renderSimpleErrorMessage (DuplicateImportRef ref) =
985− line $ "Import list contains multiple references to " ++ ref
772+ renderSimpleErrorMessage (DuplicateImportRef name) =
773+ line $ "Import list contains multiple references to " ++ printName (Qualified Nothing name)
986774
987− renderSimpleErrorMessage (DuplicateExportRef ref) =
988− line $ "Export list contains multiple references to " ++ ref
775+ renderSimpleErrorMessage (DuplicateExportRef name) =
776+ line $ "Export list contains multiple references to " ++ printName (Qualified Nothing name)
989777
990778 renderSimpleErrorMessage (IntOutOfRange value backend lo hi) =
991− paras [ line $ "Integer value " ++ show value ++ " is out of range for the " ++ backend ++ " backend."
992− , line $ "Acceptable values fall within the range " ++ show lo ++ " to " ++ show hi ++ " (inclusive)." ]
993−
994− renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
995− line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
779+ paras [ line $ "Integer value " ++ markCode (show value) ++ " is out of range for the " ++ backend ++ " backend."
780+ , line $ "Acceptable values fall within the range " ++ markCode (show lo) ++ " to " ++ markCode (show hi) ++ " (inclusive)." ]
996781
997782 renderSimpleErrorMessage msg@(ImplicitQualifiedImport importedModule asModule _) =
998− paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
999− , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
1000− , indent $ line $ showSuggestion msg
783+ paras [ line $ "Module " ++ markCode (runModuleName importedModule) ++ " was imported as " ++ markCode (runModuleName asModule) ++ " with unspecified imports."
784+ , line $ "As there are multiple modules being imported as " ++ markCode (runModuleName asModule) ++ ", consider using the explicit form:"
785+ , indent $ line $ markCode $ showSuggestion msg
1001786 ]
1002787
1003788 renderSimpleErrorMessage msg@(ImplicitImport mn _) =
1004− paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
1005− , indent $ line $ showSuggestion msg
789+ paras [ line $ "Module " ++ markCode (runModuleName mn) ++ " has unspecified imports, consider using the explicit form: "
790+ , indent $ line $ markCode $ showSuggestion msg
1006791 ]
1007792
1008793 renderSimpleErrorMessage msg@(HidingImport mn _) =
1009− paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the inclusive form: "
1010− , indent $ line $ showSuggestion msg
794+ paras [ line $ "Module " ++ markCode (runModuleName mn) ++ " has unspecified imports, consider using the inclusive form: "
795+ , indent $ line $ markCode $ showSuggestion msg
1011796 ]
1012797
1013798 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
@@ -1020,7 +805,7 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1020805 line "An anonymous function argument appears in an invalid context."
1021806
1022807 renderSimpleErrorMessage (InvalidOperatorInBinder op fn) =
1023− paras [ line $ "Operator " ++ showIdent op ++ " cannot be used in a pattern as it is an alias for function " ++ showIdent fn ++ "."
808+ paras [ line $ "Operator " ++ markCode (showQualified showOp op) ++ " cannot be used in a pattern as it is an alias for function " ++ showQualified showIdent fn ++ "."
1024809 , line "Only aliases for data constructors may be used in patterns."
1025810 ]
1026811
@@ -1028,9 +813,9 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1028813 line "The require-path option is deprecated and will be removed in PureScript 0.9."
1029814
1030815 renderSimpleErrorMessage (CannotGeneralizeRecursiveFunction ident ty) =
1031− paras [ line $ "Unable to generalize the type of the recursive function " ++ showIdent ident ++ "."
1032− , line $ "The inferred type of " ++ showIdent ident ++ " was:"
1033− , indent $ typeAsBox ty
816+ paras [ line $ "Unable to generalize the type of the recursive function " ++ markCode (showIdent ident) ++ "."
817+ , line $ "The inferred type of " ++ markCode (showIdent ident) ++ " was:"
818+ , markCodeBox $ indent $ typeAsBox ty
1034819 , line "Try adding a type signature."
1035820 ]
1036821
@@ -1038,42 +823,43 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1038823 renderHint (ErrorUnifyingTypes t1 t2) detail =
1039824 paras [ detail
1040825 , Box.hsep 1 Box.top [ line "while trying to match type"
1041− , typeAsBox t1
826+ , markCodeBox $ typeAsBox t1
1042827 ]
1043828 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "with type"
1044− , typeAsBox t2
829+ , markCodeBox $ typeAsBox t2
1045830 ]
1046831 ]
1047832 renderHint (ErrorInExpression expr) detail =
1048833 paras [ detail
1049834 , Box.hsep 1 Box.top [ Box.text "in the expression"
1050− , prettyPrintValue valueDepth expr
835+ , markCodeBox $ markCodeBox $ prettyPrintValue valueDepth expr
1051836 ]
1052837 ]
1053838 renderHint (ErrorInModule mn) detail =
1054− paras [ line $ "in module " ++ runModuleName mn
839+ paras [ line $ "in module " ++ markCode (runModuleName mn)
1055840 , detail
1056841 ]
1057842 renderHint (ErrorInSubsumption t1 t2) detail =
1058843 paras [ detail
1059844 , Box.hsep 1 Box.top [ line "while checking that type"
1060− , typeAsBox t1
845+ , markCodeBox $ typeAsBox t1
1061846 ]
1062847 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "is at least as general as type"
1063− , typeAsBox t2
848+ , markCodeBox $ typeAsBox t2
1064849 ]
1065850 ]
1066851 renderHint (ErrorInInstance nm ts) detail =
1067852 paras [ detail
1068− , Box.hsep 1 Box.top [ line "in type class instance"
1069− , line (showQualified runProperName nm)
1070− , Box.vcat Box.left (map typeAtomAsBox ts)
1071− ]
853+ , line "in type class instance"
854+ , markCodeBox $ indent $ Box.hsep 1 Box.top
855+ [ line $ showQualified runProperName nm
856+ , Box.vcat Box.left (map typeAtomAsBox ts)
857+ ]
1072858 ]
1073859 renderHint (ErrorCheckingKind ty) detail =
1074860 paras [ detail
1075861 , Box.hsep 1 Box.top [ line "while checking the kind of"
1076− , typeAsBox ty
862+ , markCodeBox $ typeAsBox ty
1077863 ]
1078864 ]
1079865 renderHint ErrorCheckingGuard detail =
@@ -1083,43 +869,43 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1083869 renderHint (ErrorInferringType expr) detail =
1084870 paras [ detail
1085871 , Box.hsep 1 Box.top [ line "while inferring the type of"
1086− , prettyPrintValue valueDepth expr
872+ , markCodeBox $ prettyPrintValue valueDepth expr
1087873 ]
1088874 ]
1089875 renderHint (ErrorCheckingType expr ty) detail =
1090876 paras [ detail
1091877 , Box.hsep 1 Box.top [ line "while checking that expression"
1092− , prettyPrintValue valueDepth expr
878+ , markCodeBox $ prettyPrintValue valueDepth expr
1093879 ]
1094880 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "has type"
1095− , typeAsBox ty
881+ , markCodeBox $ typeAsBox ty
1096882 ]
1097883 ]
1098884 renderHint (ErrorCheckingAccessor expr prop) detail =
1099885 paras [ detail
1100886 , Box.hsep 1 Box.top [ line "while checking type of property accessor"
1101− , prettyPrintValue valueDepth (Accessor prop expr)
887+ , markCodeBox $ prettyPrintValue valueDepth (Accessor prop expr)
1102888 ]
1103889 ]
1104890 renderHint (ErrorInApplication f t a) detail =
1105891 paras [ detail
1106892 , Box.hsep 1 Box.top [ line "while applying a function"
1107− , prettyPrintValue valueDepth f
893+ , markCodeBox $ prettyPrintValue valueDepth f
1108894 ]
1109895 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "of type"
1110− , typeAsBox t
896+ , markCodeBox $ typeAsBox t
1111897 ]
1112898 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "to argument"
1113− , prettyPrintValue valueDepth a
899+ , markCodeBox $ prettyPrintValue valueDepth a
1114900 ]
1115901 ]
1116902 renderHint (ErrorInDataConstructor nm) detail =
1117903 paras [ detail
1118− , line $ "in data constructor " ++ runProperName nm
904+ , line $ "in data constructor " ++ markCode (runProperName nm)
1119905 ]
1120906 renderHint (ErrorInTypeConstructor nm) detail =
1121907 paras [ detail
1122− , line $ "in type constructor " ++ runProperName nm
908+ , line $ "in type constructor " ++ markCode (runProperName nm)
1123909 ]
1124910 renderHint (ErrorInBindingGroup nms) detail =
1125911 paras [ detail
@@ -1131,25 +917,75 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1131917 ]
1132918 renderHint (ErrorInTypeSynonym name) detail =
1133919 paras [ detail
1134− , line $ "in type synonym " ++ runProperName name
920+ , line $ "in type synonym " ++ markCode (runProperName name)
1135921 ]
1136922 renderHint (ErrorInValueDeclaration n) detail =
1137923 paras [ detail
1138− , line $ "in value declaration " ++ showIdent n
924+ , line $ "in value declaration " ++ markCode (showIdent n)
1139925 ]
1140926 renderHint (ErrorInTypeDeclaration n) detail =
1141927 paras [ detail
1142− , line $ "in type declaration for " ++ showIdent n
928+ , line $ "in type declaration for " ++ markCode (showIdent n)
1143929 ]
1144930 renderHint (ErrorInForeignImport nm) detail =
1145931 paras [ detail
1146− , line $ "in foreign import " ++ showIdent nm
932+ , line $ "in foreign import " ++ markCode (showIdent nm)
933+ ]
934+ renderHint (ErrorSolvingConstraint (Constraint nm ts _)) detail =
935+ paras [ detail
936+ , line "while solving type class constriant"
937+ , markCodeBox $ indent $ Box.hsep 1 Box.left
938+ [ line (showQualified runProperName nm)
939+ , Box.vcat Box.left (map typeAtomAsBox ts)
940+ ]
1147941 ]
1148942 renderHint (PositionedError srcSpan) detail =
1149943 paras [ line $ "at " ++ displaySourceSpan srcSpan
1150944 , detail
1151945 ]
1152946
947+ renderContext :: Context -> [Box.Box]
948+ renderContext [] = []
949+ renderContext ctx =
950+ [ line "in the following context:"
951+ , indent $ paras
952+ [ Box.hcat Box.left [ Box.text (showIdent ident <> " :: ")
953+ , markCodeBox $ typeAsBox ty'
954+ ]
955+ | (ident, ty') <- take 5 ctx
956+ ]
957+ ]
958+
959+ printName :: Qualified Name -> String
960+ printName qn = nameType (disqualify qn) ++ " " ++ markCode (runName qn)
961+
962+ nameType :: Name -> String
963+ nameType (IdentName _) = "value"
964+ nameType (ValOpName _) = "operator"
965+ nameType (TyName _) = "type"
966+ nameType (TyOpName _) = "type operator"
967+ nameType (DctorName _) = "data constructor"
968+ nameType (TyClassName _) = "type class"
969+ nameType (ModName _) = "module"
970+
971+ runName :: Qualified Name -> String
972+ runName (Qualified mn (IdentName name)) =
973+ showQualified showIdent (Qualified mn name)
974+ runName (Qualified mn (ValOpName op)) =
975+ showQualified showOp (Qualified mn op)
976+ runName (Qualified mn (TyName name)) =
977+ showQualified runProperName (Qualified mn name)
978+ runName (Qualified mn (TyOpName op)) =
979+ showQualified showOp (Qualified mn op)
980+ runName (Qualified mn (DctorName name)) =
981+ showQualified runProperName (Qualified mn name)
982+ runName (Qualified mn (TyClassName name)) =
983+ showQualified runProperName (Qualified mn name)
984+ runName (Qualified Nothing (ModName name)) =
985+ runModuleName name
986+ runName (Qualified _ ModName{}) =
987+ internalError "qualified ModName in runName"
988+
1153989 valueDepth :: Int
1154990 valueDepth | full = 1000
1155991 | otherwise = 3
@@ -1192,6 +1028,10 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
11921028 where
11931029 isUnifyHint ErrorUnifyingTypes{} = True
11941030 isUnifyHint _ = False
1031+ stripRedudantHints NoInstanceFound{} = stripFirst isSolverHint
1032+ where
1033+ isSolverHint ErrorSolvingConstraint{} = True
1034+ isSolverHint _ = False
11951035 stripRedudantHints _ = id
11961036
11971037 stripFirst :: (ErrorMessageHint -> Bool) -> [ErrorMessageHint] -> [ErrorMessageHint]
@@ -1203,70 +1043,86 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
12031043 stripFirst _ [] = []
12041044
12051045 hintCategory :: ErrorMessageHint -> HintCategory
1206− hintCategory ErrorCheckingType{} = ExprHint
1207− hintCategory ErrorInferringType{} = ExprHint
1208− hintCategory ErrorInExpression{} = ExprHint
1209− hintCategory ErrorUnifyingTypes{} = CheckHint
1210− hintCategory ErrorInSubsumption{} = CheckHint
1211− hintCategory ErrorInApplication{} = CheckHint
1212− hintCategory ErrorCheckingKind{} = CheckHint
1213− hintCategory PositionedError{} = PositionHint
1214− hintCategory _ = OtherHint
1046+ hintCategory ErrorCheckingType{} = ExprHint
1047+ hintCategory ErrorInferringType{} = ExprHint
1048+ hintCategory ErrorInExpression{} = ExprHint
1049+ hintCategory ErrorUnifyingTypes{} = CheckHint
1050+ hintCategory ErrorInSubsumption{} = CheckHint
1051+ hintCategory ErrorInApplication{} = CheckHint
1052+ hintCategory ErrorCheckingKind{} = CheckHint
1053+ hintCategory ErrorSolvingConstraint{} = SolverHint
1054+ hintCategory PositionedError{} = PositionHint
1055+ hintCategory _ = OtherHint
12151056
12161057-- Pretty print and export declaration
12171058prettyPrintExport :: DeclarationRef -> String
12181059prettyPrintExport (TypeRef pn _) = runProperName pn
1219−prettyPrintExport ref = prettyPrintRef ref
1060+prettyPrintExport ref =
1061+ fromMaybe
1062+ (internalError "prettyPrintRef returned Nothing in prettyPrintExport")
1063+ (prettyPrintRef ref)
12201064
12211065prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
12221066prettyPrintImport mn idt qual =
12231067 let i = case idt of
12241068 Implicit -> runModuleName mn
1225− Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1226− Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1069+ Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (mapMaybe prettyPrintRef refs) ++ ")"
1070+ Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (mapMaybe prettyPrintRef refs) ++ ")"
12271071 in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
12281072
1229−prettyPrintRef :: DeclarationRef -> String
1230−prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1231−prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1232−prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1233−prettyPrintRef (TypeOpRef ident) = "type " ++ showIdent ident
1234−prettyPrintRef (ValueRef ident) = showIdent ident
1235−prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1236−prettyPrintRef (ProperRef name) = name
1237−prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1238−prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1239−prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1073+prettyPrintRef :: DeclarationRef -> Maybe String
1074+prettyPrintRef (TypeRef pn Nothing) =
1075+ Just $ runProperName pn ++ "(..)"
1076+prettyPrintRef (TypeRef pn (Just [])) =
1077+ Just $ runProperName pn
1078+prettyPrintRef (TypeRef pn (Just dctors)) =
1079+ Just $ runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1080+prettyPrintRef (TypeOpRef op) =
1081+ Just $ "type " ++ showOp op
1082+prettyPrintRef (ValueRef ident) =
1083+ Just $ showIdent ident
1084+prettyPrintRef (ValueOpRef op) =
1085+ Just $ showOp op
1086+prettyPrintRef (TypeClassRef pn) =
1087+ Just $ "class " ++ runProperName pn
1088+prettyPrintRef (TypeInstanceRef ident) =
1089+ Just $ showIdent ident
1090+prettyPrintRef (ModuleRef name) =
1091+ Just $ "module " ++ runModuleName name
1092+prettyPrintRef (ReExportRef _ _) =
1093+ Nothing
1094+prettyPrintRef (PositionedDeclarationRef _ _ ref) =
1095+ prettyPrintRef ref
12401096
12411097-- |
12421098-- Pretty print multiple errors
12431099--
1244−prettyPrintMultipleErrors :: Bool -> MultipleErrors -> String
1245−prettyPrintMultipleErrors full = unlines . map renderBox . prettyPrintMultipleErrorsBox full
1100+prettyPrintMultipleErrors :: PPEOptions -> MultipleErrors -> String
1101+prettyPrintMultipleErrors ppeOptions = unlines . map renderBox . prettyPrintMultipleErrorsBox ppeOptions
12461102
12471103-- |
12481104-- Pretty print multiple warnings
12491105--
1250−prettyPrintMultipleWarnings :: Bool -> MultipleErrors -> String
1251−prettyPrintMultipleWarnings full = unlines . map renderBox . prettyPrintMultipleWarningsBox full
1106+prettyPrintMultipleWarnings :: PPEOptions -> MultipleErrors -> String
1107+prettyPrintMultipleWarnings ppeOptions = unlines . map renderBox . prettyPrintMultipleWarningsBox ppeOptions
12521108
12531109-- | Pretty print warnings as a Box
1254−prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> [Box.Box]
1255−prettyPrintMultipleWarningsBox = prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning"
1110+prettyPrintMultipleWarningsBox :: PPEOptions -> MultipleErrors -> [Box.Box]
1111+prettyPrintMultipleWarningsBox ppeOptions = prettyPrintMultipleErrorsWith (ppeOptions { ppeLevel = Warning }) "Warning found:" "Warning"
12561112
12571113-- | Pretty print errors as a Box
1258−prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> [Box.Box]
1259−prettyPrintMultipleErrorsBox = prettyPrintMultipleErrorsWith Error "Error found:" "Error"
1114+prettyPrintMultipleErrorsBox :: PPEOptions -> MultipleErrors -> [Box.Box]
1115+prettyPrintMultipleErrorsBox ppeOptions = prettyPrintMultipleErrorsWith (ppeOptions { ppeLevel = Error }) "Error found:" "Error"
12601116
1261−prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> [Box.Box]
1262−prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) =
1263− let result = prettyPrintSingleError full level True e
1117+prettyPrintMultipleErrorsWith :: PPEOptions -> String -> String -> MultipleErrors -> [Box.Box]
1118+prettyPrintMultipleErrorsWith ppeOptions intro _ (MultipleErrors [e]) =
1119+ let result = prettyPrintSingleError ppeOptions e
12641120 in [ Box.vcat Box.left [ Box.text intro
12651121 , result
12661122 ]
12671123 ]
1268−prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) =
1269− let result = map (prettyPrintSingleError full level True) es
1124+prettyPrintMultipleErrorsWith ppeOptions _ intro (MultipleErrors es) =
1125+ let result = map (prettyPrintSingleError ppeOptions) es
12701126 in concat $ zipWith withIntro [1 :: Int ..] result
12711127 where
12721128 withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
src/Language/PureScript/Errors/JSON.hs+15−22
@@ -1,22 +1,7 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Errors.JSON
4−-- Copyright : (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess
5−-- License : MIT (http://opensource.org/licenses/MIT)
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
151{-# LANGUAGE TemplateHaskell #-}
162
173module Language.PureScript.Errors.JSON where
184
19−import Prelude ()
205import Prelude.Compat
216
227import qualified Data.Aeson.TH as A
@@ -30,7 +15,10 @@ data ErrorPosition = ErrorPosition
3015 , endColumn :: Int
3116 } deriving (Show, Eq, Ord)
3217
33−data ErrorSuggestion = ErrorSuggestion { replacement :: String } deriving (Show, Eq)
18+data ErrorSuggestion = ErrorSuggestion
19+ { replacement :: String
20+ , replaceRange :: Maybe ErrorPosition
21+ } deriving (Show, Eq)
3422
3523data JSONError = JSONError
3624 { position :: Maybe ErrorPosition
@@ -40,7 +28,7 @@ data JSONError = JSONError
4028 , filename :: Maybe String
4129 , moduleName :: Maybe String
4230 , suggestion :: Maybe ErrorSuggestion
43− } deriving (Show, Eq)
31+ } deriving (Show, Eq)
4432
4533data JSONResult = JSONResult
4634 { warnings :: [JSONError]
@@ -59,12 +47,12 @@ toJSONErrors verbose level = map (toJSONError verbose level) . P.runMultipleErro
5947toJSONError :: Bool -> P.Level -> P.ErrorMessage -> JSONError
6048toJSONError verbose level e =
6149 JSONError (toErrorPosition <$> sspan)
62− (P.renderBox (P.prettyPrintSingleError verbose level False (P.stripModuleAndSpan e)))
50+ (P.renderBox (P.prettyPrintSingleError (P.PPEOptions Nothing verbose level False) (P.stripModuleAndSpan e)))
6351 (P.errorCode e)
6452 (P.wikiUri e)
6553 (P.spanName <$> sspan)
6654 (P.runModuleName <$> P.errorModule e)
67− (toSuggestion <$> P.errorSuggestion (P.unwrapErrorMessage e))
55+ (toSuggestion e)
6856 where
6957 sspan :: Maybe P.SourceSpan
7058 sspan = P.errorSpan e
@@ -75,6 +63,11 @@ toJSONError verbose level e =
7563 (P.sourcePosColumn (P.spanStart ss))
7664 (P.sourcePosLine (P.spanEnd ss))
7765 (P.sourcePosColumn (P.spanEnd ss))
78− toSuggestion :: P.ErrorSuggestion -> ErrorSuggestion
79−-- TODO: Adding a newline because source spans chomp everything up to the next character
80− toSuggestion (P.ErrorSuggestion s) = ErrorSuggestion $ if null s then s else s ++ "\n"
66+ toSuggestion :: P.ErrorMessage -> Maybe ErrorSuggestion
67+ toSuggestion em =
68+ case P.errorSuggestion $ P.unwrapErrorMessage em of
69+ Nothing -> Nothing
70+ Just s -> Just $ ErrorSuggestion (suggestionText s) (toErrorPosition <$> P.suggestionSpan em)
71+
72+ -- TODO: Adding a newline because source spans chomp everything up to the next character
73+ suggestionText (P.ErrorSuggestion s) = if null s then s else s ++ "\n"
src/Language/PureScript/Externs.hs+45−27
@@ -1,37 +1,35 @@
1−{-# LANGUAGE RecordWildCards #-}
2−{-# LANGUAGE PatternGuards #-}
31{-# LANGUAGE TemplateHaskell #-}
42
53-- |
6−-- This module generates code for \"externs\" files, i.e. files containing only foreign import declarations.
4+-- This module generates code for \"externs\" files, i.e. files containing only
5+-- foreign import declarations.
76--
87module Language.PureScript.Externs
98 ( ExternsFile(..)
109 , ExternsImport(..)
1110 , ExternsFixity(..)
11+ , ExternsTypeFixity(..)
1212 , ExternsDeclaration(..)
1313 , moduleToExternsFile
1414 , applyExternsFileToEnvironment
1515 ) where
1616
17−import Prelude ()
1817import Prelude.Compat
1918
19+import Data.Aeson.TH
20+import Data.Foldable (fold)
2021import Data.List (find, foldl')
2122import Data.Maybe (mapMaybe, maybeToList, fromMaybe)
22−import Data.Foldable (fold)
2323import Data.Version (showVersion)
24−import Data.Aeson.TH
25−
2624import qualified Data.Map as M
2725
28−import Language.PureScript.Crash
2926import Language.PureScript.AST
27+import Language.PureScript.Crash
3028import Language.PureScript.Environment
31−import Language.PureScript.Names
32−import Language.PureScript.Types
3329import Language.PureScript.Kinds
30+import Language.PureScript.Names
3431import Language.PureScript.TypeClassDictionaries
32+import Language.PureScript.Types
3533
3634import Paths_purescript as Paths
3735
@@ -48,9 +46,11 @@ data ExternsFile = ExternsFile
4846 , efImports :: [ExternsImport]
4947 -- | List of operators and their fixities
5048 , efFixities :: [ExternsFixity]
49+ -- | List of type operators and their fixities
50+ , efTypeFixities :: [ExternsTypeFixity]
5151 -- | List of type and value declaration
5252 , efDeclarations :: [ExternsDeclaration]
53− } deriving (Show, Read)
53+ } deriving (Show)
5454
5555-- | A module import in an externs file
5656data ExternsImport = ExternsImport
@@ -61,7 +61,7 @@ data ExternsImport = ExternsImport
6161 , eiImportType :: ImportDeclarationType
6262 -- | The imported-as name, for qualified imports
6363 , eiImportedAs :: Maybe ModuleName
64− } deriving (Show, Read)
64+ } deriving (Show)
6565
6666-- | A fixity declaration in an externs file
6767data ExternsFixity = ExternsFixity
@@ -71,10 +71,23 @@ data ExternsFixity = ExternsFixity
7171 -- | The precedence level of the operator
7272 , efPrecedence :: Precedence
7373 -- | The operator symbol
74− , efOperator :: String
74+ , efOperator :: OpName 'ValueOpName
75+ -- | The value the operator is an alias for
76+ , efAlias :: Qualified (Either Ident (ProperName 'ConstructorName))
77+ } deriving (Show)
78+
79+-- | A type fixity declaration in an externs file
80+data ExternsTypeFixity = ExternsTypeFixity
81+ {
82+ -- | The associativity of the operator
83+ efTypeAssociativity :: Associativity
84+ -- | The precedence level of the operator
85+ , efTypePrecedence :: Precedence
86+ -- | The operator symbol
87+ , efTypeOperator :: OpName 'TypeOpName
7588 -- | The value the operator is an alias for
76− , efAlias :: Maybe (Qualified FixityAlias)
77− } deriving (Show, Read)
89+ , efTypeAlias :: Qualified (ProperName 'TypeName)
90+ } deriving (Show)
7891
7992-- | A type or value declaration appearing in an externs file
8093data ExternsDeclaration =
@@ -117,7 +130,7 @@ data ExternsDeclaration =
117130 , edInstanceTypes :: [Type]
118131 , edInstanceConstraints :: Maybe [Constraint]
119132 }
120− deriving (Show, Read)
133+ deriving (Show)
121134
122135-- | Convert an externs file back into a module
123136applyExternsFileToEnvironment :: ExternsFile -> Environment -> Environment
@@ -127,7 +140,7 @@ applyExternsFileToEnvironment ExternsFile{..} = flip (foldl' applyDecl) efDeclar
127140 applyDecl env (EDType pn kind tyKind) = env { types = M.insert (qual pn) (kind, tyKind) (types env) }
128141 applyDecl env (EDTypeSynonym pn args ty) = env { typeSynonyms = M.insert (qual pn) (args, ty) (typeSynonyms env) }
129142 applyDecl env (EDDataConstructor pn dTy tNm ty nms) = env { dataConstructors = M.insert (qual pn) (dTy, tNm, ty, nms) (dataConstructors env) }
130− applyDecl env (EDValue ident ty) = env { names = M.insert (efModuleName, ident) (ty, External, Defined) (names env) }
143+ applyDecl env (EDValue ident ty) = env { names = M.insert (Qualified (Just efModuleName) ident) (ty, External, Defined) (names env) }
131144 applyDecl env (EDClass pn args members cs) = env { typeClasses = M.insert (qual pn) (args, members, cs) (typeClasses env) }
132145 applyDecl env (EDInstance className ident tys cs) = env { typeClassDictionaries = updateMap (updateMap (M.insert (qual ident) dict) className) (Just efModuleName) (typeClassDictionaries env) }
133146 where
@@ -150,22 +163,26 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
150163 efExports = exps
151164 efImports = mapMaybe importDecl ds
152165 efFixities = mapMaybe fixityDecl ds
166+ efTypeFixities = mapMaybe typeFixityDecl ds
153167 efDeclarations = concatMap toExternsDeclaration efExports
154168
155169 fixityDecl :: Declaration -> Maybe ExternsFixity
156− fixityDecl (FixityDeclaration (Fixity assoc prec) op alias) =
157− fmap (const (ExternsFixity assoc prec op alias)) (find exportsOp exps)
158− where
159− exportsOp :: DeclarationRef -> Bool
160− exportsOp (PositionedDeclarationRef _ _ r) = exportsOp r
161− exportsOp (ValueRef ident') = ident' == Op op
162− exportsOp (TypeOpRef ident') = ident' == Op op
163− exportsOp _ = False
170+ fixityDecl (ValueFixityDeclaration (Fixity assoc prec) name op) =
171+ fmap (const (ExternsFixity assoc prec op name)) (find (findOp getValueOpRef op) exps)
164172 fixityDecl (PositionedDeclaration _ _ d) = fixityDecl d
165173 fixityDecl _ = Nothing
166174
175+ typeFixityDecl :: Declaration -> Maybe ExternsTypeFixity
176+ typeFixityDecl (TypeFixityDeclaration (Fixity assoc prec) name op) =
177+ fmap (const (ExternsTypeFixity assoc prec op name)) (find (findOp getTypeOpRef op) exps)
178+ typeFixityDecl (PositionedDeclaration _ _ d) = typeFixityDecl d
179+ typeFixityDecl _ = Nothing
180+
181+ findOp :: (DeclarationRef -> Maybe (OpName a)) -> OpName a -> DeclarationRef -> Bool
182+ findOp get op = maybe False (== op) . get
183+
167184 importDecl :: Declaration -> Maybe ExternsImport
168− importDecl (ImportDeclaration m mt qmn _) = Just (ExternsImport m mt qmn)
185+ importDecl (ImportDeclaration m mt qmn) = Just (ExternsImport m mt qmn)
169186 importDecl (PositionedDeclaration _ _ d) = importDecl d
170187 importDecl _ = Nothing
171188
@@ -184,7 +201,7 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
184201 ]
185202 _ -> internalError "toExternsDeclaration: Invalid input"
186203 toExternsDeclaration (ValueRef ident)
187− | Just (ty, _, _) <- (mn, ident) `M.lookup` names env
204+ | Just (ty, _, _) <- Qualified (Just mn) ident `M.lookup` names env
188205 = [ EDValue ident ty ]
189206 toExternsDeclaration (TypeClassRef className)
190207 | Just (args, members, implies) <- Qualified (Just mn) className `M.lookup` typeClasses env
@@ -204,5 +221,6 @@ moduleToExternsFile (Module _ _ mn ds (Just exps)) env = ExternsFile{..}
204221
205222$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsImport)
206223$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsFixity)
224+$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsTypeFixity)
207225$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsDeclaration)
208226$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ExternsFile)
src/Language/PureScript/Ide.hs+134−183
@@ -12,34 +12,18 @@
1212-- Interface for the psc-ide-server
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE MultiParamTypeClasses #-}
1815{-# LANGUAGE OverloadedStrings #-}
1916{-# LANGUAGE PackageImports #-}
2017{-# LANGUAGE TemplateHaskell #-}
21−{-# LANGUAGE TupleSections #-}
2218
2319module Language.PureScript.Ide
2420 ( handleCommand
25− -- for tests
26− , printModules
2721 ) where
2822
29−import Prelude ()
30−import Prelude.Compat
23+import Protolude
3124
32−import Control.Monad (unless)
33−import Control.Monad.Error.Class
34−import Control.Monad.IO.Class
3525import "monad-logger" Control.Monad.Logger
36−import Control.Monad.Reader.Class
37−import Data.Foldable
38−import qualified Data.Map.Lazy as M
39−import Data.Maybe (catMaybes, mapMaybe)
40−import Data.Monoid
41−import Data.Text (Text)
42−import qualified Data.Text as T
26+import qualified Language.PureScript as P
4327import qualified Language.PureScript.Ide.CaseSplit as CS
4428import Language.PureScript.Ide.Command
4529import Language.PureScript.Ide.Completion
@@ -50,196 +34,163 @@ import Language.PureScript.Ide.Imports hiding (Import)
5034import Language.PureScript.Ide.Matcher
5135import Language.PureScript.Ide.Pursuit
5236import Language.PureScript.Ide.Rebuild
53−import Language.PureScript.Ide.Reexports
5437import Language.PureScript.Ide.SourceFile
5538import Language.PureScript.Ide.State
5639import Language.PureScript.Ide.Types
5740import Language.PureScript.Ide.Util
5841import System.Directory
59−import System.Exit
6042import System.FilePath
43+import System.FilePath.Glob
6144
62−handleCommand :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
45+-- | Accepts a Commmand and runs it against psc-ide's State. This is the main
46+-- entry point for the server.
47+handleCommand :: (Ide m, MonadLogger m, MonadError PscIdeError m) =>
6348 Command -> m Success
64−handleCommand (Load [] []) = loadAllModules
65−handleCommand (Load modules deps) =
66− loadModulesAndDeps modules deps
67−handleCommand (Type search filters) =
68− findType search filters
69−handleCommand (Complete filters matcher) =
70− findCompletions filters matcher
71−handleCommand (Pursuit query Package) =
72− findPursuitPackages query
73−handleCommand (Pursuit query Identifier) =
74− findPursuitCompletions query
75−handleCommand (List LoadedModules) =
76− printModules
77−handleCommand (List AvailableModules) =
78− listAvailableModules
79−handleCommand (List (Imports fp)) =
80− importsForFile fp
81−handleCommand (CaseSplit l b e wca t) =
82− caseSplit l b e wca t
83−handleCommand (AddClause l wca) =
84− pure $ addClause l wca
85−handleCommand (Import fp outfp _ (AddImplicitImport mn)) = do
86− rs <- addImplicitImport fp mn
87− answerRequest outfp rs
88−handleCommand (Import fp outfp filters (AddImportForIdentifier ident)) = do
89− rs <- addImportForIdentifier fp ident filters
90− case rs of
91− Right rs' -> answerRequest outfp rs'
92− Left question -> pure $ CompletionResult (mapMaybe completionFromMatch question)
93−handleCommand (Rebuild file) =
94− rebuildFile file
95−handleCommand Cwd =
96− TextResult . T.pack <$> liftIO getCurrentDirectory
97−handleCommand Quit = liftIO exitSuccess
98−
99−findCompletions :: (PscIde m, MonadLogger m) =>
100− [Filter] -> Matcher -> m Success
101−findCompletions filters matcher =
102− CompletionResult . mapMaybe completionFromMatch . getCompletions filters matcher <$> getAllModulesWithReexports
103−
104−findType :: (PscIde m, MonadLogger m) =>
105− DeclIdent -> [Filter] -> m Success
106−findType search filters =
107− CompletionResult . mapMaybe completionFromMatch . getExactMatches search filters <$> getAllModulesWithReexports
108−
109−findPursuitCompletions :: (MonadIO m, MonadLogger m) =>
49+handleCommand c = case c of
50+ Load [] ->
51+ findAvailableExterns >>= loadModules
52+ Load modules ->
53+ loadModules modules
54+ Type search filters currentModule ->
55+ findType search filters currentModule
56+ Complete filters matcher currentModule ->
57+ findCompletions filters matcher currentModule
58+ Pursuit query Package ->
59+ findPursuitPackages query
60+ Pursuit query Identifier ->
61+ findPursuitCompletions query
62+ List LoadedModules ->
63+ printModules
64+ List AvailableModules ->
65+ listAvailableModules
66+ List (Imports fp) ->
67+ ImportList <$> getImportsForFile fp
68+ CaseSplit l b e wca t ->
69+ caseSplit l b e wca t
70+ AddClause l wca ->
71+ MultilineTextResult <$> CS.addClause l wca
72+ Import fp outfp _ (AddImplicitImport mn) -> do
73+ rs <- addImplicitImport fp mn
74+ answerRequest outfp rs
75+ Import fp outfp filters (AddImportForIdentifier ident) -> do
76+ rs <- addImportForIdentifier fp ident filters
77+ case rs of
78+ Right rs' -> answerRequest outfp rs'
79+ Left question ->
80+ pure (CompletionResult (map completionFromMatch question))
81+ Rebuild file ->
82+ rebuildFile file
83+ Cwd ->
84+ TextResult . toS <$> liftIO getCurrentDirectory
85+ Reset ->
86+ resetIdeState $> TextResult "State has been reset."
87+ Quit ->
88+ liftIO exitSuccess
89+
90+findCompletions :: Ide m =>
91+ [Filter] -> Matcher IdeDeclaration -> Maybe P.ModuleName -> m Success
92+findCompletions filters matcher currentModule = do
93+ modules <- getAllModules currentModule
94+ pure . CompletionResult . map completionFromMatch . getCompletions filters matcher $ modules
95+
96+findType :: Ide m =>
97+ Text -> [Filter] -> Maybe P.ModuleName -> m Success
98+findType search filters currentModule = do
99+ modules <- getAllModules currentModule
100+ pure . InfoResult . map infoFromMatch . getExactMatches search filters $ modules
101+
102+findPursuitCompletions :: MonadIO m =>
110103 PursuitQuery -> m Success
111104findPursuitCompletions (PursuitQuery q) =
112105 PursuitResult <$> liftIO (searchPursuitForDeclarations q)
113106
114−findPursuitPackages :: (MonadIO m, MonadLogger m) =>
107+findPursuitPackages :: MonadIO m =>
115108 PursuitQuery -> m Success
116109findPursuitPackages (PursuitQuery q) =
117110 PursuitResult <$> liftIO (findPackagesForModuleIdent q)
118111
119−loadExtern ::(PscIde m, MonadLogger m, MonadError PscIdeError m) =>
120− FilePath -> m ()
121−loadExtern fp = do
122− m <- readExternFile fp
123− insertModule m
112+printModules :: Ide m => m Success
113+printModules = ModuleList . map runModuleNameT <$> getLoadedModulenames
124114
125−printModules :: (PscIde m) => m Success
126−printModules = printModules' <$> getPscIdeState
127−
128−printModules' :: M.Map ModuleIdent [ExternDecl] -> Success
129−printModules' = ModuleList . M.keys
115+outputDirectory :: Ide m => m FilePath
116+outputDirectory = do
117+ outputPath <- confOutputPath . ideConfiguration <$> ask
118+ cwd <- liftIO getCurrentDirectory
119+ pure (cwd </> outputPath)
130120
131−listAvailableModules :: PscIde m => m Success
121+listAvailableModules :: Ide m => m Success
132122listAvailableModules = do
133− outputPath <- confOutputPath . envConfiguration <$> ask
123+ oDir <- outputDirectory
134124 liftIO $ do
135− cwd <- getCurrentDirectory
136− dirs <- getDirectoryContents (cwd </> outputPath)
137− return (ModuleList (listAvailableModules' dirs))
138−
139−listAvailableModules' :: [FilePath] -> [Text]
140−listAvailableModules' dirs =
141− let cleanedModules = filter (`notElem` [".", ".."]) dirs
142− in map T.pack cleanedModules
125+ contents <- getDirectoryContents oDir
126+ let cleaned = filter (`notElem` [".", ".."]) contents
127+ return (ModuleList (map toS cleaned))
143128
144−caseSplit :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
129+caseSplit :: (Ide m, MonadError PscIdeError m) =>
145130 Text -> Int -> Int -> CS.WildcardAnnotations -> Text -> m Success
146131caseSplit l b e csa t = do
147132 patterns <- CS.makePattern l b e csa <$> CS.caseSplit t
148133 pure (MultilineTextResult patterns)
149134
150−addClause :: Text -> CS.WildcardAnnotations -> Success
151−addClause t wca = MultilineTextResult (CS.addClause t wca)
152−
153−importsForFile :: (MonadIO m, MonadLogger m, MonadError PscIdeError m) =>
154− FilePath -> m Success
155−importsForFile fp = do
156− imports <- getImportsForFile fp
157− pure (ImportList imports)
158−
159−-- | The first argument is a set of modules to load. The second argument
160−-- denotes modules for which to load dependencies
161−loadModulesAndDeps :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
162− [ModuleIdent] -> [ModuleIdent] -> m Success
163−loadModulesAndDeps mods deps = do
164− r1 <- mapM loadModule (mods ++ deps)
165− r2 <- mapM loadModuleDependencies deps
166− let moduleResults = T.concat r1
167− let dependencyResults = T.concat r2
168− pure (TextResult (moduleResults <> ", " <> dependencyResults))
169−
170−loadModuleDependencies ::(PscIde m, MonadLogger m, MonadError PscIdeError m) =>
171− ModuleIdent -> m Text
172−loadModuleDependencies moduleName = do
173− m <- getModule moduleName
174− case getDependenciesForModule <$> m of
175− Just deps -> do
176− mapM_ loadModule deps
177− -- We need to load the modules, that get reexported from the dependencies
178− depModules <- catMaybes <$> mapM getModule deps
179− -- What to do with errors here? This basically means a reexported dependency
180− -- doesn't exist in the output/ folder
181− traverse_ loadReexports depModules
182− pure ("Dependencies for " <> moduleName <> " loaded.")
183− Nothing -> throwError (ModuleNotFound moduleName)
184−
185−loadReexports :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
186− Module -> m [ModuleIdent]
187−loadReexports m = case getReexports m of
188− [] -> pure []
189− exportDeps -> do
190− -- I'm fine with this crashing on a failed pattern match.
191− -- If this ever fails I'll need to look at GADTs
192− let reexports = map (\(Export mn) -> mn) exportDeps
193− $(logDebug) ("Loading reexports for module: " <> fst m <>
194− " reexports: " <> T.intercalate ", " reexports)
195− traverse_ loadModule reexports
196− exportDepsModules <- catMaybes <$> traverse getModule reexports
197− exportDepDeps <- traverse loadReexports exportDepsModules
198− return $ concat exportDepDeps
199−
200−getDependenciesForModule :: Module -> [ModuleIdent]
201−getDependenciesForModule (_, decls) = mapMaybe getDependencyName decls
202− where getDependencyName (Dependency dependencyName _ _) = Just dependencyName
203− getDependencyName _ = Nothing
204−
205−loadModule :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
206− ModuleIdent -> m Text
207−loadModule "Prim" = pure "Prim won't be loaded"
208−loadModule mn = do
209− path <- filePathFromModule mn
210− loadExtern path
211− $(logDebug) ("Loaded extern file at: " <> T.pack path)
212− pure ("Loaded extern file at: " <> T.pack path)
213−
214−loadAllModules :: (PscIde m, MonadLogger m, MonadError PscIdeError m) => m Success
215−loadAllModules = do
216− outputPath <- confOutputPath . envConfiguration <$> ask
217− cwd <- liftIO getCurrentDirectory
218− let outputDirectory = cwd </> outputPath
219− liftIO (doesDirectoryExist outputDirectory)
220− >>= flip unless (throwError (GeneralError "Couldn't locate your output directory"))
221− liftIO (getDirectoryContents outputDirectory)
222− >>= liftIO . traverse (getExternsPath outputDirectory)
223− >>= traverse_ loadExtern . catMaybes
224− pure (TextResult "All modules loaded.")
135+-- | Finds all the externs.json files inside the output folder and returns the
136+-- corresponding Modulenames
137+findAvailableExterns :: (Ide m, MonadError PscIdeError m) => m [P.ModuleName]
138+findAvailableExterns = do
139+ oDir <- outputDirectory
140+ unlessM (liftIO (doesDirectoryExist oDir))
141+ (throwError (GeneralError "Couldn't locate your output directory."))
142+ liftIO $ do
143+ directories <- getDirectoryContents oDir
144+ moduleNames <- filterM (containsExterns oDir) directories
145+ pure (P.moduleNameFromString <$> moduleNames)
225146 where
226− getExternsPath :: FilePath -> FilePath -> IO (Maybe FilePath)
227− getExternsPath outputDirectory d
228− | d `elem` [".", ".."] = pure Nothing
147+ -- Takes the output directory and a filepath like "Monad.Control.Eff" and
148+ -- looks up, whether that folder contains an externs.json
149+ containsExterns :: FilePath -> FilePath -> IO Bool
150+ containsExterns oDir d
151+ | d `elem` [".", ".."] = pure False
229152 | otherwise = do
230− let file = outputDirectory </> d </> "externs.json"
231− ex <- doesFileExist file
232− if ex
233− then pure (Just file)
234− else pure Nothing
235−
236−filePathFromModule :: (PscIde m, MonadError PscIdeError m) =>
237− ModuleIdent -> m FilePath
238−filePathFromModule moduleName = do
239− outputPath <- confOutputPath . envConfiguration <$> ask
240− cwd <- liftIO getCurrentDirectory
241− let path = cwd </> outputPath </> T.unpack moduleName </> "externs.json"
242− ex <- liftIO $ doesFileExist path
243− if ex
244− then pure path
245− else throwError (ModuleFileNotFound moduleName)
153+ let file = oDir </> d </> "externs.json"
154+ doesFileExist file
155+
156+-- | Finds all matches for the globs specified at the commandline
157+findAllSourceFiles :: Ide m => m [FilePath]
158+findAllSourceFiles = do
159+ globs <- confGlobs . ideConfiguration <$> ask
160+ liftIO (concatMapM glob globs)
161+
162+-- | Looks up the ExternsFiles for the given Modulenames and loads them into the
163+-- server state. Then proceeds to parse all the specified sourcefiles and
164+-- inserts their ASTs into the state. Finally kicks off an async worker, which
165+-- populates Stage 2 and 3 of the state.
166+loadModules
167+ :: (Ide m, MonadError PscIdeError m, MonadLogger m)
168+ => [P.ModuleName]
169+ -> m Success
170+loadModules moduleNames = do
171+ -- We resolve all the modulenames to externs files and load these into memory.
172+ oDir <- outputDirectory
173+ let efPaths =
174+ map (\mn -> oDir </> P.runModuleName mn </> "externs.json") moduleNames
175+ efiles <- traverse readExternFile efPaths
176+ traverse_ insertExterns efiles
177+
178+ -- We parse all source files, log eventual parse failures if the debug flag
179+ -- was set and insert the succesful parses into the state.
180+ (failures, allModules) <-
181+ partitionEithers <$> (traverse parseModule =<< findAllSourceFiles)
182+ unless (null failures) $
183+ $(logDebug) ("Failed to parse: " <> show failures)
184+ traverse_ insertModule allModules
185+
186+ -- Finally we kick off the worker with @async@ and return the number of
187+ -- successfully parsed modules.
188+ env <- ask
189+ let runLogger =
190+ runStdoutLoggingT
191+ . filterLogger (\_ _ -> confDebug (ideConfiguration env))
192+ -- populateStage2 and 3 return Unit for now, so it's fine to discard this
193+ -- result. We might want to block on this in a benchmarking situation.
194+ _ <- liftIO (async (runLogger (runReaderT (populateStage2 *> populateStage3) env)))
195+ pure (TextResult ("Loaded " <> show (length efiles) <> " modules and "
196+ <> show (length allModules) <> " source files."))
src/Language/PureScript/Ide/CaseSplit.hs+24−36
@@ -12,14 +12,7 @@
1212-- Casesplitting and adding function clauses
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE DataKinds #-}
17−{-# LANGUAGE FlexibleContexts #-}
18−{-# LANGUAGE LambdaCase #-}
19−{-# LANGUAGE MultiParamTypeClasses #-}
2015{-# LANGUAGE OverloadedStrings #-}
21−{-# LANGUAGE PackageImports #-}
22−{-# LANGUAGE RecordWildCards #-}
2316
2417module Language.PureScript.Ide.CaseSplit
2518 ( WildcardAnnotations()
@@ -30,26 +23,19 @@ module Language.PureScript.Ide.CaseSplit
3023 , caseSplit
3124 ) where
3225
33−import Prelude ()
34−import Prelude.Compat hiding (lex)
26+import Protolude hiding (Constructor)
3527
36−import Control.Arrow (second)
37−import Control.Monad.Error.Class
38−import "monad-logger" Control.Monad.Logger
39−import Data.List (find)
40−import Data.Monoid
41−import Data.Text (Text)
4228import qualified Data.Text as T
4329import qualified Language.PureScript as P
4430
4531import Language.PureScript.Externs
4632import Language.PureScript.Ide.Error
47−import Language.PureScript.Ide.Externs (unwrapPositioned)
4833import Language.PureScript.Ide.State
4934import Language.PureScript.Ide.Types
5035import Language.PureScript.Ide.Util
5136
5237import Text.Parsec as Parsec
38+import qualified Text.PrettyPrint.Boxes as Box
5339
5440type Constructor = (P.ProperName 'P.ConstructorName, [P.Type])
5541
@@ -61,17 +47,17 @@ explicitAnnotations = WildcardAnnotations True
6147noAnnotations :: WildcardAnnotations
6248noAnnotations = WildcardAnnotations False
6349
64−caseSplit :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
50+caseSplit :: (Ide m, MonadError PscIdeError m) =>
6551 Text -> m [Constructor]
6652caseSplit q = do
67− type' <- parseType' (T.unpack q)
53+ type' <- parseType' q
6854 (tc, args) <- splitTypeConstructor type'
6955 (EDType _ _ (P.DataType typeVars ctors)) <- findTypeDeclaration tc
7056 let applyTypeVars = P.everywhereOnTypes (P.replaceAllTypeVars (zip (map fst typeVars) args))
7157 let appliedCtors = map (second (map applyTypeVars)) ctors
7258 pure appliedCtors
7359
74−findTypeDeclaration :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
60+findTypeDeclaration :: (Ide m, MonadError PscIdeError m) =>
7561 P.ProperName 'P.TypeName -> m ExternsDeclaration
7662findTypeDeclaration q = do
7763 efs <- getExternFiles
@@ -121,39 +107,41 @@ makePattern t x y wsa = makePattern' (T.take x t) (T.drop y t)
121107 where
122108 makePattern' lhs rhs = map (\ctor -> lhs <> prettyCtor wsa ctor <> rhs)
123109
124−addClause :: Text -> WildcardAnnotations -> [Text]
125−addClause s wca =
126− let (fName, fType) = parseTypeDeclaration' (T.unpack s)
127− (args, _) = splitFunctionType fType
110+addClause :: (MonadError PscIdeError m) => Text -> WildcardAnnotations -> m [Text]
111+addClause s wca = do
112+ (fName, fType) <- parseTypeDeclaration' s
113+ let args = splitFunctionType fType
128114 template = runIdentT fName <> " " <>
129115 T.unwords (map (prettyPrintWildcard wca) args) <>
130116 " = ?" <> (T.strip . runIdentT $ fName)
131− in [s, template]
117+ pure [s, template]
132118
133119parseType' :: (MonadError PscIdeError m) =>
134− String -> m P.Type
120+ Text -> m P.Type
135121parseType' s =
136− case P.lex "<psc-ide>" s >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
122+ case P.lex "<psc-ide>" (toS s) >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
137123 Right type' -> pure type'
138124 Left err ->
139125 throwError (GeneralError ("Parsing the splittype failed with:"
140− ++ show err))
126+ <> show err))
141127
142−parseTypeDeclaration' :: String -> (P.Ident, P.Type)
128+parseTypeDeclaration' :: (MonadError PscIdeError m) => Text -> m (P.Ident, P.Type)
143129parseTypeDeclaration' s =
144130 let x = do
145− ts <- P.lex "" s
131+ ts <- P.lex "" (toS s)
146132 P.runTokenParser "" (P.parseDeclaration <* Parsec.eof) ts
147133 in
148134 case unwrapPositioned <$> x of
149− Right (P.TypeDeclaration i t) -> (i, t)
150− y -> error (show y)
151−
152−splitFunctionType :: P.Type -> ([P.Type], P.Type)
153−splitFunctionType t = (arguments, returns)
135+ Right (P.TypeDeclaration i t) -> pure (i, t)
136+ Right _ -> throwError (GeneralError "Found a non-type-declaration")
137+ Left err ->
138+ throwError (GeneralError ("Parsing the type signature failed with: "
139+ <> toS (Box.render (P.prettyPrintParseError err))))
140+
141+splitFunctionType :: P.Type -> [P.Type]
142+splitFunctionType t = fromMaybe [] arguments
154143 where
155− returns = last splitted
156− arguments = init splitted
144+ arguments = initMay splitted
157145 splitted = splitType' t
158146 splitType' (P.ForAll _ t' _) = splitType' t'
159147 splitType' (P.ConstrainedType _ t') = splitType' t'
src/Language/PureScript/Ide/Command.hs+62−72
@@ -12,38 +12,30 @@
1212-- Datatypes for the commands psc-ide accepts
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE MultiParamTypeClasses #-}
1615{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
1816
1917module Language.PureScript.Ide.Command where
2018
21−import Prelude ()
22−import Prelude.Compat
19+import Protolude
2320
24−import Control.Monad
2521import Data.Aeson
26−import Data.Maybe
27−import Data.Text (Text)
28−import Language.PureScript (ModuleName,
29− moduleNameFromString)
22+import qualified Language.PureScript as P
3023import Language.PureScript.Ide.CaseSplit
3124import Language.PureScript.Ide.Filter
3225import Language.PureScript.Ide.Matcher
3326import Language.PureScript.Ide.Types
3427
3528data Command
36− = Load
37− { loadModules :: [ModuleIdent]
38− , loadDependencies :: [ModuleIdent]
39− }
29+ = Load [P.ModuleName]
4030 | Type
41− { typeSearch :: DeclIdent
42− , typeFilters :: [Filter]
31+ { typeSearch :: Text
32+ , typeFilters :: [Filter]
33+ , typeCurrentModule :: Maybe P.ModuleName
4334 }
4435 | Complete
45− { completeFilters :: [Filter]
46− , completeMatcher :: Matcher
36+ { completeFilters :: [Filter]
37+ , completeMatcher :: Matcher IdeDeclaration
38+ , completeCurrentModule :: Maybe P.ModuleName
4739 }
4840 | Pursuit
4941 { pursuitQuery :: PursuitQuery
@@ -65,93 +57,91 @@ data Command
6557 | List { listType :: ListType }
6658 | Rebuild FilePath -- ^ Rebuild the specified file using the loaded externs
6759 | Cwd
60+ | Reset
6861 | Quit
6962
7063data ImportCommand
71− = AddImplicitImport ModuleName
72− | AddImportForIdentifier DeclIdent
64+ = AddImplicitImport P.ModuleName
65+ | AddImportForIdentifier Text
7366 deriving (Show, Eq)
7467
7568instance FromJSON ImportCommand where
7669 parseJSON = withObject "ImportCommand" $ \o -> do
77− (command :: String) <- o .: "importCommand"
70+ (command :: Text) <- o .: "importCommand"
7871 case command of
79− "addImplicitImport" -> do
80− mn <- o .: "module"
81− pure (AddImplicitImport (moduleNameFromString mn))
82− "addImport" -> do
83− ident <- o .: "identifier"
84− pure (AddImportForIdentifier ident)
72+ "addImplicitImport" ->
73+ AddImplicitImport <$> (P.moduleNameFromString <$> o .: "module")
74+ "addImport" ->
75+ AddImportForIdentifier <$> o .: "identifier"
8576 _ -> mzero
8677
8778data ListType = LoadedModules | Imports FilePath | AvailableModules
8879
8980instance FromJSON ListType where
9081 parseJSON = withObject "ListType" $ \o -> do
91− (listType' :: String) <- o .: "type"
82+ (listType' :: Text) <- o .: "type"
9283 case listType' of
93− "import" -> do
94− fp <- o .: "file"
95− return (Imports fp)
96− "loadedModules" -> return LoadedModules
97− "availableModules" -> return AvailableModules
84+ "import" -> Imports <$> o .: "file"
85+ "loadedModules" -> pure LoadedModules
86+ "availableModules" -> pure AvailableModules
9887 _ -> mzero
9988
10089instance FromJSON Command where
10190 parseJSON = withObject "command" $ \o -> do
102− (command :: String) <- o .: "command"
91+ (command :: Text) <- o .: "command"
10392 case command of
104− "list" -> do
105− listType' <- o .:? "params"
106− return $ List (fromMaybe LoadedModules listType')
107− "cwd" -> return Cwd
108− "quit" -> return Quit
109− "load" ->
110− maybe (pure (Load [] [])) (\params -> do
111− mods <- params .:? "modules"
112− deps <- params .:? "dependencies"
113− pure $ Load (fromMaybe [] mods) (fromMaybe [] deps)) =<< o .:? "params"
93+ "list" -> List <$> o .:? "params" .!= LoadedModules
94+ "cwd" -> pure Cwd
95+ "quit" -> pure Quit
96+ "reset" -> pure Reset
97+ "load" -> do
98+ params' <- o .:? "params"
99+ case params' of
100+ Nothing -> pure (Load [])
101+ Just params ->
102+ Load <$> (map P.moduleNameFromString <$> params .:? "modules" .!= [])
114103 "type" -> do
115104 params <- o .: "params"
116− search <- params .: "search"
117− filters <- params .: "filters"
118− return $ Type search filters
105+ Type
106+ <$> params .: "search"
107+ <*> params .: "filters"
108+ <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")
119109 "complete" -> do
120110 params <- o .: "params"
121− filters <- params .:? "filters"
122− matcher <- params .:? "matcher"
123− return $ Complete (fromMaybe [] filters) (fromMaybe mempty matcher)
111+ Complete
112+ <$> params .:? "filters" .!= []
113+ <*> params .:? "matcher" .!= mempty
114+ <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")
124115 "pursuit" -> do
125116 params <- o .: "params"
126− query <- params .: "query"
127− queryType <- params .: "type"
128− return $ Pursuit query queryType
117+ Pursuit
118+ <$> params .: "query"
119+ <*> params .: "type"
129120 "caseSplit" -> do
130121 params <- o .: "params"
131− line <- params .: "line"
132− begin <- params .: "begin"
133− end <- params .: "end"
134− annotations <- params .: "annotations"
135− type' <- params .: "type"
136− return $ CaseSplit line begin end (if annotations
137− then explicitAnnotations
138− else noAnnotations) type'
122+ CaseSplit
123+ <$> params .: "line"
124+ <*> params .: "begin"
125+ <*> params .: "end"
126+ <*> (mkAnnotations <$> params .: "annotations")
127+ <*> params .: "type"
139128 "addClause" -> do
140129 params <- o .: "params"
141− line <- params .: "line"
142− annotations <- params .: "annotations"
143− return $ AddClause line (if annotations
144− then explicitAnnotations
145− else noAnnotations)
130+ AddClause
131+ <$> params .: "line"
132+ <*> (mkAnnotations <$> params .: "annotations")
146133 "import" -> do
147134 params <- o .: "params"
148− fp <- params .: "file"
149− out <- params .:? "outfile"
150− filters <- params .:? "filters"
151− importCommand <- params .: "importCommand"
152− pure $ Import fp out (fromMaybe [] filters) importCommand
135+ Import
136+ <$> params .: "file"
137+ <*> params .:? "outfile"
138+ <*> params .:? "filters" .!= []
139+ <*> params .: "importCommand"
153140 "rebuild" -> do
154141 params <- o .: "params"
155− filePath <- params .: "file"
156− return $ Rebuild filePath
142+ Rebuild
143+ <$> params .: "file"
157144 _ -> mzero
145+ where
146+ mkAnnotations True = explicitAnnotations
147+ mkAnnotations False = noAnnotations
src/Language/PureScript/Ide/Completion.hs+17−17
@@ -1,32 +1,32 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Language.PureScript.Ide.Completion
3− (getCompletions, getExactMatches)
4− where
3+ ( getCompletions
4+ , getExactMatches
5+ ) where
56
6−import Prelude ()
7−import Prelude.Compat
7+import Protolude
88
9−import Data.Maybe (mapMaybe)
109import Language.PureScript.Ide.Filter
1110import Language.PureScript.Ide.Matcher
1211import Language.PureScript.Ide.Types
12+import Language.PureScript.Ide.Util
1313
1414-- | Applies the CompletionFilters and the Matcher to the given Modules
1515-- and sorts the found Completions according to the Matching Score
16−getCompletions :: [Filter] -> Matcher -> [Module] -> [Match]
16+getCompletions
17+ :: [Filter]
18+ -> Matcher IdeDeclaration
19+ -> [Module]
20+ -> [Match IdeDeclaration]
1721getCompletions filters matcher modules =
18− runMatcher matcher $ completionsFromModules (applyFilters filters modules)
22+ runMatcher matcher (completionsFromModules discardAnn (applyFilters filters modules))
1923
20−getExactMatches :: DeclIdent -> [Filter] -> [Module] -> [Match]
24+getExactMatches :: Text -> [Filter] -> [Module] -> [Match IdeDeclarationAnn]
2125getExactMatches search filters modules =
22− completionsFromModules $
23− applyFilters (equalityFilter search : filters) modules
26+ completionsFromModules identity (applyFilters (equalityFilter search : filters) modules)
2427
25−completionsFromModules :: [Module] -> [Match]
26−completionsFromModules = foldMap completionFromModule
28+completionsFromModules :: (IdeDeclarationAnn -> a) -> [Module] -> [Match a]
29+completionsFromModules f = foldMap completionFromModule
2730 where
28− completionFromModule :: Module -> [Match]
29− completionFromModule (moduleIdent, decls) = mapMaybe (matchFromDecl moduleIdent) decls
30−
31−matchFromDecl :: ModuleIdent -> ExternDecl -> Maybe Match
32−matchFromDecl mi = Just . Match mi
31+ completionFromModule (moduleName, decls) =
32+ map (\x -> Match (moduleName, f x)) decls
src/Language/PureScript/Ide/Conversions.hsnew file+35
@@ -0,0 +1,35 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : Language.PureScript.Ide.Conversions
4+-- Description : Conversions to Text for PureScript types
5+-- Copyright : Christoph Hegemann 2016
6+-- License : MIT (http://opensource.org/licenses/MIT)
7+--
8+-- Maintainer : Christoph Hegemann <christoph.hegemann1337@gmail.com>
9+-- Stability : experimental
10+--
11+-- |
12+-- Conversions to Text for PureScript types
13+-----------------------------------------------------------------------------
14+
15+module Language.PureScript.Ide.Conversions where
16+
17+import Protolude
18+import Data.Text (unwords, lines, strip)
19+import qualified Language.PureScript as P
20+
21+runProperNameT :: P.ProperName a -> Text
22+runProperNameT = toS . P.runProperName
23+
24+runIdentT :: P.Ident -> Text
25+runIdentT = toS . P.runIdent
26+
27+runOpNameT :: P.OpName a -> Text
28+runOpNameT = toS . P.runOpName
29+
30+runModuleNameT :: P.ModuleName -> Text
31+runModuleNameT = toS . P.runModuleName
32+
33+prettyTypeT :: P.Type -> Text
34+prettyTypeT = unwords . map strip . lines . toS . P.prettyPrintType
35+
src/Language/PureScript/Ide/Error.hs+8−11
@@ -14,24 +14,21 @@
1414
1515{-# LANGUAGE OverloadedStrings #-}
1616module Language.PureScript.Ide.Error
17− (ErrorMsg, PscIdeError(..), textError)
18− where
17+ ( PscIdeError(..)
18+ ) where
1919
20+import Protolude
2021import Data.Aeson
21−import Data.Monoid
22−import Data.Text (Text, pack)
2322import Language.PureScript.Errors.JSON
2423import Language.PureScript.Ide.Types (ModuleIdent)
2524import qualified Text.Parsec.Error as P
2625
27−type ErrorMsg = String
28−
2926data PscIdeError
30− = GeneralError ErrorMsg
27+ = GeneralError Text
3128 | NotFound Text
3229 | ModuleNotFound ModuleIdent
3330 | ModuleFileNotFound ModuleIdent
34− | ParseError P.ParseError ErrorMsg
31+ | ParseError P.ParseError Text
3532 | RebuildError [JSONError]
3633
3734instance ToJSON PscIdeError where
@@ -45,7 +42,7 @@ instance ToJSON PscIdeError where
4542 ]
4643
4744textError :: PscIdeError -> Text
48−textError (GeneralError msg) = pack msg
45+textError (GeneralError msg) = msg
4946textError (NotFound ident) = "Symbol '" <> ident <> "' not found."
5047textError (ModuleNotFound ident) = "Module '" <> ident <> "' not found."
5148textError (ModuleFileNotFound ident) = "Extern file for module " <> ident <>" could not be found"
@@ -53,5 +50,5 @@ textError (ParseError parseError msg) = let escape = show
5350 -- escape newlines and other special
5451 -- chars so we can send the error
5552 -- over the socket as a single line
56− in pack $ msg <> ": " <> show (escape parseError)
57−textError (RebuildError err) = pack (show err)
53+ in msg <> ": " <> escape parseError
54+textError (RebuildError err) = show err
src/Language/PureScript/Ide/Externs.hs+81−72
@@ -12,104 +12,113 @@
1212-- Handles externs files for psc-ide
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
17−{-# LANGUAGE OverloadedStrings #-}
18−{-# LANGUAGE RecordWildCards #-}
19−{-# LANGUAGE ScopedTypeVariables #-}
15+{-# LANGUAGE OverloadedStrings #-}
16+{-# LANGUAGE RecordWildCards #-}
17+{-# LANGUAGE FlexibleContexts #-}
2018
2119module Language.PureScript.Ide.Externs
22− ( ExternDecl(..),
23− ModuleIdent,
24− DeclIdent,
25− readExternFile,
20+ ( readExternFile,
2621 convertExterns,
27− unwrapPositioned,
28− unwrapPositionedRef
22+ annotateLocations
2923 ) where
3024
31−import Prelude ()
32−import Prelude.Compat
25+import Protolude
3326
34−import Control.Monad.Error.Class
35−import Control.Monad.IO.Class
3627import Data.Aeson (decodeStrict)
3728import Data.List (nub)
38−import Data.Maybe (mapMaybe)
39−import Data.Monoid
40−import Data.Text (Text)
41−import qualified Data.Text as T
29+import qualified Data.Map as Map
4230import qualified Data.ByteString as BS
4331import Language.PureScript.Ide.Error (PscIdeError (..))
4432import Language.PureScript.Ide.Types
4533import Language.PureScript.Ide.Util
4634
4735import qualified Language.PureScript as P
48−import qualified Language.PureScript.Externs as PE
4936
5037readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
51− FilePath -> m PE.ExternsFile
38+ FilePath -> m P.ExternsFile
5239readExternFile fp = do
5340 parseResult <- liftIO (decodeStrict <$> BS.readFile fp)
5441 case parseResult of
55− Nothing -> throwError . GeneralError $ "Parsing the extern at: " ++ fp ++ " failed"
42+ Nothing -> throwError . GeneralError $ "Parsing the extern at: " <> toS fp <> " failed"
5643 Just externs -> pure externs
5744
58−moduleNameToText :: P.ModuleName -> Text
59−moduleNameToText = T.pack . P.runModuleName
60−
61−identToText :: P.Ident -> Text
62−identToText = T.pack . P.runIdent
63−
64−convertExterns :: PE.ExternsFile -> Module
65−convertExterns ef = (moduleName, exportDecls ++ importDecls ++ decls)
45+convertExterns :: P.ExternsFile -> (Module, [(P.ModuleName, P.DeclarationRef)])
46+convertExterns ef =
47+ ((P.efModuleName ef, decls), exportDecls)
6648 where
67− moduleName = moduleNameToText (PE.efModuleName ef)
68− importDecls = convertImport <$> PE.efImports ef
69− exportDecls = mapMaybe (convertExport . unwrapPositionedRef) (PE.efExports ef)
70− -- Ignoring operator fixities for now since we're not using them
71− -- operatorDecls = convertOperator <$> PE.efFixities ef
72− otherDecls = mapMaybe convertDecl (PE.efDeclarations ef)
73−
74− typeClassFilter = foldMap removeTypeDeclarationsForClass (filter isTypeClassDeclaration otherDecls)
75− decls = nub $ appEndo typeClassFilter otherDecls
76−
77−removeTypeDeclarationsForClass :: ExternDecl -> Endo [ExternDecl]
78−removeTypeDeclarationsForClass (TypeClassDeclaration n) = Endo (filter notDuplicate)
79− where notDuplicate (TypeDeclaration n' _) = runProperNameT n /= runProperNameT n'
80− notDuplicate (TypeSynonymDeclaration n' _) = runProperNameT n /= runProperNameT n'
49+ decls = map
50+ (IdeDeclarationAnn emptyAnn)
51+ (cleanDeclarations ++ operatorDecls ++ tyOperatorDecls)
52+ exportDecls = mapMaybe (convertExport . unwrapPositionedRef) (P.efExports ef)
53+ operatorDecls = convertOperator <$> P.efFixities ef
54+ tyOperatorDecls = convertTypeOperator <$> P.efTypeFixities ef
55+ declarations = mapMaybe convertDecl (P.efDeclarations ef)
56+
57+ typeClassFilter = foldMap removeTypeDeclarationsForClass (filter isTypeClassDeclaration declarations)
58+ cleanDeclarations = nub $ appEndo typeClassFilter declarations
59+
60+removeTypeDeclarationsForClass :: IdeDeclaration -> Endo [IdeDeclaration]
61+removeTypeDeclarationsForClass (IdeTypeClass n) = Endo (filter notDuplicate)
62+ where notDuplicate (IdeType n' _) = runProperNameT n /= runProperNameT n'
63+ notDuplicate (IdeTypeSynonym n' _) = runProperNameT n /= runProperNameT n'
8164 notDuplicate _ = True
8265removeTypeDeclarationsForClass _ = mempty
8366
84−isTypeClassDeclaration :: ExternDecl -> Bool
85−isTypeClassDeclaration TypeClassDeclaration{} = True
67+isTypeClassDeclaration :: IdeDeclaration -> Bool
68+isTypeClassDeclaration IdeTypeClass{} = True
8669isTypeClassDeclaration _ = False
8770
88−convertImport :: PE.ExternsImport -> ExternDecl
89−convertImport ei = Dependency
90− (moduleNameToText (PE.eiModule ei))
91− []
92− (moduleNameToText <$> PE.eiImportedAs ei)
93−
94−convertExport :: P.DeclarationRef -> Maybe ExternDecl
95−convertExport (P.ModuleRef mn) = Just (Export (moduleNameToText mn))
71+convertExport :: P.DeclarationRef -> Maybe (P.ModuleName, P.DeclarationRef)
72+convertExport (P.ReExportRef m r) = Just (m, r)
9673convertExport _ = Nothing
9774
98−convertDecl :: PE.ExternsDeclaration -> Maybe ExternDecl
99−convertDecl PE.EDType{..} = Just $ TypeDeclaration edTypeName edTypeKind
100−convertDecl PE.EDTypeSynonym{..} = Just $
101− TypeSynonymDeclaration edTypeSynonymName edTypeSynonymType
102−convertDecl PE.EDDataConstructor{..} = Just $
103− DataConstructor (runProperNameT edDataCtorName) edDataCtorTypeCtor edDataCtorType
104−convertDecl PE.EDValue{..} = Just $
105− ValueDeclaration (identToText edValueName) edValueType
106−convertDecl PE.EDClass{..} = Just $ TypeClassDeclaration edClassName
107−convertDecl PE.EDInstance{} = Nothing
108−
109−unwrapPositioned :: P.Declaration -> P.Declaration
110−unwrapPositioned (P.PositionedDeclaration _ _ x) = x
111−unwrapPositioned x = x
112−
113−unwrapPositionedRef :: P.DeclarationRef -> P.DeclarationRef
114−unwrapPositionedRef (P.PositionedDeclarationRef _ _ x) = x
115−unwrapPositionedRef x = x
75+convertDecl :: P.ExternsDeclaration -> Maybe IdeDeclaration
76+convertDecl P.EDType{..} = Just (IdeType edTypeName edTypeKind)
77+convertDecl P.EDTypeSynonym{..} =
78+ Just (IdeTypeSynonym edTypeSynonymName edTypeSynonymType)
79+convertDecl P.EDDataConstructor{..} = Just $
80+ IdeDataConstructor edDataCtorName edDataCtorTypeCtor edDataCtorType
81+convertDecl P.EDValue{..} = Just $
82+ IdeValue edValueName edValueType
83+convertDecl P.EDClass{..} = Just (IdeTypeClass edClassName)
84+convertDecl P.EDInstance{} = Nothing
85+
86+convertOperator :: P.ExternsFixity -> IdeDeclaration
87+convertOperator P.ExternsFixity{..} =
88+ IdeValueOperator
89+ efOperator
90+ (toS (P.showQualified (either P.runIdent P.runProperName) efAlias))
91+ efPrecedence
92+ efAssociativity
93+
94+convertTypeOperator :: P.ExternsTypeFixity -> IdeDeclaration
95+convertTypeOperator P.ExternsTypeFixity{..} =
96+ IdeTypeOperator
97+ efTypeOperator
98+ (toS (P.showQualified P.runProperName efTypeAlias))
99+ efTypePrecedence
100+ efTypeAssociativity
101+
102+annotateLocations :: Map (Either Text Text) P.SourceSpan -> Module -> Module
103+annotateLocations ast (moduleName, decls) =
104+ (moduleName, map convertDeclaration decls)
105+ where
106+ convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn
107+ convertDeclaration (IdeDeclarationAnn ann d) = case d of
108+ IdeValue i t ->
109+ annotateValue (runIdentT i) (IdeValue i t)
110+ IdeType i k ->
111+ annotateType (runProperNameT i) (IdeType i k)
112+ IdeTypeSynonym i t ->
113+ annotateType (runProperNameT i) (IdeTypeSynonym i t)
114+ IdeDataConstructor i tn t ->
115+ annotateValue (runProperNameT i) (IdeDataConstructor i tn t)
116+ IdeTypeClass i ->
117+ annotateType (runProperNameT i) (IdeTypeClass i)
118+ IdeValueOperator n i p a ->
119+ annotateValue i (IdeValueOperator n i p a)
120+ IdeTypeOperator n i p a ->
121+ annotateType i (IdeTypeOperator n i p a)
122+ where
123+ annotateValue x = IdeDeclarationAnn (ann {annLocation = Map.lookup (Left x) ast})
124+ annotateType x = IdeDeclarationAnn (ann {annLocation = Map.lookup (Right x) ast})
src/Language/PureScript/Ide/Filter.hs+17−51
@@ -14,29 +14,22 @@
1414
1515{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1616{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
1817
1918module Language.PureScript.Ide.Filter
2019 ( Filter
2120 , moduleFilter
2221 , prefixFilter
2322 , equalityFilter
24− , dependencyFilter
25− , runFilter
2623 , applyFilters
2724 ) where
2825
29−import Prelude ()
30−import Prelude.Compat
26+import Protolude hiding (isPrefixOf)
3127
32−import Control.Monad
3328import Data.Aeson
34−import Data.Foldable
35−import Data.Maybe (listToMaybe, mapMaybe)
36−import Data.Monoid
37−import Data.Text (Text, isPrefixOf)
29+import Data.Text (isPrefixOf)
3830import Language.PureScript.Ide.Types
3931import Language.PureScript.Ide.Util
32+import qualified Language.PureScript as P
4033
4134newtype Filter = Filter (Endo [Module]) deriving(Monoid)
4235
@@ -44,69 +37,46 @@ mkFilter :: ([Module] -> [Module]) -> Filter
4437mkFilter = Filter . Endo
4538
4639-- | Only keeps the given Modules
47−moduleFilter :: [ModuleIdent] -> Filter
40+moduleFilter :: [P.ModuleName] -> Filter
4841moduleFilter =
4942 mkFilter . moduleFilter'
5043
51−moduleFilter' :: [ModuleIdent] -> [Module] -> [Module]
44+moduleFilter' :: [P.ModuleName] -> [Module] -> [Module]
5245moduleFilter' moduleIdents = filter (flip elem moduleIdents . fst)
5346
54−-- | Only keeps the given Modules and all of their dependencies
55−dependencyFilter :: [ModuleIdent] -> Filter
56−dependencyFilter = mkFilter . dependencyFilter'
57−
58−dependencyFilter' :: [ModuleIdent] -> [Module] -> [Module]
59−dependencyFilter' moduleIdents mods =
60− moduleFilter' (concatMap (getDepForModule mods) moduleIdents) mods
61− where
62− getDepForModule :: [Module] -> ModuleIdent -> [ModuleIdent]
63− getDepForModule ms moduleIdent =
64− moduleIdent : maybe [] extractDeps (findModule moduleIdent ms)
65−
66− findModule :: ModuleIdent -> [Module] -> Maybe Module
67− findModule i ms = listToMaybe $ filter go ms
68− where go (mn, _) = i == mn
69−
70− extractDeps :: Module -> [ModuleIdent]
71− extractDeps = mapMaybe extractDep . snd
72− where extractDep (Dependency n _ _) = Just n
73− extractDep _ = Nothing
74−
7547-- | Only keeps Identifiers that start with the given prefix
7648prefixFilter :: Text -> Filter
77−prefixFilter "" = mkFilter id
49+prefixFilter "" = mkFilter identity
7850prefixFilter t = mkFilter $ identFilter prefix t
7951 where
80− prefix :: ExternDecl -> Text -> Bool
81− prefix Export{} _ = False
82− prefix Dependency{} _ = False
83− prefix ed search = search `isPrefixOf` identifierFromExternDecl ed
84−
52+ prefix :: IdeDeclaration -> Text -> Bool
53+ prefix ed search = search `isPrefixOf` identifierFromIdeDeclaration ed
8554
8655-- | Only keeps Identifiers that are equal to the search string
8756equalityFilter :: Text -> Filter
8857equalityFilter = mkFilter . identFilter equality
8958 where
90− equality :: ExternDecl -> Text -> Bool
91− equality ed search = identifierFromExternDecl ed == search
59+ equality :: IdeDeclaration -> Text -> Bool
60+ equality ed search = identifierFromIdeDeclaration ed == search
9261
93−identFilter :: (ExternDecl -> Text -> Bool ) -> Text -> [Module] -> [Module]
62+identFilter :: (IdeDeclaration -> Text -> Bool) -> Text -> [Module] -> [Module]
9463identFilter predicate search =
9564 filter (not . null . snd) . fmap filterModuleDecls
9665 where
9766 filterModuleDecls :: Module -> Module
98− filterModuleDecls (moduleIdent,decls) =
99− (moduleIdent, filter (`predicate` search) decls)
67+ filterModuleDecls (moduleIdent, decls) =
68+ (moduleIdent, filter (flip predicate search . getDeclaration) decls)
69+ getDeclaration (IdeDeclarationAnn _ d) = d
10070
10171runFilter :: Filter -> [Module] -> [Module]
102−runFilter (Filter f)= appEndo f
72+runFilter (Filter f) = appEndo f
10373
10474applyFilters :: [Filter] -> [Module] -> [Module]
10575applyFilters = runFilter . fold
10676
10777instance FromJSON Filter where
10878 parseJSON = withObject "filter" $ \o -> do
109− (filter' :: String) <- o .: "filter"
79+ (filter' :: Text) <- o .: "filter"
11080 case filter' of
11181 "exact" -> do
11282 params <- o .: "params"
@@ -118,10 +88,6 @@ instance FromJSON Filter where
11888 return $ prefixFilter search
11989 "modules" -> do
12090 params <- o .: "params"
121− modules <- params .: "modules"
91+ modules <- map P.moduleNameFromString <$> params .: "modules"
12292 return $ moduleFilter modules
123− "dependencies" -> do
124− params <- o .: "params"
125− deps <- params .: "modules"
126− return $ dependencyFilter deps
12793 _ -> mzero
src/Language/PureScript/Ide/Imports.hs+44−67
@@ -12,12 +12,7 @@
1212-- Provides functionality to manage imports
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE LambdaCase #-}
18−{-# LANGUAGE MultiParamTypeClasses #-}
1915{-# LANGUAGE OverloadedStrings #-}
20−{-# LANGUAGE PackageImports #-}
2116
2217module Language.PureScript.Ide.Imports
2318 ( addImplicitImport
@@ -34,23 +29,13 @@ module Language.PureScript.Ide.Imports
3429 )
3530 where
3631
37−import Control.Applicative ((<|>))
38−import Control.Monad.Error.Class
39−import Control.Monad.IO.Class
40−import "monad-logger" Control.Monad.Logger
41−import Data.Bifunctor (first, second)
42−import Data.Function (on)
43−import qualified Data.List as List
44−import Data.Maybe (isNothing)
45−import Data.Monoid ((<>))
46−import Data.Text (Text)
32+import Protolude
4733import qualified Data.Text as T
34+import Data.List (nubBy, findIndex)
4835import qualified Data.Text.IO as TIO
4936import qualified Language.PureScript as P
5037import Language.PureScript.Ide.Completion
5138import Language.PureScript.Ide.Error
52−import Language.PureScript.Ide.Externs (unwrapPositioned,
53− unwrapPositionedRef)
5439import Language.PureScript.Ide.Filter
5540import Language.PureScript.Ide.State
5641import Language.PureScript.Ide.Types
@@ -90,23 +75,23 @@ parseImportsFromFile fp = do
9075 Right res -> pure res
9176 Left err -> throwError (GeneralError err)
9277
93−parseImportsWithModuleName :: [Text] -> Either String (P.ModuleName, [Import])
78+parseImportsWithModuleName :: [Text] -> Either Text (P.ModuleName, [Import])
9479parseImportsWithModuleName ls = do
9580 (P.Module _ _ mn decls _) <- moduleParse ls
9681 pure (mn, concatMap mkImport (unwrapPositioned <$> decls))
9782 where
98− mkImport (P.ImportDeclaration mn (P.Explicit refs) qual _) =
83+ mkImport (P.ImportDeclaration mn (P.Explicit refs) qual) =
9984 [Import mn (P.Explicit (unwrapPositionedRef <$> refs)) qual]
100− mkImport (P.ImportDeclaration mn it qual _) = [Import mn it qual]
85+ mkImport (P.ImportDeclaration mn it qual) = [Import mn it qual]
10186 mkImport _ = []
10287
103−sliceImportSection :: [Text] -> Either String (P.ModuleName, [Text], [Import], [Text])
88+sliceImportSection :: [Text] -> Either Text (P.ModuleName, [Text], [Import], [Text])
10489sliceImportSection ts =
10590 case foldl step (ModuleHeader 0) (zip [0..] ts) of
10691 Res start end ->
10792 let
10893 (moduleHeader, (importSection, remainingFile)) =
109− List.splitAt (succ (end - start)) `second` List.splitAt start ts
94+ splitAt (succ (end - start)) `second` splitAt start ts
11095 in
11196 (\(mn, is) -> (mn, moduleHeader, is, remainingFile)) <$>
11297 parseImportsWithModuleName (moduleHeader <> importSection)
@@ -114,7 +99,7 @@ sliceImportSection ts =
11499 -- If we don't find any imports, we insert a newline after the module
115100 -- declaration and begin a new importsection
116101 ModuleHeader ix ->
117− let (moduleHeader, remainingFile) = List.splitAt (succ ix) ts
102+ let (moduleHeader, remainingFile) = splitAt (succ ix) ts
118103 in
119104 (\(mn, is) -> (mn, moduleHeader ++ [""], is, remainingFile)) <$>
120105 parseImportsWithModuleName moduleHeader
@@ -156,7 +141,7 @@ step (ImportSection start lastImportLine) (ix, l)
156141 | otherwise = Res start lastImportLine
157142step (Res start end) _ = Res start end
158143
159−moduleParse :: [Text] -> Either String P.Module
144+moduleParse :: [Text] -> Either Text P.Module
160145moduleParse t = first show $ do
161146 tokens <- (P.lex "" . T.unpack . T.unlines) t
162147 P.runTokenParser "<psc-ide>" P.parseModule tokens
@@ -185,8 +170,8 @@ addImplicitImport' imports mn =
185170-- So @addExplicitImport "/File.purs" "bind" "Prelude"@ with an already existing
186171-- @import Prelude (bind)@ in the file File.purs returns @["import Prelude
187172-- (bind, unit)"]@
188−addExplicitImport :: (MonadIO m, MonadError PscIdeError m, MonadLogger m) =>
189− FilePath -> ExternDecl -> P.ModuleName -> m [Text]
173+addExplicitImport :: (MonadIO m, MonadError PscIdeError m) =>
174+ FilePath -> IdeDeclaration -> P.ModuleName -> m [Text]
190175addExplicitImport fp decl moduleName = do
191176 (mn, pre, imports, post) <- parseImportsFromFile fp
192177 let newImportSection =
@@ -197,7 +182,7 @@ addExplicitImport fp decl moduleName = do
197182 else addExplicitImport' decl moduleName imports
198183 pure (pre ++ prettyPrintImportSection newImportSection ++ post)
199184
200−addExplicitImport' :: ExternDecl -> P.ModuleName -> [Import] -> [Import]
185+addExplicitImport' :: IdeDeclaration -> P.ModuleName -> [Import] -> [Import]
201186addExplicitImport' decl moduleName imports =
202187 let
203188 isImplicitlyImported =
@@ -212,56 +197,49 @@ addExplicitImport' decl moduleName imports =
212197 then imports
213198 else updateAtFirstOrPrepend matches (insertDeclIntoImport decl) freshImport imports
214199 where
215− refFromDeclaration (TypeClassDeclaration n) = P.TypeClassRef n
216− refFromDeclaration (DataConstructor n tn _) =
217− P.TypeRef tn (Just [P.ProperName (T.unpack n)])
218− refFromDeclaration (TypeDeclaration n _) = P.TypeRef n (Just [])
200+ refFromDeclaration (IdeTypeClass n) =
201+ P.TypeClassRef n
202+ refFromDeclaration (IdeDataConstructor n tn _) =
203+ P.TypeRef tn (Just [n])
204+ refFromDeclaration (IdeType n _) =
205+ P.TypeRef n (Just [])
206+ refFromDeclaration (IdeValueOperator op _ _ _) =
207+ P.ValueOpRef op
208+ refFromDeclaration (IdeTypeOperator op _ _ _) =
209+ P.TypeOpRef op
219210 refFromDeclaration d =
220− let
221− ident = T.unpack (identifierFromExternDecl d)
222− in
223− P.ValueRef ((if all P.isSymbolChar ident then P.Op else P.Ident) ident)
211+ P.ValueRef $ P.Ident $ T.unpack (identifierFromIdeDeclaration d)
224212
225213 -- | Adds a declaration to an import:
226214 -- TypeDeclaration "Maybe" + Data.Maybe (maybe) -> Data.Maybe(Maybe, maybe)
227− insertDeclIntoImport :: ExternDecl -> Import -> Import
215+ insertDeclIntoImport :: IdeDeclaration -> Import -> Import
228216 insertDeclIntoImport decl' (Import mn (P.Explicit refs) Nothing) =
229217 Import mn (P.Explicit (insertDeclIntoRefs decl' refs)) Nothing
230218 insertDeclIntoImport _ is = is
231219
232− insertDeclIntoRefs :: ExternDecl -> [P.DeclarationRef] -> [P.DeclarationRef]
233− insertDeclIntoRefs (DataConstructor dtor tn _) refs =
234− let
235− dtor' = P.ProperName (T.unpack dtor)
236− -- TODO: Get rid of this once typeclasses can't be imported like types
237− refs' = properRefToTypeRef <$> refs
238− in
239− updateAtFirstOrPrepend (matchType tn) (insertDtor dtor') (P.TypeRef tn (Just [dtor'])) refs'
240− insertDeclIntoRefs dr refs = List.nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
220+ insertDeclIntoRefs :: IdeDeclaration -> [P.DeclarationRef] -> [P.DeclarationRef]
221+ insertDeclIntoRefs (IdeDataConstructor dtor tn _) refs =
222+ updateAtFirstOrPrepend (matchType tn) (insertDtor dtor) (P.TypeRef tn (Just [dtor])) refs
223+ insertDeclIntoRefs dr refs = nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
241224
242225 insertDtor dtor (P.TypeRef tn' dtors) =
243226 case dtors of
244− Just dtors' -> P.TypeRef tn' (Just (List.nub (dtor : dtors')))
227+ Just dtors' -> P.TypeRef tn' (Just (ordNub (dtor : dtors')))
245228 -- This means the import was opened. We don't add anything in this case
246229 -- import Data.Maybe (Maybe(..)) -> import Data.Maybe (Maybe(Just))
247230 Nothing -> P.TypeRef tn' Nothing
248231 insertDtor _ refs = refs
249232
250−
251− -- TODO: Get rid of this once typeclasses can't be imported like types
252− properRefToTypeRef (P.ProperRef n) = P.TypeRef (P.ProperName n) (Just [])
253− properRefToTypeRef r = r
254−
255233 matchType :: P.ProperName 'P.TypeName -> P.DeclarationRef -> Bool
256234 matchType tn (P.TypeRef n _) = tn == n
257235 matchType _ _ = False
258236
259237updateAtFirstOrPrepend :: (a -> Bool) -> (a -> a) -> a -> [a] -> [a]
260238updateAtFirstOrPrepend p t d l =
261− case List.findIndex p l of
239+ case findIndex p l of
262240 Nothing -> d : l
263241 Just ix ->
264− let (x, a : y) = List.splitAt ix l
242+ let (x, a : y) = splitAt ix l
265243 in x ++ [t a] ++ y
266244
267245-- | Looks up the given identifier in the currently loaded modules.
@@ -272,30 +250,30 @@ updateAtFirstOrPrepend p t d l =
272250--
273251-- * If more than one possible imports are found, reports the possibilities as a
274252-- list of completions.
275−addImportForIdentifier :: (PscIde m, MonadError PscIdeError m, MonadLogger m)
253+addImportForIdentifier :: (Ide m, MonadError PscIdeError m)
276254 => FilePath -- ^ The Sourcefile to read from
277255 -> Text -- ^ The identifier to import
278256 -> [Filter] -- ^ Filters to apply before searching for
279257 -- the identifier
280− -> m (Either [Match] [Text])
258+ -> m (Either [Match IdeDeclaration] [Text])
281259addImportForIdentifier fp ident filters = do
282− modules <- getAllModulesWithReexports
283− case getExactMatches ident filters modules of
260+ modules <- getAllModules Nothing
261+ case map (fmap discardAnn) (getExactMatches ident filters modules) of
284262 [] ->
285263 throwError (NotFound "Couldn't find the given identifier. \
286264 \Have you loaded the corresponding module?")
287265
288266 -- Only one match was found for the given identifier, so we can insert it
289267 -- right away
290− [Match m decl] ->
291− Right <$> addExplicitImport fp decl (P.moduleNameFromString (T.unpack m))
268+ [Match (m, decl)] ->
269+ Right <$> addExplicitImport fp decl m
292270
293271 -- This case comes up for newtypes and dataconstructors. Because values and
294272 -- types don't share a namespace we can get multiple matches from the same
295273 -- module. This also happens for parameterized types, as these generate both
296274 -- a type aswell as a type synonym.
297275
298− ms@[Match m1 d1, Match m2 d2] ->
276+ ms@[Match (m1, d1), Match (m2, d2)] ->
299277 if m1 /= m2
300278 -- If the modules don't line up we just ask the user to specify the
301279 -- module
@@ -305,7 +283,7 @@ addImportForIdentifier fp ident filters = do
305283 -- dataconstructor as that will give us an unnecessary import warning at
306284 -- worst
307285 Just decl ->
308− Right <$> addExplicitImport fp decl (P.moduleNameFromString (T.unpack m1))
286+ Right <$> addExplicitImport fp decl m1
309287 -- Here we need the user to specify whether he wanted a dataconstructor
310288 -- or a type
311289 Nothing ->
@@ -316,9 +294,9 @@ addImportForIdentifier fp ident filters = do
316294 xs ->
317295 pure $ Left xs
318296 where
319− decideRedundantCase dtor@(DataConstructor _ t _) (TypeDeclaration t' _) =
297+ decideRedundantCase dtor@(IdeDataConstructor _ t _) (IdeType t' _) =
320298 if t == t' then Just dtor else Nothing
321− decideRedundantCase TypeDeclaration{} ts@TypeSynonymDeclaration{} =
299+ decideRedundantCase IdeType{} ts@IdeTypeSynonym{} =
322300 Just ts
323301 decideRedundantCase _ _ = Nothing
324302
@@ -330,7 +308,7 @@ prettyPrintImport' (Import mn idt qual) =
330308 T.pack $ "import " ++ P.prettyPrintImport mn idt qual
331309
332310prettyPrintImportSection :: [Import] -> [Text]
333−prettyPrintImportSection imports = map prettyPrintImport' (List.sort imports)
311+prettyPrintImportSection imports = map prettyPrintImport' (sort imports)
334312
335313-- | Writes a list of lines to @Just filepath@ and responds with a @TextResult@,
336314-- or returns the lines as a @MultilineTextResult@ if @Nothing@ was given as the
@@ -348,8 +326,7 @@ parseImport :: Text -> Maybe Import
348326parseImport t =
349327 case P.lex "<psc-ide>" (T.unpack t)
350328 >>= P.runTokenParser "<psc-ide>" P.parseImportDeclaration' of
351− Right (mn, P.Explicit refs, mmn, _) ->
329+ Right (mn, P.Explicit refs, mmn) ->
352330 Just (Import mn (P.Explicit (unwrapPositionedRef <$> refs)) mmn)
353− Right (mn, idt, mmn, _) -> Just (Import mn idt mmn)
331+ Right (mn, idt, mmn) -> Just (Import mn idt mmn)
354332 Left _ -> Nothing
355−
src/Language/PureScript/Ide/Matcher.hs+26−33
@@ -14,24 +14,18 @@
1414
1515{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1616{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
17+{-# LANGUAGE FlexibleInstances #-}
1818
1919module Language.PureScript.Ide.Matcher
2020 ( Matcher
21− , flexMatcher
2221 , runMatcher
22+ -- for tests
23+ , flexMatcher
2324 ) where
2425
25−import Prelude ()
26−import Prelude.Compat
26+import Protolude
2727
28−import Control.Monad
2928import Data.Aeson
30−import Data.Function (on)
31−import Data.List (sortBy)
32−import Data.Maybe (mapMaybe)
33−import Data.Monoid
34−import Data.Text (Text)
3529import qualified Data.Text as T
3630import qualified Data.Text.Encoding as TE
3731import Language.PureScript.Ide.Types
@@ -40,23 +34,22 @@ import Text.EditDistance
4034import Text.Regex.TDFA ((=~))
4135
4236
43−type ScoredMatch = (Match, Double)
37+type ScoredMatch a = (Match a, Double)
4438
45−newtype Matcher = Matcher (Endo [Match]) deriving(Monoid)
39+newtype Matcher a = Matcher (Endo [Match a]) deriving (Monoid)
4640
47−instance FromJSON Matcher where
41+instance FromJSON (Matcher IdeDeclaration) where
4842 parseJSON = withObject "matcher" $ \o -> do
49− (matcher :: Maybe String) <- o .:? "matcher"
43+ (matcher :: Maybe Text) <- o .:? "matcher"
5044 case matcher of
5145 Just "flex" -> do
5246 params <- o .: "params"
53− search <- params .: "search"
54− pure $ flexMatcher search
47+ flexMatcher <$> params .: "search"
5548 Just "distance" -> do
5649 params <- o .: "params"
57− search <- params .: "search"
58− maxDist <- params .: "maximumDistance"
59− pure $ distanceMatcher search maxDist
50+ distanceMatcher
51+ <$> params .: "search"
52+ <*> params .: "maximumDistance"
6053 Just _ -> mzero
6154 Nothing -> return mempty
6255
@@ -67,37 +60,37 @@ instance FromJSON Matcher where
6760-- Examples:
6861-- flMa matches flexMatcher. Score: 14.28
6962-- sons matches sortCompletions. Score: 6.25
70−flexMatcher :: Text -> Matcher
63+flexMatcher :: Text -> Matcher IdeDeclaration
7164flexMatcher p = mkMatcher (flexMatch p)
7265
73−distanceMatcher :: Text -> Int -> Matcher
66+distanceMatcher :: Text -> Int -> Matcher IdeDeclaration
7467distanceMatcher q maxDist = mkMatcher (distanceMatcher' q maxDist)
7568
76−distanceMatcher' :: Text -> Int -> [Match] -> [ScoredMatch]
69+distanceMatcher' :: Text -> Int -> [Match IdeDeclaration] -> [ScoredMatch IdeDeclaration]
7770distanceMatcher' q maxDist = mapMaybe go
7871 where
7972 go m = let d = dist (T.unpack y)
80− y = identifierFromMatch m
73+ y = identifierFromIdeDeclaration (unwrapMatch m)
8174 in if d <= maxDist
8275 then Just (m, 1 / fromIntegral d)
8376 else Nothing
8477 dist = levenshteinDistance defaultEditCosts (T.unpack q)
8578
86−mkMatcher :: ([Match] -> [ScoredMatch]) -> Matcher
79+mkMatcher :: ([Match a] -> [ScoredMatch a]) -> Matcher a
8780mkMatcher matcher = Matcher . Endo $ fmap fst . sortCompletions . matcher
8881
89−runMatcher :: Matcher -> [Match] -> [Match]
82+runMatcher :: Matcher a -> [Match a] -> [Match a]
9083runMatcher (Matcher m)= appEndo m
9184
92−sortCompletions :: [ScoredMatch] -> [ScoredMatch]
85+sortCompletions :: [ScoredMatch a] -> [ScoredMatch a]
9386sortCompletions = sortBy (flip compare `on` snd)
9487
95−flexMatch :: Text -> [Match] -> [ScoredMatch]
88+flexMatch :: Text -> [Match IdeDeclaration] -> [ScoredMatch IdeDeclaration]
9689flexMatch = mapMaybe . flexRate
9790
98−flexRate :: Text -> Match -> Maybe ScoredMatch
91+flexRate :: Text -> Match IdeDeclaration -> Maybe (ScoredMatch IdeDeclaration)
9992flexRate p c = do
100− score <- flexScore p (identifierFromMatch c)
93+ score <- flexScore p (identifierFromIdeDeclaration (unwrapMatch c))
10194 return (c, score)
10295
10396-- FlexMatching ala Sublime.
@@ -106,11 +99,11 @@ flexRate p c = do
10699-- By string =~ pattern we'll get the start of the match and the length of
107100-- the matchas a (start, length) tuple if there's a match.
108101-- If match fails then it would be (-1,0)
109−flexScore :: Text -> DeclIdent -> Maybe Double
102+flexScore :: Text -> Text -> Maybe Double
110103flexScore pat str =
111104 case T.uncons pat of
112105 Nothing -> Nothing
113− Just (first, p) ->
106+ Just (first', p) ->
114107 case TE.encodeUtf8 str =~ TE.encodeUtf8 pat' :: (Int, Int) of
115108 (-1,0) -> Nothing
116109 (start,len) -> Just $ calcScore start (start + len)
@@ -121,11 +114,11 @@ flexScore pat str =
121114 -- escape prepends a backslash to "regexy" characters to prevent the
122115 -- matcher from crashing when trying to build the regex
123116 escape :: Char -> Text
124− escape c = if c `elem` ("[\\^$.|?*+(){}" :: String)
117+ escape c = if c `elem` T.unpack "[\\^$.|?*+(){}"
125118 then T.pack ['\\', c]
126119 else T.singleton c
127120 -- This just interleaves the search pattern with .*
128121 -- abcd[*] -> a.*b.*c.*d.*[*]
129− pat' = escape first <> foldMap (<> ".*") escapedPattern
122+ pat' = escape first' <> foldMap (<> ".*") escapedPattern
130123 calcScore start end =
131124 100.0 / fromIntegral ((1 + start) * (end - start + 1))
src/Language/PureScript/Ide/Pursuit.hs+10−14
@@ -13,22 +13,18 @@
1313-----------------------------------------------------------------------------
1414
1515{-# LANGUAGE OverloadedStrings #-}
16−{-# LANGUAGE ScopedTypeVariables #-}
1716
18−module Language.PureScript.Ide.Pursuit where
17+module Language.PureScript.Ide.Pursuit
18+ ( searchPursuitForDeclarations
19+ , findPackagesForModuleIdent
20+ ) where
1921
20−import Prelude ()
21−import Prelude.Compat
22+import Protolude hiding (fromStrict)
2223
2324import qualified Control.Exception as E
2425import Data.Aeson
25−import Data.ByteString (ByteString)
2626import Data.ByteString.Lazy (fromStrict)
27−import Data.Foldable (toList)
28−import Data.Maybe (mapMaybe)
29−import Data.Monoid ((<>))
3027import Data.String
31−import Data.Text (Text)
3228import qualified Data.Text as T
3329import Language.PureScript.Ide.Types
3430import Network.HTTP.Types.Header (hAccept)
@@ -40,14 +36,14 @@ import qualified Pipes.Prelude as P
4036queryPursuit :: Text -> IO ByteString
4137queryPursuit q = do
4238 let qClean = T.dropWhileEnd (== '.') q
43− req' <- parseUrl "http://pursuit.purescript.org/search"
39+ req' <- parseRequest "http://pursuit.purescript.org/search"
4440 let req = req'
45− { queryString=("q=" <> (fromString . T.unpack) qClean)
41+ { queryString= "q=" <> (fromString . T.unpack) qClean
4642 , requestHeaders=[(hAccept, "application/json")]
4743 }
4844 m <- newManager tlsManagerSettings
4945 withHTTP req m $ \resp ->
50− P.fold (<>) "" id $ responseBody resp
46+ P.fold (<>) "" identity (responseBody resp)
5147
5248
5349handler :: HttpException -> IO [a]
@@ -60,7 +56,7 @@ searchPursuitForDeclarations query =
6056 let results' = decode (fromStrict r) :: Maybe Array
6157 case results' of
6258 Nothing -> pure []
63− Just results -> pure (mapMaybe isDeclarationResponse (map fromJSON (toList results)))) `E.catch`
59+ Just results -> pure (mapMaybe (isDeclarationResponse . fromJSON) (toList results))) `E.catch`
6460 handler
6561 where
6662 isDeclarationResponse (Success a@DeclarationResponse{}) = Just a
@@ -72,7 +68,7 @@ findPackagesForModuleIdent query =
7268 let results' = decode (fromStrict r) :: Maybe Array
7369 case results' of
7470 Nothing -> pure []
75− Just results -> pure (mapMaybe isModuleResponse (map fromJSON (toList results)))) `E.catch`
71+ Just results -> pure (mapMaybe (isModuleResponse . fromJSON) (toList results))) `E.catch`
7672 handler
7773 where
7874 isModuleResponse (Success a@ModuleResponse{}) = Just a
src/Language/PureScript/Ide/Rebuild.hs+124−45
@@ -1,85 +1,164 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
41{-# LANGUAGE OverloadedStrings #-}
52{-# LANGUAGE PackageImports #-}
63{-# LANGUAGE RecordWildCards #-}
4+{-# LANGUAGE TemplateHaskell #-}
75{-# LANGUAGE TupleSections #-}
86
9−module Language.PureScript.Ide.Rebuild where
7+module Language.PureScript.Ide.Rebuild
8+ ( rebuildFile
9+ ) where
1010
11−import Language.PureScript.Ide.Error
12−import Language.PureScript.Ide.State
13−import Language.PureScript.Ide.Types
11+import Protolude
1412
15−import Control.Monad.Error.Class
16−import Control.Monad.IO.Class
1713import "monad-logger" Control.Monad.Logger
18−import Control.Monad.Reader.Class
19−import Control.Monad.Trans.Except
14+import qualified Data.List as List
2015import qualified Data.Map.Lazy as M
21−import Data.Maybe (fromJust, mapMaybe)
16+import Data.Maybe (fromJust)
2217import qualified Data.Set as S
2318import qualified Language.PureScript as P
2419import Language.PureScript.Errors.JSON
25−import qualified Language.PureScript.Externs as P
26−import System.FilePath (replaceExtension)
27−import System.Directory (doesFileExist)
28−import System.IO.UTF8 (readUTF8File)
20+import Language.PureScript.Ide.Error
21+import Language.PureScript.Ide.State
22+import Language.PureScript.Ide.Types
23+import Language.PureScript.Ide.Util
24+import System.IO.UTF8 (readUTF8File)
2925
26+-- | Given a filepath performs the following steps:
27+--
28+-- * Reads and parses a PureScript module from the filepath.
29+--
30+-- * Builds a dependency graph for the parsed module from the already loaded
31+-- ExternsFiles.
32+--
33+-- * Attempts to find an FFI definition file for the module by looking
34+-- for a file with the same filepath except for a .js extension.
35+--
36+-- * Passes all the created artifacts to @rebuildModule@.
37+--
38+-- * If the rebuilding succeeds, returns a @RebuildSuccess@ with the generated
39+-- warnings, and if rebuilding fails, returns a @RebuildError@ with the
40+-- generated errors.
3041rebuildFile
31− :: (PscIde m, MonadLogger m, MonadError PscIdeError m)
42+ :: (Ide m, MonadLogger m, MonadError PscIdeError m)
3243 => FilePath
3344 -> m Success
3445rebuildFile path = do
3546
36− input <- liftIO $ readUTF8File path
47+ input <- liftIO (readUTF8File path)
3748
38− m <- case map snd <$> P.parseModulesFromFiles id [(path, input)] of
39− Left parseError ->
40− throwError . RebuildError . toJSONErrors False P.Error $ parseError
41− Right [m] -> pure m
42− Right _ -> throwError . GeneralError $ "Please define exactly one module."
49+ m <- case snd <$> P.parseModuleFromFile identity (path, input) of
50+ Left parseError -> throwError
51+ . RebuildError
52+ . toJSONErrors False P.Error
53+ $ P.MultipleErrors [P.toPositionedError parseError]
54+ Right m -> pure m
4355
44− externs <- sortExterns m . M.delete (P.getModuleName m) =<< getExternFiles
56+ -- Externs files must be sorted ahead of time, so that they get applied
57+ -- correctly to the 'Environment'.
58+ externs <- sortExterns m =<< getExternFiles
4559
46− outputDirectory <- confOutputPath . envConfiguration <$> ask
60+ outputDirectory <- confOutputPath . ideConfiguration <$> ask
4761
48− let foreignModule = replaceExtension path "js"
49− foreignExists <- liftIO (doesFileExist foreignModule)
62+ -- For rebuilding, we want to 'RebuildAlways', but for inferring foreign
63+ -- modules using their file paths, we need to specify the path in the 'Map'.
64+ let filePathMap = M.singleton (P.getModuleName m) (Left P.RebuildAlways)
65+ foreigns <- P.inferForeignModules (M.singleton (P.getModuleName m) (Right path))
5066
51− let ma = P.buildMakeActions outputDirectory
52− (M.singleton (P.getModuleName m) (Left P.RebuildAlways))
53− (if foreignExists
54− then M.singleton (P.getModuleName m) foreignModule
55− else M.empty)
56− False
67+ let makeEnv = MakeActionsEnv outputDirectory filePathMap foreigns False
68+ -- Rebuild the single module using the cached externs
5769 (result, warnings) <- liftIO
58− . P.runMake P.defaultOptions
59− . P.rebuildModule (ma { P.progress = const (pure ()) }) externs
60− $ P.addDefaultImport (P.ModuleName [P.ProperName "Prim"]) m
70+ . P.runMake P.defaultOptions
71+ . P.rebuildModule (buildMakeActions
72+ >>= shushProgress $ makeEnv) externs $ m
6173 case result of
62− Left errors -> throwError . RebuildError $ toJSONErrors False P.Error errors
63− Right _ -> pure . RebuildSuccess $ toJSONErrors False P.Warning warnings
74+ Left errors -> throwError (RebuildError (toJSONErrors False P.Error errors))
75+ Right _ -> do
76+ rebuildModuleOpen makeEnv externs m
77+ pure (RebuildSuccess (toJSONErrors False P.Warning warnings))
6478
79+-- | Rebuilds a module but opens up its export list first and stores the result
80+-- inside the rebuild cache
81+rebuildModuleOpen
82+ :: (Ide m, MonadLogger m, MonadError PscIdeError m)
83+ => MakeActionsEnv
84+ -> [P.ExternsFile]
85+ -> P.Module
86+ -> m ()
87+rebuildModuleOpen makeEnv externs m = do
88+ (openResult, _) <- liftIO
89+ . P.runMake P.defaultOptions
90+ . P.rebuildModule (buildMakeActions
91+ >>= shushProgress
92+ >>= shushCodegen
93+ $ makeEnv) externs $ openModuleExports m
94+ case openResult of
95+ Left _ ->
96+ throwError (GeneralError "Failed when rebuilding with open exports")
97+ Right result -> do
98+ $(logDebug)
99+ ("Setting Rebuild cache: " <> runModuleNameT (P.efModuleName result))
100+ cacheRebuild result
101+
102+-- | Parameters we can access while building our @MakeActions@
103+data MakeActionsEnv =
104+ MakeActionsEnv
105+ { maeOutputDirectory :: FilePath
106+ , maeFilePathMap :: Map P.ModuleName (Either P.RebuildPolicy FilePath)
107+ , maeForeignPathMap :: Map P.ModuleName FilePath
108+ , maePrefixComment :: Bool
109+ }
110+
111+-- | Builds the default @MakeActions@ from a @MakeActionsEnv@
112+buildMakeActions :: MakeActionsEnv -> P.MakeActions P.Make
113+buildMakeActions MakeActionsEnv{..} =
114+ P.buildMakeActions
115+ maeOutputDirectory
116+ maeFilePathMap
117+ maeForeignPathMap
118+ maePrefixComment
119+
120+-- | Shuts the compiler up about progress messages
121+shushProgress :: P.MakeActions P.Make -> MakeActionsEnv -> P.MakeActions P.Make
122+shushProgress ma _ =
123+ ma { P.progress = \_ -> pure () }
124+
125+-- | Stops any kind of codegen (also silences errors about missing or unused FFI
126+-- files though)
127+shushCodegen :: P.MakeActions P.Make -> MakeActionsEnv -> P.MakeActions P.Make
128+shushCodegen ma MakeActionsEnv{..} =
129+ ma { P.codegen = \_ _ _ -> pure () }
130+
131+-- | Returns a topologically sorted list of dependent ExternsFiles for the given
132+-- module. Throws an error if there is a cyclic dependency within the
133+-- ExternsFiles
65134sortExterns
66− :: (PscIde m, MonadError PscIdeError m)
135+ :: (Ide m, MonadError PscIdeError m)
67136 => P.Module
68− -> M.Map P.ModuleName P.ExternsFile
137+ -> Map P.ModuleName P.ExternsFile
69138 -> m [P.ExternsFile]
70139sortExterns m ex = do
71− sorted' <- runExceptT . P.sortModules . (:) m . map mkShallowModule . M.elems $ ex
140+ sorted' <- runExceptT
141+ . P.sortModules
142+ . (:) m
143+ . map mkShallowModule
144+ . M.elems
145+ . M.delete (P.getModuleName m) $ ex
72146 case sorted' of
73− Left _ -> throwError (GeneralError "There was a cycle in the dependencies")
147+ Left err ->
148+ throwError (RebuildError (toJSONErrors False P.Error err))
74149 Right (sorted, graph) -> do
75− let deps = fromJust (lookup (P.getModuleName m) graph)
150+ let deps = fromJust (List.lookup (P.getModuleName m) graph)
76151 pure $ mapMaybe getExtern (deps `inOrderOf` map P.getModuleName sorted)
77152 where
78153 mkShallowModule P.ExternsFile{..} =
79− P.Module undefined [] efModuleName (map mkImport efImports) Nothing
154+ P.Module (P.internalModuleSourceSpan "<rebuild>") [] efModuleName (map mkImport efImports) Nothing
80155 mkImport (P.ExternsImport mn it iq) =
81− P.ImportDeclaration mn it iq False
156+ P.ImportDeclaration mn it iq
82157 getExtern mn = M.lookup mn ex
83158 -- Sort a list so its elements appear in the same order as in another list.
84159 inOrderOf :: (Ord a) => [a] -> [a] -> [a]
85160 inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
161+
162+-- | Removes a modules export list.
163+openModuleExports :: P.Module -> P.Module
164+openModuleExports (P.Module ss cs mn decls _) = P.Module ss cs mn decls Nothing
src/Language/PureScript/Ide/Reexports.hs+93−66
@@ -14,78 +14,105 @@
1414-----------------------------------------------------------------------------
1515
1616{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE PatternGuards #-}
18−{-# LANGUAGE TupleSections #-}
17+{-# LANGUAGE PackageImports #-}
18+{-# LANGUAGE TemplateHaskell #-}
19+{-# LANGUAGE RecordWildCards #-}
1920
20−module Language.PureScript.Ide.Reexports where
21+module Language.PureScript.Ide.Reexports
22+ ( resolveReexports
23+ , prettyPrintReexportResult
24+ , reexportHasFailures
25+ , ReexportResult(..)
26+ ) where
2127
28+import Protolude
2229
23−import Prelude ()
24−import Prelude.Compat
25−
26−import Data.List (union)
27−import Data.Map (Map)
2830import qualified Data.Map as Map
29−import Data.Maybe
3031import Language.PureScript.Ide.Types
31−
32−getReexports :: Module -> [ExternDecl]
33−getReexports (mn, decls)= concatMap getExport decls
34− where getExport d
35− | (Export mn') <- d
36− , mn /= mn' = replaceExportWithAliases decls mn'
37− | otherwise = []
38−
39−dependencyToExport :: ExternDecl -> ExternDecl
40−dependencyToExport (Dependency m _ _) = Export m
41−dependencyToExport decl = decl
42−
43−replaceExportWithAliases :: [ExternDecl] -> ModuleIdent -> [ExternDecl]
44−replaceExportWithAliases decls ident =
45− case filter isMatch decls of
46− [] -> [Export ident]
47− aliases -> map dependencyToExport aliases
48− where isMatch d
49− | Dependency _ _ (Just alias) <- d
50− , alias == ident = True
51− | otherwise = False
52−
53−replaceReexport :: ExternDecl -> Module -> Module -> Module
54−replaceReexport e@(Export _) (m, decls) (_, newDecls) =
55− (m, filter (/= e) decls `union` newDecls)
56−replaceReexport _ _ _ = error "Should only get Exports here."
57−
58−emptyModule :: Module
59−emptyModule = ("Empty", [])
60−
61−isExport :: ExternDecl -> Bool
62−isExport (Export _) = True
63−isExport _ = False
64−
65−removeExportDecls :: Module -> Module
66−removeExportDecls = fmap (filter (not . isExport))
67−
68−replaceReexports :: Module -> Map ModuleIdent [ExternDecl] -> Module
69−replaceReexports m db = result
32+import Language.PureScript.Ide.Util
33+import qualified Language.PureScript as P
34+
35+-- | Contains the module with resolved reexports, and eventual failures
36+data ReexportResult a
37+ = ReexportResult
38+ { reResolved :: a
39+ , reFailed :: [(P.ModuleName, P.DeclarationRef)]
40+ } deriving (Show, Eq, Functor)
41+
42+-- | Uses the passed formatter to format the resolved module, and adds eventual
43+-- failures
44+prettyPrintReexportResult
45+ :: (a -> Text)
46+ -- ^ Formatter for the resolved result
47+ -> ReexportResult a
48+ -- ^ The Result to be pretty printed
49+ -> Text
50+prettyPrintReexportResult f ReexportResult{..}
51+ | null reFailed =
52+ "Successfully resolved reexports for " <> f reResolved
53+ | otherwise =
54+ "Failed to resolve reexports for "
55+ <> f reResolved
56+ <> foldMap (\(mn, ref) -> runModuleNameT mn <> show ref) reFailed
57+
58+-- | Whether any Refs couldn't be resolved
59+reexportHasFailures :: ReexportResult a -> Bool
60+reexportHasFailures = not . null . reFailed
61+
62+-- | Resolves Reexports for a given Module, by looking up the reexported values
63+-- from the passed in Map
64+resolveReexports
65+ :: Map P.ModuleName [IdeDeclarationAnn]
66+ -- ^ Modules to search for the reexported declarations
67+ -> (Module, [(P.ModuleName, P.DeclarationRef)])
68+ -- ^ The module to resolve reexports for, aswell as the references to resolve
69+ -> ReexportResult Module
70+resolveReexports modules ((moduleName, decls), refs) =
71+ ReexportResult (moduleName, decls <> concat resolvedRefs) failedRefs
7072 where
71− reexports = getReexports m
72− result = foldl go (removeExportDecls m) reexports
73+ (failedRefs, resolvedRefs) = partitionEithers (resolveRef' <$> refs)
74+ resolveRef' x@(mn, r) = case Map.lookup mn modules of
75+ Nothing -> Left x
76+ Just decls' -> first (mn,) (resolveRef decls' r)
77+
78+resolveRef
79+ :: [IdeDeclarationAnn]
80+ -> P.DeclarationRef
81+ -> Either P.DeclarationRef [IdeDeclarationAnn]
82+resolveRef decls ref = case ref of
83+ P.TypeRef tn mdtors ->
84+ case findRef (\case IdeType name _ -> name == tn; _ -> False) of
85+ Nothing -> Left ref
86+ Just d -> Right $ d : case mdtors of
87+ Nothing ->
88+ -- If the dataconstructor field inside the TypeRef is Nothing, that
89+ -- means that all data constructors are exported, so we need to look
90+ -- those up ourselfes
91+ findDtors tn
92+ Just dtors -> mapMaybe lookupDtor dtors
93+ P.ValueRef i ->
94+ findWrapped (\case IdeValue i' _ -> i' == i; _ -> False)
95+ P.TypeOpRef name ->
96+ findWrapped (\case IdeTypeOperator n _ _ _ -> n == name; _ -> False)
97+ P.ValueOpRef name ->
98+ findWrapped (\case IdeValueOperator n _ _ _ -> n == name; _ -> False)
99+ P.TypeClassRef name ->
100+ findWrapped (\case IdeTypeClass n -> n == name; _ -> False)
101+ _ ->
102+ Left ref
103+ where
104+ findWrapped = wrapSingle . findRef
105+ wrapSingle = maybe (Left ref) (Right . pure)
106+ findRef f = find (f . discardAnn) decls
73107
74− go :: Module -> ExternDecl -> Module
75− go m' re@(Export name) = replaceReexport re m' (getModule name)
76− go _ _ = error "partiality! woohoo"
108+ lookupDtor name =
109+ findRef (\case IdeDataConstructor name' _ _ -> name == name'
110+ _ -> False)
77111
78− getModule :: ModuleIdent -> Module
79− getModule name = clean res
112+ findDtors tn = filter (f . discardAnn) decls
80113 where
81− res = fromMaybe emptyModule $ (name , ) <$> Map.lookup name db
82− -- we have to do this because keeping self exports in will result in
83− -- infinite loops
84− clean (mn, decls) = (mn,) (filter (/= Export mn) decls)
85−
86−resolveReexports :: Map ModuleIdent [ExternDecl] -> Module -> Module
87−resolveReexports modules m =
88− let replaced = replaceReexports m modules
89− in if null (getReexports replaced)
90− then replaced
91− else resolveReexports modules replaced
114+ f :: IdeDeclaration -> Bool
115+ f decl
116+ | (IdeDataConstructor _ tn' _) <- decl
117+ , tn == tn' = True
118+ | otherwise = False
src/Language/PureScript/Ide/SourceFile.hs+72−90
@@ -12,111 +12,93 @@
1212-- Getting declarations from PureScript sourcefiles
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
1715{-# LANGUAGE OverloadedStrings #-}
1816
19−module Language.PureScript.Ide.SourceFile where
17+module Language.PureScript.Ide.SourceFile
18+ ( parseModule
19+ , getImportsForFile
20+ , extractSpans
21+ ) where
2022
21−import Prelude
23+import Protolude
2224
23−import Control.Monad.Error.Class
24−import Control.Monad.IO.Class
25−import Control.Monad.Trans.Except
26−import Data.Maybe (mapMaybe)
27−import Data.Monoid
28−import qualified Data.Text as T
29−import qualified Language.PureScript.AST.Declarations as D
30−import qualified Language.PureScript.AST.SourcePos as SP
25+import qualified Language.PureScript as P
3126import Language.PureScript.Ide.Error
32−import Language.PureScript.Ide.Externs (unwrapPositioned,
33− unwrapPositionedRef)
27+import Language.PureScript.Ide.Util
3428import Language.PureScript.Ide.Types
35−import qualified Language.PureScript.Names as N
36−import qualified Language.PureScript.Parser as P
37−import System.Directory
3829import System.IO.UTF8 (readUTF8File)
3930
40−parseModuleFromFile :: (MonadIO m, MonadError PscIdeError m) =>
41− FilePath -> m D.Module
42−parseModuleFromFile fp = do
43− exists <- liftIO (doesFileExist fp)
44− if exists
45− then do
46− content <- liftIO (readUTF8File fp)
47− let m = do tokens <- P.lex fp content
48− P.runTokenParser "" P.parseModule tokens
49− either (throwError . (`ParseError` "File could not be parsed.")) pure m
50− else throwError (NotFound "File does not exist.")
31+parseModule
32+ :: (MonadIO m)
33+ => FilePath
34+ -> m (Either FilePath (FilePath, P.Module) )
35+parseModule path = do
36+ contents <- liftIO (readUTF8File path)
37+ case P.parseModuleFromFile identity (path, contents) of
38+ Left _ -> pure (Left path)
39+ Right m -> pure (Right m)
5140
52−-- data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef])
53−
54−getDeclarations :: D.Module -> [D.Declaration]
55−getDeclarations (D.Module _ _ _ declarations _) = declarations
56−
57−getImports :: D.Module -> [D.Declaration]
58−getImports (D.Module _ _ _ declarations _) =
41+getImports :: P.Module -> [(P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)]
42+getImports (P.Module _ _ _ declarations _) =
5943 mapMaybe isImport declarations
6044 where
61− isImport (D.PositionedDeclaration _ _ (i@D.ImportDeclaration{})) = Just i
45+ isImport (P.PositionedDeclaration _ _ (P.ImportDeclaration a b c)) = Just (a, b, c)
6246 isImport _ = Nothing
6347
6448getImportsForFile :: (MonadIO m, MonadError PscIdeError m) =>
6549 FilePath -> m [ModuleImport]
6650getImportsForFile fp = do
67− module' <- parseModuleFromFile fp
68− let imports = getImports module'
69− pure (mkModuleImport . unwrapPositionedImport <$> imports)
70− where
71− mkModuleImport (D.ImportDeclaration mn importType' qualifier _) =
72− ModuleImport
73− (T.pack (N.runModuleName mn))
74− importType'
75− (T.pack . N.runModuleName <$> qualifier)
76− mkModuleImport _ = error "Shouldn't have gotten anything but Imports here"
77− unwrapPositionedImport (D.ImportDeclaration mn importType' qualifier b) =
78− D.ImportDeclaration mn (unwrapImportType importType') qualifier b
79− unwrapPositionedImport x = x
80− unwrapImportType (D.Explicit decls) = D.Explicit (map unwrapPositionedRef decls)
81− unwrapImportType (D.Hiding decls) = D.Hiding (map unwrapPositionedRef decls)
82− unwrapImportType D.Implicit = D.Implicit
83−
84−getPositionedImports :: D.Module -> [D.Declaration]
85−getPositionedImports (D.Module _ _ _ declarations _) =
86− mapMaybe isImport declarations
87− where
88− isImport i@(D.PositionedDeclaration _ _ D.ImportDeclaration{}) = Just i
89− isImport _ = Nothing
51+ moduleE <- parseModule fp
52+ case moduleE of
53+ Left _ -> throwError (GeneralError "Failed to parse sourcefile.")
54+ Right (_, module') ->
55+ pure (mkModuleImport . unwrapPositionedImport <$> getImports module')
56+ where
57+ mkModuleImport (mn, importType', qualifier) =
58+ ModuleImport
59+ (runModuleNameT mn)
60+ importType'
61+ (runModuleNameT <$> qualifier)
62+ unwrapPositionedImport (mn, it, q) = (mn, unwrapImportType it, q)
63+ unwrapImportType (P.Explicit decls) = P.Explicit (map unwrapPositionedRef decls)
64+ unwrapImportType (P.Hiding decls) = P.Hiding (map unwrapPositionedRef decls)
65+ unwrapImportType P.Implicit = P.Implicit
9066
91−getDeclPosition :: D.Module -> String -> Maybe SP.SourceSpan
92−getDeclPosition m ident = getFirst (foldMap (match ident) decls)
67+-- | Given a surrounding Sourcespan and a Declaration from the PS AST, extracts
68+-- definition sites inside that Declaration.
69+extractSpans
70+ :: P.SourceSpan
71+ -- ^ The surrounding span
72+ -> P.Declaration
73+ -- ^ The declaration to extract spans from
74+ -> [(Either Text Text, P.SourceSpan)]
75+ -- ^ A @Right@ corresponds to a type level declaration, and a @Left@ to a
76+ -- value level one
77+extractSpans ss d = case d of
78+ P.PositionedDeclaration ss' _ d' ->
79+ extractSpans ss' d'
80+ P.ValueDeclaration i _ _ _ ->
81+ [(Left (runIdentT i), ss)]
82+ P.TypeSynonymDeclaration name _ _ ->
83+ [(Right (runProperNameT name), ss)]
84+ P.TypeClassDeclaration name _ _ members ->
85+ (Right (runProperNameT name), ss) : concatMap (extractSpans' ss) members
86+ P.DataDeclaration _ name _ ctors ->
87+ (Right (runProperNameT name), ss)
88+ : map (\(cname, _) -> (Left (runProperNameT cname), ss)) ctors
89+ P.ExternDeclaration ident _ ->
90+ [(Left (runIdentT ident), ss)]
91+ P.ExternDataDeclaration name _ ->
92+ [(Right (runProperNameT name), ss)]
93+ _ -> []
9394 where
94− decls = getDeclarations m
95− match q (D.PositionedDeclaration ss _ decl) = First (if go q decl
96− then Just ss
97− else Nothing)
98− match _ _ = First Nothing
99−
100− go q (D.DataDeclaration _ name _ constructors) =
101− properEqual name q || any (\(x,_) -> properEqual x q) constructors
102− go q (D.DataBindingGroupDeclaration decls') = any (go q) decls'
103− go q (D.TypeSynonymDeclaration name _ _) = properEqual name q
104− go q (D.TypeDeclaration ident' _) = identEqual ident' q
105− go q (D.ValueDeclaration ident' _ _ _) = identEqual ident' q
106− go q (D.ExternDeclaration ident' _) = identEqual ident' q
107− go q (D.ExternDataDeclaration name _) = properEqual name q
108− go q (D.TypeClassDeclaration name _ _ members) =
109− properEqual name q || any (go q . unwrapPositioned) members
110− go q (D.TypeInstanceDeclaration ident' _ _ _ _) =
111− identEqual ident' q
112− go _ _ = False
113−
114− properEqual x q = N.runProperName x == q
115− identEqual x q = N.runIdent x == q
116−
117−goToDefinition :: String -> FilePath -> IO (Maybe SP.SourceSpan)
118−goToDefinition q fp = do
119− m <- runExceptT (parseModuleFromFile fp)
120− case m of
121− Right module' -> pure (getDeclPosition module' q)
122− Left _ -> pure Nothing
95+ -- We need this special case to be able to also get the position info for
96+ -- typeclass member functions. Typedeclaratations would clash with value
97+ -- declarations for non-typeclass members, which is why we can't handle them
98+ -- in extractSpans.
99+ extractSpans' ssP dP = case dP of
100+ P.PositionedDeclaration ssP' _ dP' ->
101+ extractSpans' ssP' dP'
102+ P.TypeDeclaration ident _ ->
103+ [(Left (runIdentT ident), ssP)]
104+ _ -> []
src/Language/PureScript/Ide/State.hs+186−71
@@ -12,87 +12,202 @@
1212-- Functions to access psc-ide's state
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE MultiParamTypeClasses #-}
1815{-# LANGUAGE OverloadedStrings #-}
1916{-# LANGUAGE PackageImports #-}
2017{-# LANGUAGE TemplateHaskell #-}
21−{-# LANGUAGE TupleSections #-}
2218
23−module Language.PureScript.Ide.State where
19+module Language.PureScript.Ide.State
20+ ( getLoadedModulenames
21+ , getExternFiles
22+ , resetIdeState
23+ , cacheRebuild
24+ , insertExterns
25+ , insertModule
26+ , insertExternsSTM
27+ , getAllModules
28+ , populateStage2
29+ , populateStage3
30+ , populateStage3STM
31+ ) where
2432
25−import Prelude ()
26−import Prelude.Compat
33+import Protolude
34+import qualified Prelude
2735
2836import Control.Concurrent.STM
29−import Control.Monad.IO.Class
3037import "monad-logger" Control.Monad.Logger
31−import Control.Monad.Reader.Class
3238import qualified Data.Map.Lazy as M
33−import Data.Maybe (catMaybes)
34−import Data.Monoid
35−import qualified Data.Text as T
3639import Language.PureScript.Externs
3740import Language.PureScript.Ide.Externs
3841import Language.PureScript.Ide.Reexports
42+import Language.PureScript.Ide.SourceFile
3943import Language.PureScript.Ide.Types
40−import Language.PureScript.Names
41−
42−getPscIdeState :: (PscIde m) =>
43− m (M.Map ModuleIdent [ExternDecl])
44−getPscIdeState = do
45− stateVar <- envStateVar <$> ask
46− liftIO $ pscStateModules <$> readTVarIO stateVar
47−
48−getExternFiles :: (PscIde m) =>
49− m (M.Map ModuleName ExternsFile)
50−getExternFiles = do
51− stateVar <- envStateVar <$> ask
52− liftIO (externsFiles <$> readTVarIO stateVar)
53−
54−getExternFile :: (PscIde m) =>
55− ModuleName -> m (Maybe ExternsFile)
56−getExternFile mn = M.lookup mn <$> getExternFiles
57−
58−getAllDecls :: (PscIde m) => m [ExternDecl]
59−getAllDecls = concat <$> getPscIdeState
60−
61−getAllModules :: (PscIde m) => m [Module]
62−getAllModules = M.toList <$> getPscIdeState
63−
64−getAllModulesWithReexports :: (PscIde m, MonadLogger m) =>
65− m [Module]
66−getAllModulesWithReexports = do
67− mis <- M.keys <$> getPscIdeState
68− ms <- traverse getModuleWithReexports mis
69− pure (catMaybes ms)
70−
71−getModule :: (PscIde m, MonadLogger m) =>
72− ModuleIdent -> m (Maybe Module)
73−getModule m = do
74− modules <- getPscIdeState
75− pure ((m,) <$> M.lookup m modules)
76−
77−getModuleWithReexports :: (PscIde m, MonadLogger m) =>
78− ModuleIdent -> m (Maybe Module)
79−getModuleWithReexports mi = do
80− m <- getModule mi
81− modules <- getPscIdeState
82− pure $ resolveReexports modules <$> m
83−
84−insertModule ::(PscIde m, MonadLogger m) =>
85− ExternsFile -> m ()
86−insertModule externsFile = do
87− env <- ask
88− let moduleName = efModuleName externsFile
89− $(logDebug) $ "Inserting Module: " <> T.pack (runModuleName moduleName)
90− liftIO . atomically $ insertModule' (envStateVar env) externsFile
91−
92−insertModule' :: TVar PscIdeState -> ExternsFile -> STM ()
93−insertModule' st ef =
94− modifyTVar st $ \x ->
95− x { externsFiles = M.insert (efModuleName ef) ef (externsFiles x)
96− , pscStateModules = let (mn, decls) = convertExterns ef
97− in M.insert mn decls (pscStateModules x)
98− }
44+import Language.PureScript.Ide.Util
45+import qualified Language.PureScript as P
46+import System.Clock
47+
48+-- | Resets all State inside psc-ide
49+resetIdeState :: Ide m => m ()
50+resetIdeState = do
51+ ideVar <- ideStateVar <$> ask
52+ liftIO . atomically $ do
53+ writeTVar ideVar emptyIdeState
54+ setStage3STM ideVar emptyStage3
55+
56+-- | Gets the loaded Modulenames
57+getLoadedModulenames :: Ide m => m [P.ModuleName]
58+getLoadedModulenames = M.keys <$> getExternFiles
59+
60+-- | Gets all loaded ExternFiles
61+getExternFiles :: Ide m => m (M.Map P.ModuleName ExternsFile)
62+getExternFiles = s1Externs <$> getStage1
63+
64+-- | Insert a Module into Stage1 of the State
65+insertModule :: Ide m => (FilePath, P.Module) -> m ()
66+insertModule module' = do
67+ stateVar <- ideStateVar <$> ask
68+ liftIO . atomically $ insertModuleSTM stateVar module'
69+
70+-- | STM version of insertModule
71+insertModuleSTM :: TVar IdeState -> (FilePath, P.Module) -> STM ()
72+insertModuleSTM ref (fp, module') =
73+ modifyTVar ref $ \x ->
74+ x { ideStage1 = (ideStage1 x) {
75+ s1Modules = M.insert
76+ (P.getModuleName module')
77+ (module', fp)
78+ (s1Modules (ideStage1 x))}}
79+
80+-- | Retrieves Stage1 from the State.
81+-- This includes loaded Externfiles
82+getStage1 :: Ide m => m Stage1
83+getStage1 = do
84+ st <- ideStateVar <$> ask
85+ fmap ideStage1 . liftIO . readTVarIO $ st
86+
87+-- | STM version of getStage1
88+getStage1STM :: TVar IdeState -> STM Stage1
89+getStage1STM ref = ideStage1 <$> readTVar ref
90+
91+-- | Retrieves Stage2 from the State.
92+getStage2 :: Ide m => m Stage2
93+getStage2 = do
94+ st <- ideStateVar <$> ask
95+ liftIO (atomically (getStage2STM st))
96+
97+getStage2STM :: TVar IdeState -> STM Stage2
98+getStage2STM ref = ideStage2 <$> readTVar ref
99+
100+-- | STM version of setStage2
101+setStage2STM :: TVar IdeState -> Stage2 -> STM ()
102+setStage2STM ref s2 = do
103+ modifyTVar ref $ \x ->
104+ x {ideStage2 = s2}
105+ pure ()
106+
107+-- | Retrieves Stage3 from the State.
108+-- This includes the denormalized Declarations and cached rebuilds
109+getStage3 :: Ide m => m Stage3
110+getStage3 = do
111+ st <- ideStateVar <$> ask
112+ fmap ideStage3 . liftIO . readTVarIO $ st
113+
114+-- | Sets Stage3 inside the compiler
115+setStage3STM :: TVar IdeState -> Stage3 -> STM ()
116+setStage3STM ref s3 = do
117+ modifyTVar ref $ \x ->
118+ x {ideStage3 = s3}
119+ pure ()
120+
121+-- | Checks if the given ModuleName matches the last rebuild cache and if it
122+-- does returns all loaded definitions + the definitions inside the rebuild
123+-- cache
124+getAllModules :: Ide m => Maybe P.ModuleName -> m [Module]
125+getAllModules mmoduleName = do
126+ declarations <- s3Declarations <$> getStage3
127+ rebuild <- cachedRebuild
128+ case mmoduleName of
129+ Nothing -> pure (M.toList declarations)
130+ Just moduleName ->
131+ case rebuild of
132+ Just (cachedModulename, ef)
133+ | cachedModulename == moduleName -> do
134+ (AstData asts) <- s2AstData <$> getStage2
135+ let ast = fromMaybe M.empty (M.lookup moduleName asts)
136+ pure . M.toList $
137+ M.insert moduleName
138+ (snd . annotateLocations ast . fst . convertExterns $ ef) declarations
139+ _ -> pure (M.toList declarations)
140+
141+-- | Adds an ExternsFile into psc-ide's State Stage1. This does not populate the
142+-- following Stages, which needs to be done after all the necessary Exterms have
143+-- been loaded.
144+insertExterns :: Ide m => ExternsFile -> m ()
145+insertExterns ef = do
146+ st <- ideStateVar <$> ask
147+ liftIO (atomically (insertExternsSTM st ef))
148+
149+-- | STM version of insertExterns
150+insertExternsSTM :: TVar IdeState -> ExternsFile -> STM ()
151+insertExternsSTM ref ef =
152+ modifyTVar ref $ \x ->
153+ x { ideStage1 = (ideStage1 x) {
154+ s1Externs = M.insert (efModuleName ef) ef (s1Externs (ideStage1 x))}}
155+
156+-- | Sets rebuild cache to the given ExternsFile
157+cacheRebuild :: Ide m => ExternsFile -> m ()
158+cacheRebuild ef = do
159+ st <- ideStateVar <$> ask
160+ liftIO . atomically . modifyTVar st $ \x ->
161+ x { ideStage3 = (ideStage3 x) {
162+ s3CachedRebuild = Just (efModuleName ef, ef)}}
163+
164+-- | Retrieves the rebuild cache
165+cachedRebuild :: Ide m => m (Maybe (P.ModuleName, ExternsFile))
166+cachedRebuild = s3CachedRebuild <$> getStage3
167+
168+-- | Extracts source spans from the parsed ASTs
169+populateStage2 :: (Ide m, MonadLogger m) => m ()
170+populateStage2 = do
171+ st <- ideStateVar <$> ask
172+ duration <- liftIO $ do
173+ start <- getTime Monotonic
174+ atomically (populateStage2STM st)
175+ end <- getTime Monotonic
176+ pure (Prelude.show (diffTimeSpec start end))
177+ $(logDebug) $ "Finished populating Stage2 in " <> toS duration
178+
179+-- | STM version of populateStage2
180+populateStage2STM :: TVar IdeState -> STM ()
181+populateStage2STM ref = do
182+ modules <- s1Modules <$> getStage1STM ref
183+ let spans = map (\((P.Module ss _ _ decls _), _) -> M.fromList (concatMap (extractSpans ss) decls)) modules
184+ setStage2STM ref (Stage2 (AstData spans))
185+
186+-- | Resolves reexports and populates Stage3 with data to be used in queries.
187+populateStage3 :: (Ide m, MonadLogger m) => m ()
188+populateStage3 = do
189+ st <- ideStateVar <$> ask
190+ (duration, results) <- liftIO $ do
191+ start <- getTime Monotonic
192+ results <- atomically (populateStage3STM st)
193+ end <- getTime Monotonic
194+ pure (Prelude.show (diffTimeSpec start end), results)
195+ traverse_
196+ (logWarnN . prettyPrintReexportResult (runModuleNameT . fst))
197+ (filter reexportHasFailures results)
198+ $(logDebug) $ "Finished populating Stage3 in " <> toS duration
199+
200+-- | STM version of populateStage3
201+populateStage3STM :: TVar IdeState -> STM [ReexportResult Module]
202+populateStage3STM ref = do
203+ externs <- s1Externs <$> getStage1STM ref
204+ (AstData asts) <- s2AstData <$> getStage2STM ref
205+ let modules = M.map convertExterns externs
206+ nModules :: Map P.ModuleName (Module, [(P.ModuleName, P.DeclarationRef)])
207+ nModules = M.mapWithKey
208+ (\moduleName (m, refs) ->
209+ (fromMaybe m $ annotateLocations <$> M.lookup moduleName asts <*> pure m, refs)) modules
210+ -- resolves reexports and discards load failures for now
211+ result = resolveReexports (M.map (snd . fst) nModules) <$> M.elems nModules
212+ setStage3STM ref (Stage3 (M.fromList (map reResolved result)) Nothing)
213+ pure result
src/Language/PureScript/Ide/Types.hs+98−76
@@ -12,102 +12,122 @@
1212-- Type definitions for psc-ide
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
18−{-# LANGUAGE OverloadedStrings #-}
19−{-# LANGUAGE ScopedTypeVariables #-}
15+{-# LANGUAGE OverloadedStrings #-}
16+{-# LANGUAGE DeriveFoldable #-}
2017
2118module Language.PureScript.Ide.Types where
2219
23−import Prelude ()
24−import Prelude.Compat
20+import Protolude
2521
2622import Control.Concurrent.STM
27−import Control.Monad
28−import Control.Monad.Reader.Class
29−import Control.Monad.Trans
3023import Data.Aeson
3124import Data.Map.Lazy as M
32−import Data.Maybe (maybeToList)
33−import Data.Text (Text (), pack, unpack)
34−import qualified Language.PureScript.AST.Declarations as D
35−import Language.PureScript.Externs
3625import qualified Language.PureScript.Errors.JSON as P
37−import qualified Language.PureScript.Names as N
3826import qualified Language.PureScript as P
39−
40−import Text.Parsec
27+import Language.PureScript.Ide.Conversions
28+import Text.Parsec as Parsec
4129import Text.Parsec.Text
4230
43−type Ident = Text
44−type DeclIdent = Text
4531type ModuleIdent = Text
4632
47−data ExternDecl
48− -- | A function/value declaration
49− = ValueDeclaration Ident P.Type
50− | TypeDeclaration (P.ProperName 'P.TypeName) P.Kind
51− | TypeSynonymDeclaration (P.ProperName 'P.TypeName) P.Type
52− -- | A Dependency onto another Module
53− | Dependency
54− ModuleIdent -- name of the dependency
55− [Text] -- explicit imports
56− (Maybe Text) -- An eventual qualifier
57− -- | A module declaration
58− | ModuleDecl
59− ModuleIdent -- The modules name
60− [DeclIdent] -- The exported identifiers
61− -- | A data/newtype declaration
62− | DataConstructor
63− DeclIdent -- The type name
64− (P.ProperName 'P.TypeName)
65− P.Type -- The "type"
66− -- | An exported module
67− | TypeClassDeclaration (P.ProperName 'P.ClassName)
68− | Export ModuleIdent -- The exported Modules name
69− deriving (Show,Eq,Ord)
70−
71−type Module = (ModuleIdent, [ExternDecl])
33+data IdeDeclaration
34+ = IdeValue P.Ident P.Type
35+ | IdeType (P.ProperName 'P.TypeName) P.Kind
36+ | IdeTypeSynonym (P.ProperName 'P.TypeName) P.Type
37+ | IdeDataConstructor (P.ProperName 'P.ConstructorName) (P.ProperName 'P.TypeName) P.Type
38+ | IdeTypeClass (P.ProperName 'P.ClassName)
39+ | IdeValueOperator (P.OpName 'P.ValueOpName) Text P.Precedence P.Associativity
40+ | IdeTypeOperator (P.OpName 'P.TypeOpName) Text P.Precedence P.Associativity
41+ deriving (Show, Eq, Ord)
42+
43+data IdeDeclarationAnn = IdeDeclarationAnn Annotation IdeDeclaration
44+ deriving (Show, Eq, Ord)
45+
46+data Annotation
47+ = Annotation
48+ { annLocation :: Maybe P.SourceSpan
49+ , annExportedFrom :: Maybe P.ModuleName
50+ } deriving (Show, Eq, Ord)
51+
52+emptyAnn :: Annotation
53+emptyAnn = Annotation Nothing Nothing
54+
55+type Module = (P.ModuleName, [IdeDeclarationAnn])
56+
57+newtype AstData a =
58+ AstData (Map P.ModuleName (Map (Either Text Text) a))
59+ deriving (Show, Eq, Ord, Functor, Foldable)
7260
7361data Configuration =
7462 Configuration
7563 { confOutputPath :: FilePath
7664 , confDebug :: Bool
65+ , confGlobs :: [FilePath]
7766 }
7867
79−data PscIdeEnvironment =
80− PscIdeEnvironment
81− { envStateVar :: TVar PscIdeState
82− , envConfiguration :: Configuration
68+data IdeEnvironment =
69+ IdeEnvironment
70+ { ideStateVar :: TVar IdeState
71+ , ideConfiguration :: Configuration
8372 }
8473
85−type PscIde m = (MonadIO m, MonadReader PscIdeEnvironment m)
74+type Ide m = (MonadIO m, MonadReader IdeEnvironment m)
75+
76+data IdeState = IdeState
77+ { ideStage1 :: Stage1
78+ , ideStage2 :: Stage2
79+ , ideStage3 :: Stage3
80+ }
8681
87−data PscIdeState =
88− PscIdeState
89− { pscStateModules :: M.Map Text [ExternDecl]
90− , externsFiles :: M.Map P.ModuleName ExternsFile
91− } deriving Show
82+emptyIdeState :: IdeState
83+emptyIdeState = IdeState emptyStage1 emptyStage2 emptyStage3
9284
93−emptyPscIdeState :: PscIdeState
94−emptyPscIdeState = PscIdeState M.empty M.empty
85+emptyStage1 :: Stage1
86+emptyStage1 = Stage1 M.empty M.empty
9587
96−data Match = Match ModuleIdent ExternDecl
97− deriving (Show, Eq)
88+emptyStage2 :: Stage2
89+emptyStage2 = Stage2 (AstData M.empty)
90+
91+emptyStage3 :: Stage3
92+emptyStage3 = Stage3 M.empty Nothing
93+
94+data Stage1 = Stage1
95+ { s1Externs :: M.Map P.ModuleName P.ExternsFile
96+ , s1Modules :: M.Map P.ModuleName (P.Module, FilePath)
97+ }
98+
99+data Stage2 = Stage2
100+ { s2AstData :: AstData P.SourceSpan
101+ }
102+
103+data Stage3 = Stage3
104+ { s3Declarations :: M.Map P.ModuleName [IdeDeclarationAnn]
105+ , s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)
106+ }
107+
108+newtype Match a = Match (P.ModuleName, a)
109+ deriving (Show, Eq, Functor)
98110
99111newtype Completion =
100− Completion (ModuleIdent, DeclIdent, Text)
112+ Completion (Text, Text, Text)
113+ deriving (Show,Eq)
114+
115+newtype Info =
116+ Info (Text, Text, Text, Maybe P.SourceSpan)
101117 deriving (Show,Eq)
102118
119+instance ToJSON Info where
120+ toJSON (Info (m, d, t, sourceSpan)) =
121+ object ["module" .= m, "identifier" .= d, "type" .= t, "definedAt" .= sourceSpan]
122+
103123instance ToJSON Completion where
104− toJSON (Completion (m,d,t)) =
124+ toJSON (Completion (m, d, t)) =
105125 object ["module" .= m, "identifier" .= d, "type" .= t]
106126
107127data ModuleImport =
108128 ModuleImport
109129 { importModuleName :: ModuleIdent
110− , importType :: D.ImportDeclarationType
130+ , importType :: P.ImportDeclarationType
111131 , importQualifier :: Maybe Text
112132 } deriving(Show)
113133
@@ -117,29 +137,30 @@ instance Eq ModuleImport where
117137 && importQualifier mi1 == importQualifier mi2
118138
119139instance ToJSON ModuleImport where
120− toJSON (ModuleImport mn D.Implicit qualifier) =
140+ toJSON (ModuleImport mn P.Implicit qualifier) =
121141 object $ [ "module" .= mn
122142 , "importType" .= ("implicit" :: Text)
123143 ] ++ fmap (\x -> "qualifier" .= x) (maybeToList qualifier)
124− toJSON (ModuleImport mn (D.Explicit refs) _) =
144+ toJSON (ModuleImport mn (P.Explicit refs) _) =
125145 object [ "module" .= mn
126146 , "importType" .= ("explicit" :: Text)
127147 , "identifiers" .= (identifierFromDeclarationRef <$> refs)
128148 ]
129− toJSON (ModuleImport mn (D.Hiding refs) _) =
149+ toJSON (ModuleImport mn (P.Hiding refs) _) =
130150 object [ "module" .= mn
131151 , "importType" .= ("hiding" :: Text)
132152 , "identifiers" .= (identifierFromDeclarationRef <$> refs)
133153 ]
134154
135−identifierFromDeclarationRef :: D.DeclarationRef -> String
136−identifierFromDeclarationRef (D.TypeRef name _) = N.runProperName name
137−identifierFromDeclarationRef (D.ValueRef ident) = N.runIdent ident
138−identifierFromDeclarationRef (D.TypeClassRef name) = N.runProperName name
155+identifierFromDeclarationRef :: P.DeclarationRef -> Text
156+identifierFromDeclarationRef (P.TypeRef name _) = runProperNameT name
157+identifierFromDeclarationRef (P.ValueRef ident) = runIdentT ident
158+identifierFromDeclarationRef (P.TypeClassRef name) = runProperNameT name
139159identifierFromDeclarationRef _ = ""
140160
141161data Success =
142162 CompletionResult [Completion]
163+ | InfoResult [Info]
143164 | TextResult Text
144165 | MultilineTextResult [Text]
145166 | PursuitResult [PursuitResponse]
@@ -154,6 +175,7 @@ encodeSuccess res =
154175
155176instance ToJSON Success where
156177 toJSON (CompletionResult cs) = encodeSuccess cs
178+ toJSON (InfoResult i) = encodeSuccess i
157179 toJSON (TextResult t) = encodeSuccess t
158180 toJSON (MultilineTextResult ts) = encodeSuccess ts
159181 toJSON (PursuitResult resp) = encodeSuccess resp
@@ -183,14 +205,14 @@ data PursuitResponse =
183205 ModuleResponse ModuleIdent Text
184206 -- | A Pursuit Response for a declaration. Consist of the declarations type,
185207 -- module, name and package
186− | DeclarationResponse Text ModuleIdent DeclIdent Text
208+ | DeclarationResponse Text ModuleIdent Text Text
187209 deriving (Show,Eq)
188210
189211instance FromJSON PursuitResponse where
190212 parseJSON (Object o) = do
191213 package <- o .: "package"
192214 info <- o .: "info"
193− (type' :: String) <- info .: "type"
215+ (type' :: Text) <- info .: "type"
194216 case type' of
195217 "module" -> do
196218 name <- info .: "module"
@@ -205,26 +227,26 @@ instance FromJSON PursuitResponse where
205227
206228typeParse :: Text -> Either Text (Text, Text)
207229typeParse t = case parse parseType "" t of
208− Right (x,y) -> Right (pack x, pack y)
209− Left err -> Left (pack (show err))
230+ Right (x,y) -> Right (x, y)
231+ Left err -> Left (show err)
210232 where
211− parseType :: Parser (String, String)
233+ parseType :: Parser (Text, Text)
212234 parseType = do
213235 name <- identifier
214236 _ <- string "::"
215237 spaces
216238 type' <- many1 anyChar
217− pure (unpack name, type')
239+ pure (name, toS type')
218240
219241 identifier :: Parser Text
220242 identifier = do
221243 spaces
222244 ident <-
223245 -- necessary for being able to parse the following ((++), concat)
224− between (char '(') (char ')') (many1 (noneOf ", )")) <|>
246+ between (char '(') (char ')') (many1 (noneOf ", )")) Parsec.<|>
225247 many1 (noneOf ", )")
226248 spaces
227− pure (pack ident)
249+ pure (toS ident)
228250
229251instance ToJSON PursuitResponse where
230252 toJSON (ModuleResponse name package) =
src/Language/PureScript/Ide/Util.hs+64−34
@@ -9,57 +9,87 @@
99-- Stability : experimental
1010--
1111-- |
12−-- Generally useful functions and conversions
12+-- Generally useful functions
1313-----------------------------------------------------------------------------
1414
1515{-# LANGUAGE OverloadedStrings #-}
1616
17−module Language.PureScript.Ide.Util where
17+module Language.PureScript.Ide.Util
18+ ( identifierFromIdeDeclaration
19+ , unwrapMatch
20+ , unwrapPositioned
21+ , unwrapPositionedRef
22+ , completionFromMatch
23+ , infoFromMatch
24+ , encodeT
25+ , decodeT
26+ , discardAnn
27+ , module Language.PureScript.Ide.Conversions
28+ ) where
1829
30+import Protolude hiding (decodeUtf8, encodeUtf8)
1931import Data.Aeson
20−import Data.Text (Text)
2132import qualified Data.Text as T
22−import Data.Text.Lazy (fromStrict, toStrict)
2333import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
2434import qualified Language.PureScript as P
2535import Language.PureScript.Ide.Types
36+import Language.PureScript.Ide.Conversions
2637
27−runProperNameT :: P.ProperName a -> Text
28−runProperNameT = T.pack . P.runProperName
38+identifierFromIdeDeclaration :: IdeDeclaration -> Text
39+identifierFromIdeDeclaration d = case d of
40+ IdeValue name _ -> runIdentT name
41+ IdeType name _ -> runProperNameT name
42+ IdeTypeSynonym name _ -> runProperNameT name
43+ IdeDataConstructor name _ _ -> runProperNameT name
44+ IdeTypeClass name -> runProperNameT name
45+ IdeValueOperator op _ _ _ -> runOpNameT op
46+ IdeTypeOperator op _ _ _ -> runOpNameT op
2947
30−runIdentT :: P.Ident -> Text
31−runIdentT = T.pack . P.runIdent
48+discardAnn :: IdeDeclarationAnn -> IdeDeclaration
49+discardAnn (IdeDeclarationAnn _ d) = d
3250
33−prettyTypeT :: P.Type -> Text
34−prettyTypeT = T.unwords . fmap T.strip . T.lines . T.pack . P.prettyPrintType
51+unwrapMatch :: Match a -> a
52+unwrapMatch (Match (_, ed)) = ed
3553
36−identifierFromExternDecl :: ExternDecl -> Text
37−identifierFromExternDecl (ValueDeclaration name _) = name
38−identifierFromExternDecl (TypeDeclaration name _) = runProperNameT name
39−identifierFromExternDecl (TypeSynonymDeclaration name _) = runProperNameT name
40−identifierFromExternDecl (DataConstructor name _ _) = name
41−identifierFromExternDecl (TypeClassDeclaration name) = runProperNameT name
42−identifierFromExternDecl (ModuleDecl name _) = name
43−identifierFromExternDecl Dependency{} = "~Dependency~"
44−identifierFromExternDecl Export{} = "~Export~"
54+completionFromMatch :: Match IdeDeclaration -> Completion
55+completionFromMatch = Completion . completionFromMatch'
4556
46−identifierFromMatch :: Match -> Text
47−identifierFromMatch (Match _ ed) = identifierFromExternDecl ed
57+completionFromMatch' :: Match IdeDeclaration -> (Text, Text, Text)
58+completionFromMatch' (Match (m', d)) = case d of
59+ IdeValue name type' -> (m, runIdentT name, prettyTypeT type')
60+ IdeType name kind -> (m, runProperNameT name, toS (P.prettyPrintKind kind))
61+ IdeTypeSynonym name kind -> (m, runProperNameT name, prettyTypeT kind)
62+ IdeDataConstructor name _ type' -> (m, runProperNameT name, prettyTypeT type')
63+ IdeTypeClass name -> (m, runProperNameT name, "class")
64+ IdeValueOperator op ref precedence associativity ->
65+ (m, runOpNameT op, showFixity precedence associativity ref op)
66+ IdeTypeOperator op ref precedence associativity ->
67+ (m, runOpNameT op, showFixity precedence associativity ref op)
68+ where
69+ m = runModuleNameT m'
70+ showFixity p a r o =
71+ let asso = case a of
72+ P.Infix -> "infix"
73+ P.Infixl -> "infixl"
74+ P.Infixr -> "infixr"
75+ in T.unwords [asso, show p, r, "as", runOpNameT o]
4876
49−completionFromMatch :: Match -> Maybe Completion
50−completionFromMatch (Match _ Dependency{}) = Nothing
51−completionFromMatch (Match _ Export{}) = Nothing
52−completionFromMatch (Match m d) = Just $ case d of
53− ValueDeclaration name type' -> Completion (m, name, prettyTypeT type')
54− TypeDeclaration name kind -> Completion (m, runProperNameT name, T.pack $ P.prettyPrintKind kind)
55− TypeSynonymDeclaration name kind -> Completion (m, runProperNameT name, prettyTypeT kind)
56− DataConstructor name _ type' -> Completion (m, name, prettyTypeT type')
57− TypeClassDeclaration name -> Completion (m, runProperNameT name, "class")
58− ModuleDecl name _ -> Completion ("module", name, "module")
59− _ -> error "the impossible happened in completionFromMatch"
77+infoFromMatch :: Match IdeDeclarationAnn -> Info
78+infoFromMatch (Match (m, (IdeDeclarationAnn ann d))) =
79+ Info (a, b, c, annLocation ann)
80+ where
81+ (a, b, c) = completionFromMatch' (Match (m, d))
6082
6183encodeT :: (ToJSON a) => a -> Text
62−encodeT = toStrict . decodeUtf8 . encode
84+encodeT = toS . decodeUtf8 . encode
6385
6486decodeT :: (FromJSON a) => Text -> Maybe a
65−decodeT = decode . encodeUtf8 . fromStrict
87+decodeT = decode . encodeUtf8 . toS
88+
89+unwrapPositioned :: P.Declaration -> P.Declaration
90+unwrapPositioned (P.PositionedDeclaration _ _ x) = x
91+unwrapPositioned x = x
92+
93+unwrapPositionedRef :: P.DeclarationRef -> P.DeclarationRef
94+unwrapPositionedRef (P.PositionedDeclarationRef _ _ x) = x
95+unwrapPositionedRef x = x
src/Language/PureScript/Ide/Watcher.hs+25−31
@@ -12,44 +12,38 @@
1212-- File watcher for externs files
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE RecordWildCards #-}
15+module Language.PureScript.Ide.Watcher
16+ ( watcher
17+ ) where
1618
17−module Language.PureScript.Ide.Watcher where
19+import Protolude
1820
19−import Prelude ()
20−import Prelude.Compat
21−
22−import Control.Concurrent (threadDelay)
2321import Control.Concurrent.STM
24−import Control.Monad
25−import Control.Monad.Trans.Except
26−import qualified Data.Map as M
27−import Data.Maybe (isJust)
28−import Language.PureScript.Externs
2922import Language.PureScript.Ide.Externs
3023import Language.PureScript.Ide.State
3124import Language.PureScript.Ide.Types
3225import System.FilePath
3326import System.FSNotify
3427
28+-- | Reloads an ExternsFile from Disc. If the Event indicates the ExternsFile
29+-- was deleted we don't do anything.
30+reloadFile :: TVar IdeState -> Event -> IO ()
31+reloadFile _ Removed{} = pure ()
32+reloadFile ref ev = do
33+ let fp = eventPath ev
34+ ef' <- runExceptT (readExternFile fp)
35+ case ef' of
36+ Left _ -> pure ()
37+ Right ef -> do
38+ void $ atomically (insertExternsSTM ref ef *> populateStage3STM ref)
39+ putStrLn ("Reloaded File at: " ++ fp)
3540
36−reloadFile :: TVar PscIdeState -> FilePath -> IO ()
37−reloadFile stateVar fp = do
38− (Right ef@ExternsFile{..}) <- runExceptT $ readExternFile fp
39− reloaded <- atomically $ do
40− st <- readTVar stateVar
41− if isLoaded efModuleName st
42− then
43− insertModule' stateVar ef *> pure True
44− else
45− pure False
46− when reloaded $ putStrLn $ "Reloaded File at: " ++ fp
47− where
48− isLoaded name st = isJust (M.lookup name (externsFiles st))
49−
50−watcher :: TVar PscIdeState -> FilePath -> IO ()
51−watcher stateVar fp = withManager $ \mgr -> do
52− _ <- watchTree mgr fp
53− (\ev -> takeFileName (eventPath ev) == "externs.json")
54− (reloadFile stateVar . eventPath)
55− forever (threadDelay 10000)
41+-- | Installs filewatchers for the given directory and reloads ExternsFiles when
42+-- they change on disc
43+watcher :: TVar IdeState -> FilePath -> IO ()
44+watcher stateVar fp =
45+ withManagerConf (defaultConfig { confDebounce = NoDebounce }) $ \mgr -> do
46+ _ <- watchTree mgr fp
47+ (\ev -> takeFileName (eventPath ev) == "externs.json")
48+ (reloadFile stateVar)
49+ forever (threadDelay 100000)
src/Language/PureScript/Interactive.hsnew file+289
@@ -0,0 +1,289 @@
1+{-# LANGUAGE DoAndIfThenElse #-}
2+{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE MultiParamTypeClasses #-}
4+{-# LANGUAGE TupleSections #-}
5+{-# LANGUAGE DataKinds #-}
6+
7+module Language.PureScript.Interactive
8+ ( handleCommand
9+ , module Interactive
10+
11+ -- TODO: remove these exports
12+ , make
13+ , runMake
14+ ) where
15+
16+import Prelude ()
17+import Prelude.Compat
18+
19+import Data.List (intercalate, nub, sort, find, foldl')
20+import Data.Maybe (mapMaybe)
21+import qualified Data.Map as M
22+
23+import Control.Monad.IO.Class (MonadIO, liftIO)
24+import Control.Monad.State.Class
25+import Control.Monad.Reader.Class
26+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
27+import Control.Monad.Trans.State.Strict (StateT, runStateT)
28+import Control.Monad.Writer.Strict (Writer(), runWriter)
29+
30+import qualified Language.PureScript as P
31+import qualified Language.PureScript.Names as N
32+
33+import Language.PureScript.Interactive.Completion as Interactive
34+import Language.PureScript.Interactive.IO as Interactive
35+import Language.PureScript.Interactive.Message as Interactive
36+import Language.PureScript.Interactive.Module as Interactive
37+import Language.PureScript.Interactive.Parser as Interactive
38+import Language.PureScript.Interactive.Printer as Interactive
39+import Language.PureScript.Interactive.Types as Interactive
40+
41+import System.FilePath ((</>))
42+
43+-- | Pretty-print errors
44+printErrors :: MonadIO m => P.MultipleErrors -> m ()
45+printErrors = liftIO . putStrLn . P.prettyPrintMultipleErrors P.defaultPPEOptions
46+
47+-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
48+-- options and ignores the warning messages.
49+runMake :: P.Make a -> IO (Either P.MultipleErrors a)
50+runMake mk = fst <$> P.runMake P.defaultOptions mk
51+
52+-- | Rebuild a module, using the cached externs data for dependencies.
53+rebuild
54+ :: [P.ExternsFile]
55+ -> P.Module
56+ -> P.Make (P.ExternsFile, P.Environment)
57+rebuild loadedExterns m = do
58+ externs <- P.rebuildModule buildActions loadedExterns m
59+ return (externs, foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment (loadedExterns ++ [externs]))
60+ where
61+ buildActions :: P.MakeActions P.Make
62+ buildActions =
63+ (P.buildMakeActions modulesDir
64+ filePathMap
65+ M.empty
66+ False) { P.progress = const (return ()) }
67+
68+ filePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
69+ filePathMap = M.singleton (P.getModuleName m) (Left P.RebuildAlways)
70+
71+-- | Build the collection of modules from scratch. This is usually done on startup.
72+make
73+ :: [(FilePath, P.Module)]
74+ -> P.Make ([P.ExternsFile], P.Environment)
75+make ms = do
76+ foreignFiles <- P.inferForeignModules filePathMap
77+ externs <- P.make (buildActions foreignFiles) (map snd ms)
78+ return (externs, foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment externs)
79+ where
80+ buildActions :: M.Map P.ModuleName FilePath -> P.MakeActions P.Make
81+ buildActions foreignFiles =
82+ P.buildMakeActions modulesDir
83+ filePathMap
84+ foreignFiles
85+ False
86+
87+ filePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
88+ filePathMap = M.fromList $ map (\(fp, m) -> (P.getModuleName m, Right fp)) ms
89+
90+-- | Performs a PSCi command
91+handleCommand
92+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
93+ => (String -> m ())
94+ -> m ()
95+ -> Command
96+ -> m ()
97+handleCommand _ _ ShowHelp = liftIO $ putStrLn helpMessage
98+handleCommand _ r ResetState = handleResetState r
99+handleCommand c _ (Expression val) = handleExpression c val
100+handleCommand _ _ (Import im) = handleImport im
101+handleCommand _ _ (Decls l) = handleDecls l
102+handleCommand _ _ (TypeOf val) = handleTypeOf val
103+handleCommand _ _ (KindOf typ) = handleKindOf typ
104+handleCommand _ _ (BrowseModule moduleName) = handleBrowse moduleName
105+handleCommand _ _ (ShowInfo QueryLoaded) = handleShowLoadedModules
106+handleCommand _ _ (ShowInfo QueryImport) = handleShowImportedModules
107+handleCommand _ _ QuitPSCi = P.internalError "`handleCommand QuitPSCi` was called. This is a bug."
108+
109+-- | Reset the application state
110+handleResetState
111+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
112+ => m ()
113+ -> m ()
114+handleResetState reload = do
115+ modify $ updateImportedModules (const [])
116+ . updateLets (const [])
117+ files <- asks psciLoadedFiles
118+ e <- runExceptT $ do
119+ modules <- ExceptT . liftIO $ loadAllModules files
120+ (externs, _) <- ExceptT . liftIO . runMake . make $ modules
121+ return (map snd modules, externs)
122+ case e of
123+ Left errs -> printErrors errs
124+ Right (modules, externs) -> do
125+ modify (updateLoadedExterns (const (zip modules externs)))
126+ reload
127+
128+-- | Takes a value expression and evaluates it with the current state.
129+handleExpression
130+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
131+ => (String -> m ())
132+ -> P.Expr
133+ -> m ()
134+handleExpression evaluate val = do
135+ st <- get
136+ let m = createTemporaryModule True st val
137+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
138+ case e of
139+ Left errs -> printErrors errs
140+ Right _ -> do
141+ js <- liftIO $ readFile (modulesDir </> "$PSCI" </> "index.js")
142+ evaluate js
143+
144+-- |
145+-- Takes a list of declarations and updates the environment, then run a make. If the declaration fails,
146+-- restore the original environment.
147+--
148+handleDecls
149+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
150+ => [P.Declaration]
151+ -> m ()
152+handleDecls ds = do
153+ st <- gets (updateLets (++ ds))
154+ let m = createTemporaryModule False st (P.Literal (P.ObjectLiteral []))
155+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
156+ case e of
157+ Left err -> printErrors err
158+ Right _ -> put st
159+
160+-- | Show actual loaded modules in psci.
161+handleShowLoadedModules
162+ :: (MonadState PSCiState m, MonadIO m)
163+ => m ()
164+handleShowLoadedModules = do
165+ loadedModules <- gets psciLoadedExterns
166+ liftIO $ putStrLn (readModules loadedModules)
167+ where
168+ readModules = unlines . sort . nub . map (P.runModuleName . P.getModuleName . fst)
169+
170+-- | Show the imported modules in psci.
171+handleShowImportedModules
172+ :: (MonadState PSCiState m, MonadIO m)
173+ => m ()
174+handleShowImportedModules = do
175+ PSCiState { psciImportedModules = importedModules } <- get
176+ liftIO $ showModules importedModules >>= putStrLn
177+ return ()
178+ where
179+ showModules = return . unlines . sort . map showModule
180+ showModule (mn, declType, asQ) =
181+ "import " ++ N.runModuleName mn ++ showDeclType declType ++
182+ foldMap (\mn' -> " as " ++ N.runModuleName mn') asQ
183+
184+ showDeclType P.Implicit = ""
185+ showDeclType (P.Explicit refs) = refsList refs
186+ showDeclType (P.Hiding refs) = " hiding " ++ refsList refs
187+ refsList refs = " (" ++ commaList (mapMaybe showRef refs) ++ ")"
188+
189+ showRef :: P.DeclarationRef -> Maybe String
190+ showRef (P.TypeRef pn dctors) =
191+ Just $ N.runProperName pn ++ "(" ++ maybe ".." (commaList . map N.runProperName) dctors ++ ")"
192+ showRef (P.TypeOpRef op) =
193+ Just $ "type " ++ N.showOp op
194+ showRef (P.ValueRef ident) =
195+ Just $ N.runIdent ident
196+ showRef (P.ValueOpRef op) =
197+ Just $ N.showOp op
198+ showRef (P.TypeClassRef pn) =
199+ Just $ "class " ++ N.runProperName pn
200+ showRef (P.TypeInstanceRef ident) =
201+ Just $ N.runIdent ident
202+ showRef (P.ModuleRef name) =
203+ Just $ "module " ++ N.runModuleName name
204+ showRef (P.ReExportRef _ _) =
205+ Nothing
206+ showRef (P.PositionedDeclarationRef _ _ ref) =
207+ showRef ref
208+
209+ commaList :: [String] -> String
210+ commaList = intercalate ", "
211+
212+-- | Imports a module, preserving the initial state on failure.
213+handleImport
214+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
215+ => ImportedModule
216+ -> m ()
217+handleImport im = do
218+ st <- gets (updateImportedModules (im :))
219+ let m = createTemporaryModuleForImports st
220+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
221+ case e of
222+ Left errs -> printErrors errs
223+ Right _ -> put st
224+
225+-- | Takes a value and prints its type
226+handleTypeOf
227+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
228+ => P.Expr
229+ -> m ()
230+handleTypeOf val = do
231+ st <- get
232+ let m = createTemporaryModule False st val
233+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
234+ case e of
235+ Left errs -> printErrors errs
236+ Right (_, env') ->
237+ case M.lookup (P.mkQualified (P.Ident "it") (P.ModuleName [P.ProperName "$PSCI"])) (P.names env') of
238+ Just (ty, _, _) -> liftIO . putStrLn . P.prettyPrintType $ ty
239+ Nothing -> liftIO $ putStrLn "Could not find type"
240+
241+-- | Takes a type and prints its kind
242+handleKindOf
243+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
244+ => P.Type
245+ -> m ()
246+handleKindOf typ = do
247+ st <- get
248+ let m = createTemporaryModuleForKind st typ
249+ mName = P.ModuleName [P.ProperName "$PSCI"]
250+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
251+ case e of
252+ Left errs -> printErrors errs
253+ Right (_, env') ->
254+ case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
255+ Just (_, typ') -> do
256+ let chk = (P.emptyCheckState env') { P.checkCurrentModule = Just mName }
257+ k = check (P.kindOf typ') chk
258+
259+ check :: StateT P.CheckState (ExceptT P.MultipleErrors (Writer P.MultipleErrors)) a -> P.CheckState -> Either P.MultipleErrors (a, P.CheckState)
260+ check sew = fst . runWriter . runExceptT . runStateT sew
261+ case k of
262+ Left err -> printErrors err
263+ Right (kind, _) -> liftIO . putStrLn . P.prettyPrintKind $ kind
264+ Nothing -> liftIO $ putStrLn "Could not find kind"
265+
266+-- | Browse a module and displays its signature
267+handleBrowse
268+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
269+ => P.ModuleName
270+ -> m ()
271+handleBrowse moduleName = do
272+ st <- get
273+ env <- asks psciEnvironment
274+ if isModInEnv moduleName st
275+ then liftIO . putStrLn $ printModuleSignatures moduleName env
276+ else case lookupUnQualifiedModName moduleName st of
277+ Just unQualifiedName ->
278+ if isModInEnv unQualifiedName st
279+ then liftIO . putStrLn $ printModuleSignatures unQualifiedName env
280+ else failNotInEnv moduleName
281+ Nothing ->
282+ failNotInEnv moduleName
283+ where
284+ isModInEnv modName =
285+ any ((== modName) . P.getModuleName . fst) . psciLoadedExterns
286+ failNotInEnv modName =
287+ liftIO $ putStrLn $ "Module '" ++ N.runModuleName modName ++ "' is not valid."
288+ lookupUnQualifiedModName quaModName st =
289+ (\(modName,_,_) -> modName) <$> find ( \(_, _, mayQuaName) -> mayQuaName == Just quaModName) (psciImportedModules st)
psci/PSCi/Completion.hs → src/Language/PureScript/Interactive/Completion.hsrenamed+77−81
@@ -1,36 +1,89 @@
11{-# LANGUAGE DataKinds #-}
22
3−module PSCi.Completion where
3+module Language.PureScript.Interactive.Completion
4+ ( CompletionM
5+ , liftCompletionM
6+ , completion
7+ , completion'
8+ ) where
49
5−import Prelude ()
610import Prelude.Compat
711
8−import Data.Maybe (mapMaybe)
9−import Data.List (nub, nubBy, sortBy, isPrefixOf, stripPrefix)
10−import Data.Char (isUpper)
11−import Data.Function (on)
12−
13−import Control.Arrow (second)
14−import Control.Monad.Trans.Reader (asks, runReaderT, ReaderT)
15−import Control.Monad.Trans.State.Strict
16−
17−import System.Console.Haskeline
18−
12+import Control.Arrow (second)
13+import Control.Monad.IO.Class (MonadIO(..))
14+import Control.Monad.State.Class (MonadState(..))
15+import Control.Monad.Trans.Reader (asks, runReaderT, ReaderT)
16+import Data.Function (on)
17+import Data.List (nub, nubBy, isPrefixOf, sortBy, stripPrefix)
18+import Data.Maybe (mapMaybe)
1919import qualified Language.PureScript as P
20+import qualified Language.PureScript.Interactive.Directive as D
21+import Language.PureScript.Interactive.Types
2022import qualified Language.PureScript.Names as N
21−
22−import qualified PSCi.Directive as D
23−import PSCi.Types
23+import System.Console.Haskeline
2424
2525-- Completions may read the state, but not modify it.
2626type CompletionM = ReaderT PSCiState IO
2727
28−-- Lift a `CompletionM` action to a `StateT PSCiState IO` one.
29−liftCompletionM :: CompletionM a -> StateT PSCiState IO a
30−liftCompletionM act = StateT (\s -> (\a -> (a, s)) <$> runReaderT act s)
28+-- Lift a `CompletionM` action into a state monad.
29+liftCompletionM
30+ :: (MonadState PSCiState m, MonadIO m)
31+ => CompletionM a
32+ -> m a
33+liftCompletionM act = do
34+ st <- get
35+ liftIO $ runReaderT act st
3136
3237-- Haskeline completions
3338
39+-- | Loads module, function, and file completions.
40+completion
41+ :: (MonadState PSCiState m, MonadIO m)
42+ => CompletionFunc m
43+completion = liftCompletionM . completion'
44+
45+completion' :: CompletionFunc CompletionM
46+completion' = completeWordWithPrev Nothing " \t\n\r" findCompletions
47+
48+-- | Callback for Haskeline's `completeWordWithPrev`.
49+-- Expects:
50+-- * Line contents to the left of the word, reversed
51+-- * Word to be completed
52+findCompletions :: String -> String -> CompletionM [Completion]
53+findCompletions prev word = do
54+ let ctx = completionContext (words (reverse prev)) word
55+ completions <- concat <$> traverse getCompletions ctx
56+ return $ sortBy directivesFirst completions
57+ where
58+ getCompletions :: CompletionContext -> CompletionM [Completion]
59+ getCompletions = fmap (mapMaybe (either (prefixedBy word) Just)) . getCompletion
60+
61+ getCompletion :: CompletionContext -> CompletionM [Either String Completion]
62+ getCompletion ctx =
63+ case ctx of
64+ CtxFilePath f -> map Right <$> listFiles f
65+ CtxModule -> map Left <$> getModuleNames
66+ CtxIdentifier -> map Left <$> ((++) <$> getIdentNames <*> getDctorNames)
67+ CtxType -> map Left <$> getTypeNames
68+ CtxFixed str -> return [Left str]
69+ CtxDirective d -> return (map Left (completeDirectives d))
70+
71+ completeDirectives :: String -> [String]
72+ completeDirectives = map (':' :) . D.directiveStringsFor
73+
74+ prefixedBy :: String -> String -> Maybe Completion
75+ prefixedBy w cand = if w `isPrefixOf` cand
76+ then Just (simpleCompletion cand)
77+ else Nothing
78+
79+ directivesFirst :: Completion -> Completion -> Ordering
80+ directivesFirst (Completion _ d1 _) (Completion _ d2 _) = go d1 d2
81+ where
82+ go (':' : xs) (':' : ys) = compare xs ys
83+ go (':' : _) _ = LT
84+ go _ (':' : _) = GT
85+ go xs ys = compare xs ys
86+
3487data CompletionContext
3588 = CtxDirective String
3689 | CtxFilePath String
@@ -38,16 +91,7 @@ data CompletionContext
3891 | CtxIdentifier
3992 | CtxType
4093 | CtxFixed String
41− deriving (Show, Read)
42−
43−-- |
44−-- Loads module, function, and file completions.
45−--
46−completion :: CompletionFunc (StateT PSCiState IO)
47−completion = liftCompletionM . completion'
48−
49−completion' :: CompletionFunc CompletionM
50−completion' = completeWordWithPrev Nothing " \t\n\r" findCompletions
94+ deriving (Show)
5195
5296-- |
5397-- Decide what kind of completion we need based on input. This function expects
@@ -75,8 +119,6 @@ completeDirective ws w =
75119
76120directiveArg :: String -> Directive -> [CompletionContext]
77121directiveArg _ Browse = [CtxModule]
78−directiveArg w Load = [CtxFilePath w]
79−directiveArg w Foreign = [CtxFilePath w]
80122directiveArg _ Quit = []
81123directiveArg _ Reset = []
82124directiveArg _ Help = []
@@ -87,10 +129,8 @@ directiveArg _ Kind = [CtxType]
87129completeImport :: [String] -> String -> [CompletionContext]
88130completeImport ws w' =
89131 case (ws, w') of
90− (["import"], w) | headSatisfies isUpper w -> [CtxModule]
91− (["import"], _) -> [CtxModule, CtxFixed "qualified"]
92− (["import", "qualified"], _) -> [CtxModule]
93− _ -> []
132+ (["import"], _) -> [CtxModule]
133+ _ -> []
94134
95135headSatisfies :: (a -> Bool) -> [a] -> Bool
96136headSatisfies p str =
@@ -98,44 +138,8 @@ headSatisfies p str =
98138 (c:_) -> p c
99139 _ -> False
100140
101−-- | Callback for Haskeline's `completeWordWithPrev`.
102−-- Expects:
103−-- * Line contents to the left of the word, reversed
104−-- * Word to be completed
105−findCompletions :: String -> String -> CompletionM [Completion]
106−findCompletions prev word = do
107− let ctx = completionContext (words (reverse prev)) word
108− completions <- concat <$> traverse getCompletions ctx
109− return $ sortBy directivesFirst completions
110− where
111− getCompletions :: CompletionContext -> CompletionM [Completion]
112− getCompletions = fmap (mapMaybe (either (prefixedBy word) Just)) . getCompletion
113−
114− prefixedBy :: String -> String -> Maybe Completion
115− prefixedBy w cand = if w `isPrefixOf` cand
116− then Just (simpleCompletion cand)
117− else Nothing
118−
119−getCompletion :: CompletionContext -> CompletionM [Either String Completion]
120−getCompletion ctx =
121− case ctx of
122− CtxFilePath f -> map Right <$> listFiles f
123− CtxModule -> map Left <$> getModuleNames
124− CtxIdentifier -> map Left <$> ((++) <$> getIdentNames <*> getDctorNames)
125− CtxType -> map Left <$> getTypeNames
126− CtxFixed str -> return [Left str]
127− CtxDirective d -> return (map Left (completeDirectives d))
128−
129− where
130− completeDirectives :: String -> [String]
131− completeDirectives = map (':' :) . D.directiveStringsFor
132−
133−
134141getLoadedModules :: CompletionM [P.Module]
135−getLoadedModules = asks (map snd . psciLoadedModules)
136−
137−getImportedModules :: CompletionM [ImportedModule]
138−getImportedModules = asks psciImportedModules
142+getLoadedModules = asks (map fst . psciLoadedExterns)
139143
140144getModuleNames :: CompletionM [String]
141145getModuleNames = moduleNames <$> getLoadedModules
@@ -215,12 +219,4 @@ dctorNames = nubOnFst . concatMap go . P.exportedDeclarations
215219 go _ = []
216220
217221moduleNames :: [P.Module] -> [String]
218−moduleNames ms = nub [P.runModuleName moduleName | P.Module _ _ moduleName _ _ <- ms]
219−
220−directivesFirst :: Completion -> Completion -> Ordering
221−directivesFirst (Completion _ d1 _) (Completion _ d2 _) = go d1 d2
222− where
223− go (':' : xs) (':' : ys) = compare xs ys
224− go (':' : _) _ = LT
225− go _ (':' : _) = GT
226− go xs ys = compare xs ys
222+moduleNames = nub . map (P.runModuleName . P.getModuleName)
psci/PSCi/Directive.hs → src/Language/PureScript/Interactive/Directive.hsrenamed+2−21
@@ -1,29 +1,15 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Directive
4−-- Copyright :
5−-- License : MIT
6−--
7−-- Maintainer :
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- Directives for PSCI.
133--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.Interactive.Directive where
155
16−module PSCi.Directive where
17−
18−import Prelude ()
196import Prelude.Compat
207
21−
228import Data.Maybe (fromJust, listToMaybe)
239import Data.List (isPrefixOf)
2410import Data.Tuple (swap)
2511
26−import PSCi.Types
12+import Language.PureScript.Interactive.Types
2713
2814-- |
2915-- List of all avaliable directives.
@@ -41,8 +27,6 @@ directiveStrings =
4127 , (Quit , ["quit"])
4228 , (Reset , ["reset"])
4329 , (Browse , ["browse"])
44− , (Load , ["load", "module"])
45− , (Foreign, ["foreign"])
4630 , (Type , ["type"])
4731 , (Kind , ["kind"])
4832 , (Show , ["show"])
@@ -109,11 +93,8 @@ help =
10993 , (Quit, "", "Quit PSCi")
11094 , (Reset, "", "Discard all imported modules and declared bindings")
11195 , (Browse, "<module>", "See all functions in <module>")
112− , (Load, "<file>", "Load <file> for importing")
113− , (Foreign, "<file>", "Load foreign module <file>")
11496 , (Type, "<expr>", "Show the type of <expr>")
11597 , (Kind, "<type>", "Show the kind of <type>")
11698 , (Show, "import", "Show all imported modules")
11799 , (Show, "loaded", "Show all loaded modules")
118100 ]
119−
psci/PSCi/IO.hs → src/Language/PureScript/Interactive/IO.hsrenamed+4−31
@@ -1,28 +1,11 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : IO
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15−module PSCi.IO where
1+module Language.PureScript.Interactive.IO where
162
17−import Prelude ()
183import Prelude.Compat
194
20−import System.Directory (createDirectoryIfMissing, getHomeDirectory, findExecutable, doesFileExist)
21−import System.FilePath (takeDirectory, (</>), isPathSeparator)
22−import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
235import Control.Monad (msum)
24−import Control.Monad.IO.Class (MonadIO, liftIO)
25−import System.Console.Haskeline (outputStrLn, InputT)
6+import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
7+import System.Directory (createDirectoryIfMissing, getHomeDirectory, findExecutable)
8+import System.FilePath (takeDirectory, (</>), isPathSeparator)
269
2710mkdirp :: FilePath -> IO ()
2811mkdirp = createDirectoryIfMissing True . takeDirectory
@@ -50,19 +33,9 @@ getHistoryFilename = do
5033 mkdirp filename
5134 return filename
5235
53−
5436-- |
5537-- Expands tilde in path.
5638--
5739expandTilde :: FilePath -> IO FilePath
5840expandTilde ('~':p:rest) | isPathSeparator p = (</> rest) <$> getHomeDirectory
5941expandTilde p = return p
60−
61−
62−whenFileExists :: MonadIO m => FilePath -> (FilePath -> InputT m ()) -> InputT m ()
63−whenFileExists filePath f = do
64− absPath <- liftIO $ expandTilde filePath
65− exists <- liftIO $ doesFileExist absPath
66− if exists
67− then f absPath
68− else outputStrLn $ "Couldn't locate: " ++ filePath
src/Language/PureScript/Interactive/Message.hsnew file+52
@@ -0,0 +1,52 @@
1+module Language.PureScript.Interactive.Message where
2+
3+import Prelude.Compat
4+
5+import Data.List (intercalate)
6+import Data.Version (showVersion)
7+import qualified Paths_purescript as Paths
8+import qualified Language.PureScript.Interactive.Directive as D
9+import Language.PureScript.Interactive.Types
10+
11+-- Messages
12+
13+-- | The help message.
14+helpMessage :: String
15+helpMessage = "The following commands are available:\n\n " ++
16+ intercalate "\n " (map line D.help) ++
17+ "\n\n" ++ extraHelp
18+ where
19+ line :: (Directive, String, String) -> String
20+ line (dir, arg, desc) =
21+ let cmd = ':' : D.stringFor dir
22+ in unwords [ cmd
23+ , replicate (11 - length cmd) ' '
24+ , arg
25+ , replicate (11 - length arg) ' '
26+ , desc
27+ ]
28+
29+ extraHelp =
30+ "Further information is available on the PureScript wiki:\n" ++
31+ " --> https://github.com/purescript/purescript/wiki/psci"
32+
33+-- | The welcome prologue.
34+prologueMessage :: String
35+prologueMessage = unlines
36+ [ "PSCi, version " ++ showVersion Paths.version
37+ , "Type :? for help"
38+ ]
39+
40+supportModuleMessage :: String
41+supportModuleMessage = unlines
42+ [ "PSCi requires the purescript-psci-support package to be installed."
43+ , "You can install it using Bower as follows:"
44+ , ""
45+ , " bower i purescript-psci-support --save-dev"
46+ , ""
47+ , "For help getting started, visit http://wiki.purescript.org/PSCi"
48+ ]
49+
50+-- | The quit message.
51+quitMessage :: String
52+quitMessage = "See ya!"
src/Language/PureScript/Interactive/Module.hsnew file+99
@@ -0,0 +1,99 @@
1+module Language.PureScript.Interactive.Module where
2+
3+import Prelude.Compat
4+
5+import Control.Monad
6+import qualified Language.PureScript as P
7+import Language.PureScript.Interactive.Types
8+import System.FilePath (pathSeparator)
9+import System.IO.UTF8 (readUTF8File)
10+
11+-- * Support Module
12+
13+-- | The name of the PSCI support module
14+supportModuleName :: P.ModuleName
15+supportModuleName = P.moduleNameFromString "PSCI.Support"
16+
17+-- | Checks if the Console module is defined
18+supportModuleIsDefined :: [P.Module] -> Bool
19+supportModuleIsDefined = any ((== supportModuleName) . P.getModuleName)
20+
21+-- * Module Management
22+
23+-- |
24+-- Loads a file for use with imports.
25+--
26+loadModule :: FilePath -> IO (Either String [P.Module])
27+loadModule filename = do
28+ content <- readUTF8File filename
29+ return $ either (Left . P.prettyPrintMultipleErrors P.defaultPPEOptions) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
30+
31+-- |
32+-- Load all modules.
33+--
34+loadAllModules :: [FilePath] -> IO (Either P.MultipleErrors [(FilePath, P.Module)])
35+loadAllModules files = do
36+ filesAndContent <- forM files $ \filename -> do
37+ content <- readUTF8File filename
38+ return (filename, content)
39+ return $ P.parseModulesFromFiles id filesAndContent
40+
41+-- |
42+-- Makes a volatile module to execute the current expression.
43+--
44+createTemporaryModule :: Bool -> PSCiState -> P.Expr -> P.Module
45+createTemporaryModule exec PSCiState{psciImportedModules = imports, psciLetBindings = lets} val =
46+ let
47+ moduleName = P.ModuleName [P.ProperName "$PSCI"]
48+ effModuleName = P.moduleNameFromString "Control.Monad.Eff"
49+ effImport = (effModuleName, P.Implicit, Just (P.ModuleName [P.ProperName "$Eff"]))
50+ supportImport = (supportModuleName, P.Implicit, Just (P.ModuleName [P.ProperName "$Support"]))
51+ eval = P.Var (P.Qualified (Just (P.ModuleName [P.ProperName "$Support"])) (P.Ident "eval"))
52+ mainValue = P.App eval (P.Var (P.Qualified Nothing (P.Ident "it")))
53+ itDecl = P.ValueDeclaration (P.Ident "it") P.Public [] $ Right val
54+ typeDecl = P.TypeDeclaration (P.Ident "$main")
55+ (P.TypeApp
56+ (P.TypeApp
57+ (P.TypeConstructor
58+ (P.Qualified (Just (P.ModuleName [P.ProperName "$Eff"])) (P.ProperName "Eff")))
59+ (P.TypeWildcard internalSpan))
60+ (P.TypeWildcard internalSpan))
61+ mainDecl = P.ValueDeclaration (P.Ident "$main") P.Public [] $ Right mainValue
62+ decls = if exec then [itDecl, typeDecl, mainDecl] else [itDecl]
63+ internalSpan = P.internalModuleSourceSpan "<internal>"
64+ in
65+ P.Module internalSpan
66+ [] moduleName
67+ ((importDecl `map` (effImport : supportImport : imports)) ++ lets ++ decls)
68+ Nothing
69+
70+
71+-- |
72+-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
73+--
74+createTemporaryModuleForKind :: PSCiState -> P.Type -> P.Module
75+createTemporaryModuleForKind PSCiState{psciImportedModules = imports, psciLetBindings = lets} typ =
76+ let
77+ moduleName = P.ModuleName [P.ProperName "$PSCI"]
78+ itDecl = P.TypeSynonymDeclaration (P.ProperName "IT") [] typ
79+ in
80+ P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing
81+
82+-- |
83+-- Makes a volatile module to execute the current imports.
84+--
85+createTemporaryModuleForImports :: PSCiState -> P.Module
86+createTemporaryModuleForImports PSCiState{psciImportedModules = imports} =
87+ let
88+ moduleName = P.ModuleName [P.ProperName "$PSCI"]
89+ in
90+ P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName (importDecl `map` imports) Nothing
91+
92+importDecl :: ImportedModule -> P.Declaration
93+importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ
94+
95+indexFile :: FilePath
96+indexFile = ".psci_modules" ++ pathSeparator : "index.js"
97+
98+modulesDir :: FilePath
99+modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
psci/PSCi/Parser.hs → src/Language/PureScript/Interactive/Parser.hsrenamed+9−27
@@ -1,35 +1,19 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Parser
4−-- Copyright : (c) Phil Freeman 2014
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- Parser for PSCI.
133--
14−-----------------------------------------------------------------------------
15−
16−module PSCi.Parser
4+module Language.PureScript.Interactive.Parser
175 ( parseCommand
186 ) where
197
20−import Prelude ()
21−import Prelude.Compat hiding (lex)
22−
23−import Data.Char (isSpace)
24−import Data.List (intercalate)
25−
26−import Text.Parsec hiding ((<|>))
8+import Prelude.Compat hiding (lex)
279
10+import Data.Char (isSpace)
11+import Data.List (intercalate)
12+import Text.Parsec hiding ((<|>))
2813import qualified Language.PureScript as P
29−import Language.PureScript.Parser.Common (mark, same)
30−
31−import qualified PSCi.Directive as D
32−import PSCi.Types
14+import qualified Language.PureScript.Interactive.Directive as D
15+import Language.PureScript.Interactive.Types
16+import Language.PureScript.Parser.Common (mark, same)
3317
3418-- |
3519-- Parses PSCI metacommands or expressions input from the user.
@@ -79,8 +63,6 @@ parseDirective cmd =
7963 Quit -> return QuitPSCi
8064 Reset -> return ResetState
8165 Browse -> BrowseModule <$> parseRest P.moduleName arg
82− Load -> return $ LoadFile (trim arg)
83− Foreign -> return $ LoadForeign (trim arg)
8466 Show -> ShowInfo <$> parseReplQuery' (trim arg)
8567 Type -> TypeOf <$> parseRest P.parseValue arg
8668 Kind -> KindOf <$> parseRest P.parseType arg
@@ -107,7 +89,7 @@ psciLet = Decls <$> (P.reserved "let" *> P.indented *> manyDecls)
10789-- :show import works, for example.
10890psciImport :: P.TokenParser Command
10991psciImport = do
110− (mn, declType, asQ, _) <- P.parseImportDeclaration'
92+ (mn, declType, asQ) <- P.parseImportDeclaration'
11193 return $ Import (mn, declType, asQ)
11294
11395-- | Any other declaration that we don't need a 'special case' parser for
psci/PSCi/Printer.hs → src/Language/PureScript/Interactive/Printer.hsrenamed+16−20
@@ -1,34 +1,32 @@
11{-# LANGUAGE RecordWildCards #-}
22{-# LANGUAGE DataKinds #-}
33
4−module PSCi.Printer where
4+module Language.PureScript.Interactive.Printer where
55
6−import Prelude ()
7−import Prelude.Compat
6+import Prelude.Compat
87
8+import Data.List (intersperse)
9+import qualified Data.Map as M
10+import Data.Maybe (mapMaybe)
911import qualified Language.PureScript as P
1012import qualified Text.PrettyPrint.Boxes as Box
11−import qualified Data.Map as M
12−import System.Console.Haskeline
13−import Data.Maybe (mapMaybe)
14−import Data.List (intersperse)
15−import Control.Monad.IO.Class (MonadIO)
1613
1714-- Printers
1815
1916-- |
2017-- Pretty print a module's signatures
2118--
22−printModuleSignatures :: MonadIO m => P.ModuleName -> P.Environment -> InputT m ()
19+printModuleSignatures :: P.ModuleName -> P.Environment -> String
2320printModuleSignatures moduleName (P.Environment {..}) =
2421 -- get relevant components of a module from environment
25− let moduleNamesIdent = (filter ((== moduleName) . fst) . M.keys) names
26− moduleTypeClasses = (filter (\(P.Qualified maybeName _) -> maybeName == Just moduleName) . M.keys) typeClasses
27− moduleTypes = (filter (\(P.Qualified maybeName _) -> maybeName == Just moduleName) . M.keys) types
22+ let moduleNamesIdent = byModuleName names
23+ moduleTypeClasses = byModuleName typeClasses
24+ moduleTypes = byModuleName types
25+ byModuleName = filter ((== Just moduleName) . P.getQual) . M.keys
2826
2927 in
3028 -- print each component
31− (outputStr . unlines . map trimEnd . lines . Box.render . Box.vsep 1 Box.left)
29+ (unlines . map trimEnd . lines . Box.render . Box.vsep 1 Box.left)
3230 [ printModule's (mapMaybe (showTypeClass . findTypeClass typeClasses)) moduleTypeClasses -- typeClasses
3331 , printModule's (mapMaybe (showType typeClasses dataConstructors typeSynonyms . findType types)) moduleTypes -- types
3432 , printModule's (map (showNameType . findNameType names)) moduleNamesIdent -- functions
@@ -36,8 +34,10 @@ printModuleSignatures moduleName (P.Environment {..}) =
3634
3735 where printModule's showF = Box.vsep 1 Box.left . showF
3836
39− findNameType :: M.Map (P.ModuleName, P.Ident) (P.Type, P.NameKind, P.NameVisibility) -> (P.ModuleName, P.Ident) -> (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility))
40− findNameType envNames m@(_, mIdent) = (mIdent, M.lookup m envNames)
37+ findNameType :: M.Map (P.Qualified P.Ident) (P.Type, P.NameKind, P.NameVisibility)
38+ -> P.Qualified P.Ident
39+ -> (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility))
40+ findNameType envNames m = (P.disqualify m, M.lookup m envNames)
4141
4242 showNameType :: (P.Ident, Maybe (P.Type, P.NameKind, P.NameVisibility)) -> Box.Box
4343 showNameType (mIdent, Just (mType, _, _)) = Box.text (P.showIdent mIdent ++ " :: ") Box.<> P.typeAsBox mType
@@ -58,7 +58,7 @@ printModuleSignatures moduleName (P.Environment {..}) =
5858 if null constrs
5959 then Box.text ""
6060 else Box.text "("
61− Box.<> Box.hcat Box.left (intersperse (Box.text ", ") $ map (\(P.Qualified _ pn, lt) -> Box.text (P.runProperName pn) Box.<+> Box.hcat Box.left (map P.typeAtomAsBox lt)) constrs)
61+ Box.<> Box.hcat Box.left (intersperse (Box.text ", ") $ map (\(P.Constraint (P.Qualified _ pn) lt _) -> Box.text (P.runProperName pn) Box.<+> Box.hcat Box.left (map P.typeAtomAsBox lt)) constrs)
6262 Box.<> Box.text ") <= "
6363 className =
6464 Box.text (P.runProperName name)
@@ -125,7 +125,3 @@ printModuleSignatures moduleName (P.Environment {..}) =
125125 mapFirstRest f g (x:xs) = f x : map g xs
126126
127127 trimEnd = reverse . dropWhile (== ' ') . reverse
128−
129−-- | Pretty-print errors
130−printErrors :: MonadIO m => P.MultipleErrors -> InputT m ()
131−printErrors = outputStrLn . P.prettyPrintMultipleErrors False
src/Language/PureScript/Interactive/Types.hsnew file+145
@@ -0,0 +1,145 @@
1+-- |
2+-- Type declarations and associated basic functions for PSCI.
3+--
4+module Language.PureScript.Interactive.Types where
5+
6+import Prelude.Compat
7+
8+import qualified Language.PureScript as P
9+
10+-- | The PSCI configuration.
11+--
12+-- These configuration values do not change during execution.
13+--
14+data PSCiConfig = PSCiConfig
15+ { psciLoadedFiles :: [FilePath]
16+ , psciEnvironment :: P.Environment
17+ } deriving Show
18+
19+-- | The PSCI state.
20+--
21+-- Holds a list of imported modules, loaded files, and partial let bindings.
22+-- The let bindings are partial,
23+-- because it makes more sense to apply the binding to the final evaluated expression.
24+data PSCiState = PSCiState
25+ { psciImportedModules :: [ImportedModule]
26+ , psciLetBindings :: [P.Declaration]
27+ , psciLoadedExterns :: [(P.Module, P.ExternsFile)]
28+ } deriving Show
29+
30+initialPSCiState :: PSCiState
31+initialPSCiState = PSCiState [] [] []
32+
33+-- | All of the data that is contained by an ImportDeclaration in the AST.
34+-- That is:
35+--
36+-- * A module name, the name of the module which is being imported
37+-- * An ImportDeclarationType which specifies whether there is an explicit
38+-- import list, a hiding list, or neither.
39+-- * If the module is imported qualified, its qualified name in the importing
40+-- module. Otherwise, Nothing.
41+--
42+type ImportedModule = (P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)
43+
44+psciImportedModuleNames :: PSCiState -> [P.ModuleName]
45+psciImportedModuleNames (PSCiState{psciImportedModules = is}) =
46+ map (\(mn, _, _) -> mn) is
47+
48+allImportsOf :: P.Module -> PSCiState -> [ImportedModule]
49+allImportsOf m (PSCiState{psciImportedModules = is}) =
50+ filter isImportOfThis is
51+ where
52+ name = P.getModuleName m
53+ isImportOfThis (name', _, _) = name == name'
54+
55+-- * State helpers
56+
57+-- | Updates the imported modules in the state record.
58+updateImportedModules :: ([ImportedModule] -> [ImportedModule]) -> PSCiState -> PSCiState
59+updateImportedModules f st = st { psciImportedModules = f (psciImportedModules st) }
60+
61+-- | Updates the loaded externs files in the state record.
62+updateLoadedExterns :: ([(P.Module, P.ExternsFile)] -> [(P.Module, P.ExternsFile)]) -> PSCiState -> PSCiState
63+updateLoadedExterns f st = st { psciLoadedExterns = f (psciLoadedExterns st) }
64+
65+-- | Updates the let bindings in the state record.
66+updateLets :: ([P.Declaration] -> [P.Declaration]) -> PSCiState -> PSCiState
67+updateLets f st = st { psciLetBindings = f (psciLetBindings st) }
68+
69+-- * Commands
70+
71+-- |
72+-- Valid Meta-commands for PSCI
73+--
74+data Command
75+ -- |
76+ -- A purescript expression
77+ --
78+ = Expression P.Expr
79+ -- |
80+ -- Show the help (ie, list of directives)
81+ --
82+ | ShowHelp
83+ -- |
84+ -- Import a module from a loaded file
85+ --
86+ | Import ImportedModule
87+ -- |
88+ -- Browse a module
89+ --
90+ | BrowseModule P.ModuleName
91+ -- |
92+ -- Exit PSCI
93+ --
94+ | QuitPSCi
95+ -- |
96+ -- Reset the state of the REPL
97+ --
98+ | ResetState
99+ -- |
100+ -- Add some declarations to the current evaluation context.
101+ --
102+ | Decls [P.Declaration]
103+ -- |
104+ -- Find the type of an expression
105+ --
106+ | TypeOf P.Expr
107+ -- |
108+ -- Find the kind of an expression
109+ --
110+ | KindOf P.Type
111+ -- |
112+ -- Shows information about the current state of the REPL
113+ --
114+ | ShowInfo ReplQuery
115+
116+data ReplQuery
117+ = QueryLoaded
118+ | QueryImport
119+ deriving (Eq, Show)
120+
121+-- | A list of all ReplQuery values.
122+replQueries :: [ReplQuery]
123+replQueries = [QueryLoaded, QueryImport]
124+
125+replQueryStrings :: [String]
126+replQueryStrings = map showReplQuery replQueries
127+
128+showReplQuery :: ReplQuery -> String
129+showReplQuery QueryLoaded = "loaded"
130+showReplQuery QueryImport = "import"
131+
132+parseReplQuery :: String -> Maybe ReplQuery
133+parseReplQuery "loaded" = Just QueryLoaded
134+parseReplQuery "import" = Just QueryImport
135+parseReplQuery _ = Nothing
136+
137+data Directive
138+ = Help
139+ | Quit
140+ | Reset
141+ | Browse
142+ | Type
143+ | Kind
144+ | Show
145+ deriving (Eq, Show)
src/Language/PureScript/Kinds.hs+9−20
@@ -2,36 +2,25 @@
22
33module Language.PureScript.Kinds where
44
5−import Prelude ()
65import Prelude.Compat
76
87import qualified Data.Aeson.TH as A
98
10−-- |
11−-- The data type of kinds
12−--
9+-- | The data type of kinds
1310data Kind
14− -- |
15− -- Unification variable of type Kind
16− --
11+ -- | Unification variable of type Kind
1712 = KUnknown Int
18− -- |
19− -- The kind of types
20− --
13+ -- | The kind of types
2114 | Star
22− -- |
23− -- The kind of effects
24− --
15+ -- | The kind of effects
2516 | Bang
26− -- |
27− -- Kinds for labelled, unordered rows without duplicates
28− --
17+ -- | Kinds for labelled, unordered rows without duplicates
2918 | Row Kind
30− -- |
31− -- Function kinds
32− --
19+ -- | Function kinds
3320 | FunKind Kind Kind
34− deriving (Show, Read, Eq, Ord)
21+ -- | Type-level strings
22+ | Symbol
23+ deriving (Show, Eq, Ord)
3524
3625$(A.deriveJSON A.defaultOptions ''Kind)
3726
src/Language/PureScript/Linter.hs+6−23
@@ -1,30 +1,24 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE PatternGuards #-}
4−
51-- |
62-- This module implements a simple linting pass on the PureScript AST.
73--
84module Language.PureScript.Linter (lint, module L) where
95
10−import Prelude ()
116import Prelude.Compat
127
8+import Control.Monad.Writer.Class
9+
1310import Data.List (nub, (\\))
1411import Data.Maybe (mapMaybe)
1512import Data.Monoid
16−
1713import qualified Data.Set as S
1814
19−import Control.Monad.Writer.Class
20−
21−import Language.PureScript.Crash
2215import Language.PureScript.AST
23−import Language.PureScript.Names
16+import Language.PureScript.Crash
2417import Language.PureScript.Errors
25−import Language.PureScript.Types
2618import Language.PureScript.Linter.Exhaustive as L
2719import Language.PureScript.Linter.Imports as L
20+import Language.PureScript.Names
21+import Language.PureScript.Types
2822
2923-- | Lint the PureScript AST.
3024-- |
@@ -46,7 +40,7 @@ lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDecl
4640 lintDeclaration :: Declaration -> m ()
4741 lintDeclaration = tell . f
4842 where
49− (warningsInDecl, _, _, _, _) = everythingWithScope stepD stepE stepB (\_ _ -> mempty) stepDo
43+ (warningsInDecl, _, _, _, _) = everythingWithScope (\_ _ -> mempty) stepE stepB (\_ _ -> mempty) stepDo
5044
5145 f :: Declaration -> MultipleErrors
5246 f (PositionedDeclaration pos _ dec) = addHint (PositionedError pos) (f dec)
@@ -54,16 +48,6 @@ lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDecl
5448 f (TypeDeclaration name ty) = addHint (ErrorInTypeDeclaration name) (checkTypeVars ty)
5549 f dec = warningsInDecl moduleNames dec <> checkTypeVarsInDecl dec
5650
57− stepD :: S.Set Ident -> Declaration -> MultipleErrors
58− stepD _ (ValueDeclaration (Op name) _ _ _) = errorMessage (DeprecatedOperatorDecl name)
59− stepD _ (TypeClassDeclaration _ _ _ decls) = foldMap go decls
60− where
61− go :: Declaration -> MultipleErrors
62− go (PositionedDeclaration _ _ d') = go d'
63− go (TypeDeclaration (Op name) _) = errorMessage (DeprecatedOperatorDecl name)
64− go _ = mempty
65− stepD _ _ = mempty
66−
6751 stepE :: S.Set Ident -> Expr -> MultipleErrors
6852 stepE s (Abs (Left name) _) | name `S.member` s = errorMessage (ShadowedName name)
6953 stepE s (Let ds' _) = foldMap go ds'
@@ -71,7 +55,6 @@ lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDecl
7155 go d | Just i <- getDeclIdent d
7256 , i `S.member` s = errorMessage (ShadowedName i)
7357 | otherwise = mempty
74− stepE _ (OperatorSection op val) = errorMessage $ DeprecatedOperatorSection op val
7558 stepE _ _ = mempty
7659
7760 stepB :: S.Set Ident -> Binder -> MultipleErrors
src/Language/PureScript/Linter/Exhaustive.hs+110−79
@@ -1,36 +1,38 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41-- |
52-- Module for exhaustivity checking over pattern matching definitions
63-- The algorithm analyses the clauses of a definition one by one from top
74-- to bottom, where in each step it has the cases already missing (uncovered),
85-- and it generates the new set of missing cases.
96--
10−module Language.PureScript.Linter.Exhaustive (checkExhaustiveModule) where
7+module Language.PureScript.Linter.Exhaustive
8+ ( checkExhaustiveExpr
9+ ) where
1110
12−import Prelude ()
1311import Prelude.Compat
1412
15−import qualified Data.Map as M
16−import Data.Maybe (fromMaybe)
17−import Data.List (foldl', sortBy, nub)
18−import Data.Function (on)
19−
20−import Control.Monad (unless)
2113import Control.Applicative
2214import Control.Arrow (first, second)
15+import Control.Monad (unless)
2316import Control.Monad.Writer.Class
17+import Control.Monad.Supply.Class (MonadSupply, fresh, freshName)
18+
19+import Data.Function (on)
20+import Data.List (foldl', sortBy, nub)
21+import Data.Maybe (fromMaybe)
22+import qualified Data.Map as M
2423
25−import Language.PureScript.Crash
2624import Language.PureScript.AST.Binders
27−import Language.PureScript.AST.Literals
2825import Language.PureScript.AST.Declarations
26+import Language.PureScript.AST.Literals
27+import Language.PureScript.Crash
2928import Language.PureScript.Environment
30−import Language.PureScript.Names as P
29+import Language.PureScript.Errors
3130import Language.PureScript.Kinds
31+import Language.PureScript.Names as P
32+import Language.PureScript.Pretty.Values (prettyPrintBinderAtom)
33+import Language.PureScript.Traversals
3234import Language.PureScript.Types as P
33−import Language.PureScript.Errors
35+import qualified Language.PureScript.Constants as C
3436
3537-- | There are two modes of failure for the redundancy check:
3638--
@@ -44,7 +46,7 @@ data RedundancyError = Incomplete | Unknown
4446-- Qualifies a propername from a given qualified propername and a default module name
4547--
4648qualifyName
47− :: (ProperName a)
49+ :: ProperName a
4850 -> ModuleName
4951 -> Qualified (ProperName b)
5052 -> Qualified (ProperName a)
@@ -138,7 +140,7 @@ missingCasesSingle env mn (LiteralBinder (ObjectLiteral bs)) (LiteralBinder (Obj
138140 where
139141 fm = fromMaybe e
140142
141− compBS :: Eq a => b -> a -> Maybe b -> Maybe b -> (a, (b, b))
143+ compBS :: b -> a -> Maybe b -> Maybe b -> (a, (b, b))
142144 compBS e s b b' = (s, compB e b b')
143145
144146 (sortedNames, binders) = unzip $ genericMerge (compBS NullBinder) sbs sbs'
@@ -179,12 +181,11 @@ missingCasesSingle _ _ b _ = ([b], Left Unknown)
179181missingCasesMultiple :: Environment -> ModuleName -> [Binder] -> [Binder] -> ([[Binder]], Either RedundancyError Bool)
180182missingCasesMultiple env mn = go
181183 where
182− go [] [] = ([], pure True)
183184 go (x:xs) (y:ys) = (map (: xs) miss1 ++ map (x :) miss2, liftA2 (&&) pr1 pr2)
184185 where
185186 (miss1, pr1) = missingCasesSingle env mn x y
186187 (miss2, pr2) = go xs ys
187− go _ _ = internalError "Argument lengths did not match in missingCasesMultiple."
188+ go _ _ = ([], pure True)
188189
189190-- |
190191-- Guard handling
@@ -229,8 +230,16 @@ missingAlternative env mn ca uncovered
229230-- it partitions that set with the new uncovered cases, until it consumes the whole set of clauses.
230231-- Then, returns the uncovered set of case alternatives.
231232--
232−checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Bool -> Environment -> ModuleName -> Int -> [CaseAlternative] -> m ()
233−checkExhaustive hasConstraint env mn numArgs cas = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
233+checkExhaustive
234+ :: forall m
235+ . (MonadWriter MultipleErrors m, MonadSupply m)
236+ => Environment
237+ -> ModuleName
238+ -> Int
239+ -> [CaseAlternative]
240+ -> Expr
241+ -> m Expr
242+checkExhaustive env mn numArgs cas expr = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas
234243 where
235244 step :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Either RedundancyError Bool, [[Binder]]))
236245 step (uncovered, (nec, redundant)) ca =
@@ -246,69 +255,91 @@ checkExhaustive hasConstraint env mn numArgs cas = makeResult . first nub $ fold
246255 )
247256 )
248257
249− makeResult :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> m ()
258+ makeResult :: ([[Binder]], (Either RedundancyError Bool, [[Binder]])) -> m Expr
250259 makeResult (bss, (rr, bss')) =
251− do unless (hasConstraint || null bss) tellNonExhaustive
252− unless (null bss') tellRedundant
260+ do unless (null bss') tellRedundant
253261 case rr of
254− Left Incomplete -> unless hasConstraint tellIncomplete
262+ Left Incomplete -> tellIncomplete
255263 _ -> return ()
264+ if null bss
265+ then return expr
266+ else addPartialConstraint (second null (splitAt 5 bss)) expr
256267 where
257− tellNonExhaustive = tell . errorMessage . uncurry NotExhaustivePattern . second null . splitAt 5 $ bss
258− tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
259− tellIncomplete = tell . errorMessage $ IncompleteExhaustivityCheck
260−
261−-- |
262−-- Exhaustivity checking over a list of declarations
263−--
264−checkExhaustiveDecls :: forall m. MonadWriter MultipleErrors m => Environment -> ModuleName -> [Declaration] -> m ()
265−checkExhaustiveDecls env mn = mapM_ onDecl
266− where
267− onDecl :: Declaration -> m ()
268− onDecl (BindingGroupDeclaration bs) = mapM_ (onDecl . convert) bs
269− where
270− convert :: (Ident, NameKind, Expr) -> Declaration
271− convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
272− onDecl (ValueDeclaration name _ _ (Right e)) = censor (addHint (ErrorInValueDeclaration name)) (onExpr False e)
273− onDecl (PositionedDeclaration pos _ dec) = censor (addHint (PositionedError pos)) (onDecl dec)
274− onDecl _ = return ()
275−
276− onExpr :: Bool -> Expr -> m ()
277− onExpr isP (UnaryMinus e) = onExpr isP e
278− onExpr isP (Literal (ArrayLiteral es)) = mapM_ (onExpr isP) es
279− onExpr isP (Literal (ObjectLiteral es)) = mapM_ (onExpr isP . snd) es
280− onExpr isP (TypeClassDictionaryConstructorApp _ e) = onExpr isP e
281− onExpr isP (Accessor _ e) = onExpr isP e
282− onExpr isP (ObjectUpdate o es) = onExpr isP o >> mapM_ (onExpr isP . snd) es
283− onExpr isP (Abs _ e) = onExpr isP e
284− onExpr isP (App e1 e2) = onExpr isP e1 >> onExpr isP e2
285− onExpr isP (IfThenElse e1 e2 e3) = onExpr isP e1 >> onExpr isP e2 >> onExpr isP e3
286− onExpr isP (Case es cas) = checkExhaustive isP env mn (length es) cas >> mapM_ (onExpr isP) es >> mapM_ (onCaseAlternative isP) cas
287− onExpr isP (TypedValue _ e ty) = onExpr (isP || hasPartialConstraint ty) e
288− onExpr isP (Let ds e) = mapM_ onDecl ds >> onExpr isP e
289− onExpr isP (PositionedValue pos _ e) = censor (addHint (PositionedError pos)) (onExpr isP e)
290− onExpr _ _ = return ()
291−
292− onCaseAlternative :: Bool -> CaseAlternative -> m ()
293− onCaseAlternative isP (CaseAlternative _ (Left es)) = mapM_ (\(e, g) -> onExpr isP e >> onExpr isP g) es
294− onCaseAlternative isP (CaseAlternative _ (Right e)) = onExpr isP e
295−
296− hasPartialConstraint :: Type -> Bool
297− hasPartialConstraint (ConstrainedType cs _) = any (go . fst) cs
268+ tellRedundant = tell . errorMessage . uncurry OverlappingPattern . second null . splitAt 5 $ bss'
269+ tellIncomplete = tell . errorMessage $ IncompleteExhaustivityCheck
270+
271+ -- | We add a Partial constraint by adding a call to the following identity function:
272+ --
273+ -- partial :: forall a. Partial => a -> a
274+ --
275+ -- The binder information is provided so that it can be embedded in the constraint,
276+ -- and then included in the error message.
277+ addPartialConstraint :: ([[Binder]], Bool) -> Expr -> m Expr
278+ addPartialConstraint (bss, complete) e = do
279+ tyVar <- ("p" ++) . show <$> fresh
280+ var <- freshName
281+ return $
282+ Let
283+ [ partial var tyVar ]
284+ $ App (Var (Qualified Nothing (Ident C.__unused))) e
298285 where
299− go :: Qualified (ProperName 'ClassName) -> Bool
300− go qname
301− | qname == partialClass = True
302− | otherwise =
303− case qname `M.lookup` typeClasses env of
304− Just ([], _, cs') -> any (go . fst) cs'
305− _ -> False
306− partialClass :: Qualified (ProperName 'ClassName)
307− partialClass = primName "Partial"
308− hasPartialConstraint _ = False
286+ partial :: String -> String -> Declaration
287+ partial var tyVar =
288+ ValueDeclaration (Ident C.__unused) Private [] $ Right $
289+ TypedValue
290+ True
291+ (Abs (Left (Ident var)) (Var (Qualified Nothing (Ident var))))
292+ (ty tyVar)
293+
294+ ty :: String -> Type
295+ ty tyVar =
296+ ForAll tyVar
297+ ( ConstrainedType
298+ [ Constraint C.Partial [] (Just constraintData) ]
299+ $ TypeApp (TypeApp tyFunction (TypeVar tyVar)) (TypeVar tyVar)
300+ )
301+ Nothing
302+
303+ constraintData :: ConstraintData
304+ constraintData =
305+ PartialConstraintData (map (map prettyPrintBinderAtom) bss) complete
309306
310307-- |
311−-- Exhaustivity checking over a single module
308+-- Exhaustivity checking
312309--
313−checkExhaustiveModule :: forall m. MonadWriter MultipleErrors m => Environment -> Module -> m ()
314−checkExhaustiveModule env (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
310+checkExhaustiveExpr
311+ :: forall m
312+ . (MonadWriter MultipleErrors m, MonadSupply m)
313+ => Environment
314+ -> ModuleName
315+ -> Expr
316+ -> m Expr
317+checkExhaustiveExpr env mn = onExpr
318+ where
319+ onDecl :: Declaration -> m Declaration
320+ onDecl (BindingGroupDeclaration bs) = BindingGroupDeclaration <$> mapM (thirdM onExpr) bs
321+ onDecl (ValueDeclaration name x y (Right e)) = ValueDeclaration name x y . Right <$> censor (addHint (ErrorInValueDeclaration name)) (onExpr e)
322+ onDecl (PositionedDeclaration pos x dec) = PositionedDeclaration pos x <$> censor (addHint (PositionedError pos)) (onDecl dec)
323+ onDecl decl = return decl
324+
325+ onExpr :: Expr -> m Expr
326+ onExpr (UnaryMinus e) = UnaryMinus <$> onExpr e
327+ onExpr (Literal (ArrayLiteral es)) = Literal . ArrayLiteral <$> mapM onExpr es
328+ onExpr (Literal (ObjectLiteral es)) = Literal . ObjectLiteral <$> mapM (sndM onExpr) es
329+ onExpr (TypeClassDictionaryConstructorApp x e) = TypeClassDictionaryConstructorApp x <$> onExpr e
330+ onExpr (Accessor x e) = Accessor x <$> onExpr e
331+ onExpr (ObjectUpdate o es) = ObjectUpdate <$> onExpr o <*> mapM (sndM onExpr) es
332+ onExpr (Abs x e) = Abs x <$> onExpr e
333+ onExpr (App e1 e2) = App <$> onExpr e1 <*> onExpr e2
334+ onExpr (IfThenElse e1 e2 e3) = IfThenElse <$> onExpr e1 <*> onExpr e2 <*> onExpr e3
335+ onExpr (Case es cas) = do
336+ case' <- Case <$> mapM onExpr es <*> mapM onCaseAlternative cas
337+ checkExhaustive env mn (length es) cas case'
338+ onExpr (TypedValue x e y) = TypedValue x <$> onExpr e <*> pure y
339+ onExpr (Let ds e) = Let <$> mapM onDecl ds <*> onExpr e
340+ onExpr (PositionedValue pos x e) = PositionedValue pos x <$> censor (addHint (PositionedError pos)) (onExpr e)
341+ onExpr expr = return expr
342+
343+ onCaseAlternative :: CaseAlternative -> m CaseAlternative
344+ onCaseAlternative (CaseAlternative x (Left es)) = CaseAlternative x . Left <$> mapM (\(e, g) -> (,) <$> onExpr e <*> onExpr g) es
345+ onCaseAlternative (CaseAlternative x (Right e)) = CaseAlternative x . Right <$> onExpr e
src/Language/PureScript/Linter/Imports.hs+172−152
@@ -1,63 +1,37 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
41module Language.PureScript.Linter.Imports
52 ( lintImports
63 , Name(..)
74 , UsedImports()
85 ) where
96
10−import Prelude ()
117import Prelude.Compat
128
13−import Control.Monad (unless, when)
14−import Control.Monad.Error.Class (MonadError(..))
9+import Control.Monad (join, unless, foldM, (<=<))
1510import Control.Monad.Writer.Class
1611
17−import Data.Foldable (forM_)
18−import Data.List ((\\), find, intersect, nub)
19−import Data.Maybe (mapMaybe)
12+import Data.Function (on)
13+import Data.Foldable (for_)
14+import Data.List (find, intersect, nub, groupBy, sortBy, (\\))
15+import Data.Maybe (mapMaybe, fromMaybe)
2016import Data.Monoid (Sum(..))
17+import Data.Traversable (forM)
2118import qualified Data.Map as M
2219
2320import Language.PureScript.AST.Declarations
2421import Language.PureScript.AST.SourcePos
2522import Language.PureScript.Crash
26−import Language.PureScript.Names as P
27−
2823import Language.PureScript.Errors
24+import Language.PureScript.Names
25+import Language.PureScript.Sugar.Names.Common (warnDuplicateRefs)
2926import Language.PureScript.Sugar.Names.Env
3027import Language.PureScript.Sugar.Names.Imports
31−
3228import qualified Language.PureScript.Constants as C
3329
34−-- | Imported name used in some type or expression.
35−data Name
36− = IdentName (Qualified Ident)
37− | TyName (Qualified (ProperName 'TypeName))
38− | TyOpName (Qualified Ident)
39− | DctorName (Qualified (ProperName 'ConstructorName))
40− | TyClassName (Qualified (ProperName 'ClassName))
41− deriving (Eq, Show)
42−
43−getIdentName :: Maybe ModuleName -> Name -> Maybe Ident
44−getIdentName q (IdentName (Qualified q' name)) | q == q' = Just name
45−getIdentName _ _ = Nothing
46−
47−getTypeOpName :: Maybe ModuleName -> Name -> Maybe Ident
48−getTypeOpName q (TyOpName (Qualified q' name)) | q == q' = Just name
49−getTypeOpName _ _ = Nothing
50−
51−getTypeName :: Maybe ModuleName -> Name -> Maybe (ProperName 'TypeName)
52−getTypeName q (TyName (Qualified q' name)) | q == q' = Just name
53−getTypeName _ _ = Nothing
54−
55−getClassName :: Maybe ModuleName -> Name -> Maybe (ProperName 'ClassName)
56−getClassName q (TyClassName (Qualified q' name)) | q == q' = Just name
57−getClassName _ _ = Nothing
58−
59−-- | Map of module name to list of imported names from that module which have been used.
60−type UsedImports = M.Map ModuleName [Name]
30+-- |
31+-- Map of module name to list of imported names from that module which have
32+-- been used.
33+--
34+type UsedImports = M.Map ModuleName [Qualified Name]
6135
6236-- |
6337-- Find and warn on:
@@ -75,46 +49,79 @@ type UsedImports = M.Map ModuleName [Name]
7549--
7650lintImports
7751 :: forall m
78− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
52+ . MonadWriter MultipleErrors m
7953 => Module
8054 -> Env
8155 -> UsedImports
8256 -> m ()
83−lintImports (Module _ _ mn mdecls mexports) env usedImps = do
57+lintImports (Module _ _ _ _ Nothing) _ _ =
58+ internalError "lintImports needs desugared exports"
59+lintImports (Module ss _ mn mdecls (Just mexports)) env usedImps = do
60+
61+ -- TODO: this needs some work to be easier to understand
8462
85− let scope = maybe nullImports (\(_, imps, _) -> imps) (M.lookup mn env)
63+ let scope = maybe primImports (\(_, imps', _) -> imps') (M.lookup mn env)
8664 usedImps' = foldr (elaborateUsed scope) usedImps exportedModules
8765 numOpenImports = getSum $ foldMap (Sum . countOpenImports) mdecls
8866 allowImplicit = numOpenImports == 1
67+ imports = M.toAscList (findImports mdecls)
8968
90− imps <- M.toAscList <$> findImports mdecls
91−
92− forM_ imps $ \(mni, decls) ->
93− unless (isPrim mni) $ do
94− forM_ decls $ \(ss, declType, qualifierName) ->
95− censor (onErrorMessages $ addModuleLocError ss) $ do
69+ for_ imports $ \(mni, decls) ->
70+ unless (isPrim mni) $
71+ for_ decls $ \(ss', declType, qualifierName) ->
72+ maybe id warnWithPosition ss' $ do
9673 let names = nub $ M.findWithDefault [] mni usedImps'
9774 lintImportDecl env mni qualifierName names declType allowImplicit
9875
99− forM_ (M.toAscList (byQual imps)) $ \(mnq, entries) -> do
76+ for_ (M.toAscList (byQual imports)) $ \(mnq, entries) -> do
10077 let mnis = nub $ map (\(_, _, mni) -> mni) entries
10178 unless (length mnis == 1) $ do
10279 let implicits = filter (\(_, declType, _) -> not $ isExplicit declType) entries
103− forM_ implicits $ \(ss, _, mni) ->
104− censor (onErrorMessages $ addModuleLocError ss) $ do
80+ for_ implicits $ \(ss', _, mni) ->
81+ maybe id warnWithPosition ss' $ do
10582 let names = nub $ M.findWithDefault [] mni usedImps'
10683 usedRefs = findUsedRefs env mni (Just mnq) names
10784 unless (null usedRefs) $
10885 tell $ errorMessage $ ImplicitQualifiedImport mni mnq usedRefs
10986
110− return ()
87+ for_ imports $ \(mnq, imps) -> do
88+
89+ warned <- foldM (checkDuplicateImports mnq) [] (selfCartesianSubset imps)
90+
91+ let unwarned = imps \\ warned
92+ duplicates
93+ = join
94+ . map tail
95+ . filter ((> 1) . length)
96+ . groupBy ((==) `on` defQual)
97+ . sortBy (compare `on` defQual)
98+ $ unwarned
99+
100+ for_ duplicates $ \(pos, _, _) ->
101+ maybe id warnWithPosition pos $
102+ tell $ errorMessage $ DuplicateSelectiveImport mnq
103+
104+ for_ (imps \\ (warned ++ duplicates)) $ \(pos, typ, _) ->
105+ warnDuplicateRefs (fromMaybe ss pos) DuplicateImportRef $ case typ of
106+ Explicit refs -> refs
107+ Hiding refs -> refs
108+ _ -> []
111109
112110 where
113111
112+ defQual :: ImportDef -> Maybe ModuleName
113+ defQual (_, _, q) = q
114+
115+ selfCartesianSubset :: [a] -> [(a, a)]
116+ selfCartesianSubset (x : xs) = [(x, y) | y <- xs] ++ selfCartesianSubset xs
117+ selfCartesianSubset [] = []
118+
114119 countOpenImports :: Declaration -> Int
115− countOpenImports (ImportDeclaration mn' Implicit Nothing _) | not (isPrim mn') = 1
116− countOpenImports (ImportDeclaration mn' (Hiding _) Nothing _) | not (isPrim mn') = 1
117120 countOpenImports (PositionedDeclaration _ _ d) = countOpenImports d
121+ countOpenImports (ImportDeclaration mn' Implicit Nothing)
122+ | not (isPrim mn' || mn == mn') = 1
123+ countOpenImports (ImportDeclaration mn' (Hiding _) Nothing)
124+ | not (isPrim mn' || mn == mn') = 1
118125 countOpenImports _ = 0
119126
120127 -- Checks whether a module is the Prim module - used to suppress any checks
@@ -131,15 +138,15 @@ lintImports (Module _ _ mn mdecls mexports) env usedImps = do
131138 byQual = foldr goImp M.empty
132139 where
133140 goImp (mni, xs) acc = foldr (goDecl mni) acc xs
134− goDecl mni (ss, declType, Just qmn) acc =
135− let entry = (ss, declType, mni)
141+ goDecl mni (ss', declType, Just qmn) acc =
142+ let entry = (ss', declType, mni)
136143 in M.alter (Just . maybe [entry] (entry :)) qmn acc
137144 goDecl _ _ acc = acc
138145
139146 -- The list of modules that are being re-exported by the current module. Any
140147 -- module that appears in this list is always considered to be used.
141148 exportedModules :: [ModuleName]
142− exportedModules = nub $ maybe [] (mapMaybe extractModule) mexports
149+ exportedModules = nub $ mapMaybe extractModule mexports
143150 where
144151 extractModule (PositionedDeclarationRef _ _ r) = extractModule r
145152 extractModule (ModuleRef mne) = Just mne
@@ -150,52 +157,54 @@ lintImports (Module _ _ mn mdecls mexports) env usedImps = do
150157 -- that are implicitly exported and then re-exported.
151158 elaborateUsed :: Imports -> ModuleName -> UsedImports -> UsedImports
152159 elaborateUsed scope mne used =
153− let classes = extractByQual mne (importedTypeClasses scope) TyClassName
154− types = extractByQual mne (importedTypes scope) TyName
155− dctors = extractByQual mne (importedDataConstructors scope) DctorName
156− values = extractByQual mne (importedValues scope) IdentName
157− in foldr go used (classes ++ types ++ dctors ++ values)
160+ foldr go used
161+ $ extractByQual mne (importedTypeClasses scope) TyClassName
162+ ++ extractByQual mne (importedTypeOps scope) TyOpName
163+ ++ extractByQual mne (importedTypes scope) TyName
164+ ++ extractByQual mne (importedDataConstructors scope) DctorName
165+ ++ extractByQual mne (importedValues scope) IdentName
166+ ++ extractByQual mne (importedValueOps scope) ValOpName
158167 where
159− go :: (ModuleName, Name) -> UsedImports -> UsedImports
168+ go :: (ModuleName, Qualified Name) -> UsedImports -> UsedImports
160169 go (q, name) = M.alter (Just . maybe [name] (name :)) q
161170
162171 extractByQual
163− :: (Eq a)
164− => ModuleName
172+ :: ModuleName
165173 -> M.Map (Qualified a) [ImportRecord a]
166− -> (Qualified a -> Name)
167− -> [(ModuleName, Name)]
174+ -> (a -> Name)
175+ -> [(ModuleName, Qualified Name)]
168176 extractByQual k m toName = mapMaybe go (M.toList m)
169177 where
170178 go (q@(Qualified mnq _), is)
171179 | isUnqualified q =
172180 case find (isQualifiedWith k) (map importName is) of
173− Just (Qualified _ name) -> Just (k, toName $ Qualified mnq name)
181+ Just (Qualified _ name) -> Just (k, Qualified mnq (toName name))
174182 _ -> Nothing
175183 | isQualifiedWith k q =
176− case importName (head is) of
177− Qualified (Just mn') name -> Just (mn', toName $ Qualified mnq name)
178− _ -> internalError "unqualified name in extractByQual"
184+ case importName (head is) of
185+ Qualified (Just mn') name -> Just (mn', Qualified mnq (toName name))
186+ _ -> internalError "unqualified name in extractByQual"
179187 go _ = Nothing
180188
181189lintImportDecl
182190 :: forall m
183− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
191+ . MonadWriter MultipleErrors m
184192 => Env
185193 -> ModuleName
186194 -> Maybe ModuleName
187− -> [Name]
195+ -> [Qualified Name]
188196 -> ImportDeclarationType
189197 -> Bool
190− -> m ()
198+ -> m Bool
191199lintImportDecl env mni qualifierName names declType allowImplicit =
192200 case declType of
193201 Implicit -> case qualifierName of
194− Nothing -> unless allowImplicit (checkImplicit ImplicitImport)
195− Just q ->
196− let usedModuleNames = mapMaybe extractQualName names
197− in unless (q `elem` usedModuleNames) unused
198− Hiding _ -> unless allowImplicit (checkImplicit HidingImport)
202+ Nothing ->
203+ if null allRefs
204+ then unused
205+ else unless' allowImplicit (checkImplicit ImplicitImport)
206+ Just q -> unless' (q `elem` mapMaybe getQual names) unused
207+ Hiding _ -> unless' allowImplicit (checkImplicit HidingImport)
199208 Explicit [] -> unused
200209 Explicit declrefs -> checkExplicit declrefs
201210
@@ -203,82 +212,103 @@ lintImportDecl env mni qualifierName names declType allowImplicit =
203212
204213 checkImplicit
205214 :: (ModuleName -> [DeclarationRef] -> SimpleErrorMessage)
206− -> m ()
215+ -> m Bool
207216 checkImplicit warning =
208217 if null allRefs
209218 then unused
210− else tell $ errorMessage $ warning mni allRefs
219+ else warn (warning mni (map simplifyTypeRef allRefs))
220+ where
221+ -- Replace explicit type refs with data constructor lists from listing the
222+ -- used constructors explicity `T(X, Y, [...])` to `T(..)` for suggestion
223+ -- message.
224+ simplifyTypeRef :: DeclarationRef -> DeclarationRef
225+ simplifyTypeRef (TypeRef name (Just dctors))
226+ | not (null dctors) = TypeRef name Nothing
227+ simplifyTypeRef other = other
211228
212229 checkExplicit
213230 :: [DeclarationRef]
214− -> m ()
231+ -> m Bool
215232 checkExplicit declrefs = do
216233 let idents = nub (mapMaybe runDeclRef declrefs)
217− dctors = mapMaybe (matchDctor qualifierName) names
218− usedNames = mapMaybe (matchName (typeForDCtor mni) qualifierName) names
234+ dctors = mapMaybe (getDctorName <=< disqualifyFor qualifierName) names
235+ usedNames = mapMaybe (matchName (typeForDCtor mni) <=< disqualifyFor qualifierName) names
219236 diff = idents \\ usedNames
220− case (length diff, length idents) of
221− (0, _) -> return ()
237+
238+ didWarn <- case (length diff, length idents) of
239+ (0, _) -> return False
222240 (n, m) | n == m -> unused
223− _ -> tell $ errorMessage $ UnusedExplicitImport mni diff qualifierName allRefs
241+ _ -> warn (UnusedExplicitImport mni diff qualifierName allRefs)
224242
225− -- If we've not already warned a type is unused, check its data constructors
226− forM_ (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
243+ didWarn' <- forM (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
227244 let allCtors = dctorsForType mni tn
228− when (runProperName tn `elem` usedNames) $ case (c, dctors `intersect` allCtors) of
229− (_, []) | c /= Just [] ->
230− tell $ errorMessage $ UnusedDctorImport tn
231− (Just ctors, dctors') ->
232− let ddiff = ctors \\ dctors'
233− in unless (null ddiff) $ tell $ errorMessage $ UnusedDctorExplicitImport tn ddiff
234− _ -> return ()
235− return ()
236−
237− unused :: m ()
238− unused = tell $ errorMessage $ UnusedImport mni
245+ -- If we've not already warned a type is unused, check its data constructors
246+ unless' (runProperName tn `notElem` usedNames) $
247+ case (c, dctors `intersect` allCtors) of
248+ (_, []) | c /= Just [] -> warn (UnusedDctorImport tn)
249+ (Just ctors, dctors') ->
250+ let ddiff = ctors \\ dctors'
251+ in unless' (null ddiff) $ warn $ UnusedDctorExplicitImport tn ddiff
252+ _ -> return False
253+
254+ return (didWarn || or didWarn')
255+
256+ unused :: m Bool
257+ unused = warn (UnusedImport mni)
258+
259+ warn :: SimpleErrorMessage -> m Bool
260+ warn err = tell (errorMessage err) >> return True
261+
262+ -- Unless the boolean is true, run the action. Return false when the action is
263+ -- not run, otherwise return whatever the action does.
264+ --
265+ -- The return value is intended for cases where we want to track whether some
266+ -- work was done, as there may be further conditions in the action that mean
267+ -- it ends up doing nothing.
268+ unless' :: Bool -> m Bool -> m Bool
269+ unless' False m = m
270+ unless' True _ = return False
239271
240272 allRefs :: [DeclarationRef]
241273 allRefs = findUsedRefs env mni qualifierName names
242274
243275 dtys
244276 :: ModuleName
245− -> [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
246− dtys mn = maybe [] exportedTypes $ envModuleExports <$> mn `M.lookup` env
277+ -> M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
278+ dtys mn = maybe M.empty exportedTypes $ envModuleExports <$> mn `M.lookup` env
247279
248280 dctorsForType
249281 :: ModuleName
250282 -> ProperName 'TypeName
251283 -> [ProperName 'ConstructorName]
252− dctorsForType mn tn =
253− maybe [] getDctors (find matches $ dtys mn)
254− where
255− matches ((ty, _),_) = ty == tn
256− getDctors ((_,ctors),_) = ctors
284+ dctorsForType mn tn = maybe [] fst $ tn `M.lookup` dtys mn
257285
258286 typeForDCtor
259287 :: ModuleName
260288 -> ProperName 'ConstructorName
261289 -> Maybe (ProperName 'TypeName)
262− typeForDCtor mn pn =
263− getTy <$> find matches (dtys mn)
264− where
265− matches ((_, ctors), _) = pn `elem` ctors
266− getTy ((ty, _), _) = ty
290+ typeForDCtor mn pn = fst <$> find (elem pn . fst . snd) (M.toList (dtys mn))
267291
268−findUsedRefs :: Env -> ModuleName -> Maybe ModuleName -> [Name] -> [DeclarationRef]
269−findUsedRefs env mni qualifierName names =
292+findUsedRefs
293+ :: Env
294+ -> ModuleName
295+ -> Maybe ModuleName
296+ -> [Qualified Name]
297+ -> [DeclarationRef]
298+findUsedRefs env mni qn names =
270299 let
271− classRefs = TypeClassRef <$> mapMaybe (getClassName qualifierName) names
272− valueRefs = ValueRef <$> mapMaybe (getIdentName qualifierName) names
273− typeOpRefs = TypeOpRef <$> mapMaybe (getTypeOpName qualifierName) names
274− types = mapMaybe (getTypeName qualifierName) names
275− dctors = mapMaybe (matchDctor qualifierName) names
300+ classRefs = TypeClassRef <$> mapMaybe (getClassName <=< disqualifyFor qn) names
301+ valueRefs = ValueRef <$> mapMaybe (getIdentName <=< disqualifyFor qn) names
302+ valueOpRefs = ValueOpRef <$> mapMaybe (getValOpName <=< disqualifyFor qn) names
303+ typeOpRefs = TypeOpRef <$> mapMaybe (getTypeOpName <=< disqualifyFor qn) names
304+ types = mapMaybe (getTypeName <=< disqualifyFor qn) names
305+ dctors = mapMaybe (getDctorName <=< disqualifyFor qn) names
276306 typesWithDctors = reconstructTypeRefs dctors
277307 typesWithoutDctors = filter (`M.notMember` typesWithDctors) types
278308 typesRefs
279309 = map (flip TypeRef (Just [])) typesWithoutDctors
280310 ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
281− in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs
311+ in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs ++ valueOpRefs
282312
283313 where
284314
@@ -287,7 +317,8 @@ findUsedRefs env mni qualifierName names =
287317 -> M.Map (ProperName 'TypeName) [ProperName 'ConstructorName]
288318 reconstructTypeRefs = foldr accumDctors M.empty
289319 where
290− accumDctors dctor = M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
320+ accumDctors dctor =
321+ M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
291322
292323 findTypeForDctor
293324 :: ModuleName
@@ -296,32 +327,20 @@ findUsedRefs env mni qualifierName names =
296327 findTypeForDctor mn dctor =
297328 case mn `M.lookup` env of
298329 Just (_, _, exps) ->
299− case find (elem dctor . snd . fst) (exportedTypes exps) of
300− Just ((ty, _), _) -> ty
330+ case find (elem dctor . fst . snd) (M.toList (exportedTypes exps)) of
331+ Just (ty, _) -> ty
301332 Nothing -> internalError $ "missing type for data constructor " ++ runProperName dctor ++ " in findTypeForDctor"
302333 Nothing -> internalError $ "missing module " ++ runModuleName mn ++ " in findTypeForDctor"
303334
304335matchName
305336 :: (ProperName 'ConstructorName -> Maybe (ProperName 'TypeName))
306− -> Maybe ModuleName
307337 -> Name
308338 -> Maybe String
309−matchName _ qual (IdentName (Qualified q x)) | q == qual = Just $ showIdent x
310−matchName _ qual (TyName (Qualified q x)) | q == qual = Just $ runProperName x
311−matchName _ qual (TyClassName (Qualified q x)) | q == qual = Just $ runProperName x
312−matchName lookupDc qual (DctorName (Qualified q x)) | q == qual = runProperName <$> lookupDc x
313−matchName _ _ _ = Nothing
314−
315−extractQualName :: Name -> Maybe ModuleName
316−extractQualName (IdentName (Qualified q _)) = q
317−extractQualName (TyName (Qualified q _)) = q
318−extractQualName (TyOpName (Qualified q _)) = q
319−extractQualName (TyClassName (Qualified q _)) = q
320−extractQualName (DctorName (Qualified q _)) = q
321−
322−matchDctor :: Maybe ModuleName -> Name -> Maybe (ProperName 'ConstructorName)
323−matchDctor qual (DctorName (Qualified q x)) | q == qual = Just x
324−matchDctor _ _ = Nothing
339+matchName _ (IdentName x) = Just $ showIdent x
340+matchName _ (TyName x) = Just $ runProperName x
341+matchName _ (TyClassName x) = Just $ runProperName x
342+matchName lookupDc (DctorName x) = runProperName <$> lookupDc x
343+matchName _ _ = Nothing
325344
326345runDeclRef :: DeclarationRef -> Maybe String
327346runDeclRef (PositionedDeclarationRef _ _ ref) = runDeclRef ref
@@ -330,15 +349,16 @@ runDeclRef (TypeRef pn _) = Just $ runProperName pn
330349runDeclRef (TypeClassRef pn) = Just $ runProperName pn
331350runDeclRef _ = Nothing
332351
333−getTypeRef
334− :: DeclarationRef
335− -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
336−getTypeRef (PositionedDeclarationRef _ _ ref) = getTypeRef ref
337−getTypeRef (TypeRef pn x) = Just (pn, x)
338−getTypeRef _ = Nothing
339−
340−addModuleLocError :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
341−addModuleLocError sp err =
342− case sp of
343− Just pos -> withPosition pos err
344− _ -> err
352+checkDuplicateImports
353+ :: MonadWriter MultipleErrors m
354+ => ModuleName
355+ -> [ImportDef]
356+ -> (ImportDef, ImportDef)
357+ -> m [ImportDef]
358+checkDuplicateImports mn xs ((_, t1, q1), (pos, t2, q2)) =
359+ if t1 == t2 && q1 == q2
360+ then do
361+ maybe id warnWithPosition pos $
362+ tell $ errorMessage $ DuplicateImport mn t2 q2
363+ return $ (pos, t2, q2) : xs
364+ else return xs
src/Language/PureScript/Make.hs+79−84
@@ -1,10 +1,4 @@
1−{-# LANGUAGE FlexibleContexts #-}
21{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE TupleSections #-}
4−{-# LANGUAGE RankNTypes #-}
5−{-# LANGUAGE RecordWildCards #-}
6−{-# LANGUAGE ScopedTypeVariables #-}
7−{-# LANGUAGE MultiParamTypeClasses #-}
82{-# LANGUAGE TypeFamilies #-}
93
104module Language.PureScript.Make
@@ -20,59 +14,47 @@ module Language.PureScript.Make
2014 -- * Implementation of Make API using files on disk
2115 , Make(..)
2216 , runMake
17+ , makeIO
18+ , readTextFile
2319 , buildMakeActions
20+ , inferForeignModules
2421 ) where
2522
26−import Prelude ()
2723import Prelude.Compat
2824
29−import Control.Applicative ((<|>))
25+import Control.Concurrent.Lifted as C
3026import Control.Monad hiding (sequence)
27+import Control.Monad.Base (MonadBase(..))
3128import Control.Monad.Error.Class (MonadError(..))
32−import Control.Monad.Writer.Class (MonadWriter(..))
33−import Control.Monad.Trans.Class (MonadTrans(..))
34−import Control.Monad.Trans.Except
3529import Control.Monad.IO.Class
36−import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks)
3730import Control.Monad.Logger
31+import Control.Monad.Reader (MonadReader(..), ReaderT(..), asks)
3832import Control.Monad.Supply
39−import Control.Monad.Base (MonadBase(..))
33+import Control.Monad.Trans.Class (MonadTrans(..))
4034import Control.Monad.Trans.Control (MonadBaseControl(..))
35+import Control.Monad.Trans.Except
36+import Control.Monad.Writer.Class (MonadWriter(..))
4137
42−import Control.Concurrent.Lifted as C
43−
44−import Data.List (foldl', sort)
45−import Data.Maybe (fromMaybe, catMaybes, isJust)
38+import Data.Aeson (encode, decode)
39+import Data.ByteString.Builder (toLazyByteString, stringUtf8)
4640import Data.Either (partitionEithers)
47−import Data.Time.Clock
48−import Data.String (fromString)
4941import Data.Foldable (for_)
42+import Data.List (foldl', sort)
43+import Data.Maybe (fromMaybe, catMaybes)
44+import Data.String (fromString)
45+import Data.Time.Clock
5046import Data.Traversable (for)
5147import Data.Version (showVersion)
52−import Data.Aeson (encode, decode)
5348import qualified Data.ByteString.Lazy as B
5449import qualified Data.ByteString.UTF8 as BU8
55−import qualified Data.Set as S
5650import qualified Data.Map as M
51+import qualified Data.Set as S
5752
58−import qualified Text.Parsec as Parsec
59−
60−import SourceMap.Types
61−import SourceMap
62−
63−import System.Directory
64− (doesFileExist, getModificationTime, createDirectoryIfMissing, getCurrentDirectory)
65−import System.FilePath ((</>), takeDirectory, makeRelative, splitPath, normalise)
66−import System.IO.Error (tryIOError)
67−import System.IO.UTF8 (readUTF8File, writeUTF8File)
68−
69−import qualified Language.JavaScript.Parser as JS
70−
71−import Language.PureScript.Crash
7253import Language.PureScript.AST
73−import Language.PureScript.Externs
54+import Language.PureScript.Crash
7455import Language.PureScript.Environment
7556import Language.PureScript.Errors
57+import Language.PureScript.Externs
7658import Language.PureScript.Linter
7759import Language.PureScript.ModuleDependencies
7860import Language.PureScript.Names
@@ -82,18 +64,29 @@ import Language.PureScript.Pretty.Common(SMap(..))
8264import Language.PureScript.Renamer
8365import Language.PureScript.Sugar
8466import Language.PureScript.TypeChecker
85−import qualified Language.PureScript.Constants as C
67+import qualified Language.JavaScript.Parser as JS
8668import qualified Language.PureScript.Bundle as Bundle
87−import qualified Language.PureScript.Parser as PSParser
88−
8969import qualified Language.PureScript.CodeGen.JS as J
70+import qualified Language.PureScript.Constants as C
9071import qualified Language.PureScript.CoreFn as CF
72+import qualified Language.PureScript.Parser as PSParser
73+
9174import qualified Paths_purescript as Paths
9275
76+import SourceMap
77+import SourceMap.Types
78+
79+import System.Directory (doesFileExist, getModificationTime, createDirectoryIfMissing, getCurrentDirectory)
80+import System.FilePath ((</>), takeDirectory, makeRelative, splitPath, normalise, replaceExtension)
81+import System.IO.Error (tryIOError)
82+import System.IO.UTF8 (readUTF8File, writeUTF8File)
83+
84+import qualified Text.Parsec as Parsec
85+
9386-- | Progress messages from the make process
9487data ProgressMessage
9588 = CompilingModule ModuleName
96− deriving (Show, Read, Eq, Ord)
89+ deriving (Show, Eq, Ord)
9790
9891-- | Render a progress message
9992renderProgressMessage :: ProgressMessage -> String
@@ -107,31 +100,22 @@ renderProgressMessage (CompilingModule mn) = "Compiling " ++ runModuleName mn
107100--
108101-- * The details of how files are read/written etc.
109102--
110−data MakeActions m = MakeActions {
111− -- |
112− -- Get the timestamp for the input file(s) for a module. If there are multiple
113− -- files (.purs and foreign files, for example) the timestamp should be for
103+data MakeActions m = MakeActions
104+ { getInputTimestamp :: ModuleName -> m (Either RebuildPolicy (Maybe UTCTime))
105+ -- ^ Get the timestamp for the input file(s) for a module. If there are multiple
106+ -- files (@.purs@ and foreign files, for example) the timestamp should be for
114107 -- the most recently modified file.
115− --
116− getInputTimestamp :: ModuleName -> m (Either RebuildPolicy (Maybe UTCTime))
117− -- |
118− -- Get the timestamp for the output files for a module. This should be the
119− -- timestamp for the oldest modified file, or Nothing if any of the required
120− -- output files are missing.
121− --
122108 , getOutputTimestamp :: ModuleName -> m (Maybe UTCTime)
123− -- |
124− -- Read the externs file for a module as a string and also return the actual
125− -- path for the file.
109+ -- ^ Get the timestamp for the output files for a module. This should be the
110+ -- timestamp for the oldest modified file, or 'Nothing' if any of the required
111+ -- output files are missing.
126112 , readExterns :: ModuleName -> m (FilePath, Externs)
127− -- |
128− -- Run the code generator for the module and write any required output files.
129− --
113+ -- ^ Read the externs file for a module as a string and also return the actual
114+ -- path for the file.
130115 , codegen :: CF.Module CF.Ann -> Environment -> Externs -> SupplyT m ()
131− -- |
132− -- Respond to a progress update.
133− --
116+ -- ^ Run the code generator for the module and write any required output files.
134117 , progress :: ProgressMessage -> m ()
118+ -- ^ Respond to a progress update.
135119 }
136120
137121-- |
@@ -146,10 +130,10 @@ data RebuildPolicy
146130 -- | Never rebuild this module
147131 = RebuildNever
148132 -- | Always rebuild this module
149− | RebuildAlways deriving (Show, Read, Eq, Ord)
133+ | RebuildAlways deriving (Show, Eq, Ord)
150134
151135-- | Rebuild a single module
152−rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
136+rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
153137 => MakeActions m
154138 -> [ExternsFile]
155139 -> Module
@@ -157,11 +141,11 @@ rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options
157141rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
158142 progress $ CompilingModule moduleName
159143 let env = foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
160− lint m
161− ((checked@(Module ss coms _ elaborated exps), env'), nextVar) <- runSupplyT 0 $ do
162− [desugared] <- desugar externs [m]
144+ withPrim = importPrim m
145+ lint withPrim
146+ ((Module ss coms _ elaborated exps, env'), nextVar) <- runSupplyT 0 $ do
147+ [desugared] <- desugar externs [withPrim]
163148 runCheck' env $ typeCheckModule desugared
164− checkExhaustiveModule env' checked
165149 regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
166150 let mod' = Module ss coms moduleName regrouped exps
167151 corefn = CF.moduleToCoreFn env' mod'
@@ -176,14 +160,11 @@ rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
176160-- If timestamps have not changed, the externs file can be used to provide the module's types without
177161-- having to typecheck the module again.
178162--
179−make :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
163+make :: forall m. (Monad m, MonadBaseControl IO m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
180164 => MakeActions m
181165 -> [Module]
182− -> m Environment
166+ -> m [ExternsFile]
183167make ma@MakeActions{..} ms = do
184− requirePath <- asks optionsRequirePath
185− when (isJust requirePath) $ tell $ errorMessage DeprecatedRequirePath
186−
187168 checkModuleNamesAreUnique
188169
189170 (sorted, graph) <- sortModules ms
@@ -202,7 +183,7 @@ make ma@MakeActions{..} ms = do
202183
203184 -- Bundle up all the externs and return them as an Environment
204185 (_, externs) <- unzip . fromMaybe (internalError "make: externs were missing but no errors reported.") . sequence <$> for barriers (takeMVar . fst . snd)
205− return $ foldl' (flip applyExternsFileToEnvironment) initEnvironment externs
186+ return externs
206187
207188 where
208189 checkModuleNamesAreUnique :: m ()
@@ -272,7 +253,7 @@ make ma@MakeActions{..} ms = do
272253
273254 decodeExterns :: Externs -> Maybe ExternsFile
274255 decodeExterns bs = do
275− externs <- decode (fromString bs)
256+ externs <- decode (toLazyByteString (stringUtf8 bs))
276257 guard $ efVersion externs == showVersion Paths.version
277258 return externs
278259
@@ -304,10 +285,28 @@ makeIO f io = do
304285 e <- liftIO $ tryIOError io
305286 either (throwError . singleError . f) return e
306287
307−-- Traverse (Either e) instance (base 4.7)
308−traverseEither :: Applicative f => (a -> f b) -> Either e a -> f (Either e b)
309−traverseEither _ (Left x) = pure (Left x)
310−traverseEither f (Right y) = Right <$> f y
288+-- | Read a text file in the 'Make' monad, capturing any errors using the
289+-- 'MonadError' instance.
290+readTextFile :: FilePath -> Make String
291+readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
292+
293+-- | Infer the module name for a module by looking for the same filename with
294+-- a .js extension.
295+inferForeignModules
296+ :: forall m
297+ . MonadIO m
298+ => M.Map ModuleName (Either RebuildPolicy FilePath)
299+ -> m (M.Map ModuleName FilePath)
300+inferForeignModules = fmap (M.mapMaybe id) . traverse inferForeignModule
301+ where
302+ inferForeignModule :: Either RebuildPolicy FilePath -> m (Maybe FilePath)
303+ inferForeignModule (Left _) = return Nothing
304+ inferForeignModule (Right path) = do
305+ let jsFile = replaceExtension path "js"
306+ exists <- liftIO $ doesFileExist jsFile
307+ if exists
308+ then return (Just jsFile)
309+ else return Nothing
311310
312311-- |
313312-- A set of make actions that read and write modules from the given directory.
@@ -324,7 +323,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
324323 getInputTimestamp :: ModuleName -> Make (Either RebuildPolicy (Maybe UTCTime))
325324 getInputTimestamp mn = do
326325 let path = fromMaybe (internalError "Module has no filename in 'make'") $ M.lookup mn filePathMap
327− e1 <- traverseEither getTimestamp path
326+ e1 <- traverse getTimestamp path
328327 fPath <- maybe (return Nothing) getTimestamp $ M.lookup mn foreigns
329328 return $ fmap (max fPath) e1
330329
@@ -375,7 +374,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
375374 genSourceMap dir mapFile extraLines mappings = do
376375 let pathToDir = iterate (".." </>) ".." !! length (splitPath $ normalise outputDir)
377376 sourceFile = case mappings of
378− ((SMap file _ _):_) -> Just $ pathToDir </> makeRelative dir file
377+ (SMap file _ _ : _) -> Just $ pathToDir </> makeRelative dir file
379378 _ -> Nothing
380379 let rawMapping = SourceMapping { smFile = "index.js", smSourceRoot = Nothing, smMappings =
381380 map (\(SMap _ orig gen) -> Mapping {
@@ -414,9 +413,6 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
414413 progress :: ProgressMessage -> Make ()
415414 progress = liftIO . putStrLn . renderProgressMessage
416415
417−readTextFile :: FilePath -> Make String
418−readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
419−
420416-- |
421417-- Check that the declarations in a given PureScript module match with those
422418-- in its corresponding foreign module.
@@ -464,11 +460,10 @@ checkForeignDecls m path = do
464460 (errs, _) ->
465461 Left errs
466462
467− -- TODO: Handling for parenthesised operators should be removed after 0.9.
468463 -- We ignore the error message here, just being told it's an invalid
469464 -- identifier should be enough.
470465 parseIdent :: String -> Either String Ident
471− parseIdent str = try str <|> try ("(" ++ str ++ ")")
466+ parseIdent str = try str
472467 where
473468 try s = either (const (Left str)) Right $ do
474469 ts <- PSParser.lex "" s
src/Language/PureScript/ModuleDependencies.hs+16−12
@@ -1,12 +1,12 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−
31-- |
42-- Provides the ability to sort modules based on module dependencies
53--
6−module Language.PureScript.ModuleDependencies (
7− sortModules,
8− ModuleGraph
9−) where
4+module Language.PureScript.ModuleDependencies
5+ ( sortModules
6+ , ModuleGraph
7+ ) where
8+
9+import Prelude.Compat
1010
1111import Control.Monad.Error.Class (MonadError(..))
1212
@@ -14,11 +14,11 @@ import Data.Graph
1414import Data.List (nub)
1515import Data.Maybe (fromMaybe)
1616
17−import Language.PureScript.Crash
1817import Language.PureScript.AST
18+import Language.PureScript.Crash
19+import Language.PureScript.Errors
1920import Language.PureScript.Names
2021import Language.PureScript.Types
21−import Language.PureScript.Errors
2222
2323-- | A list of modules with their transitive dependencies
2424type ModuleGraph = [(ModuleName, [ModuleName])]
@@ -47,7 +47,7 @@ sortModules ms = do
4747 -- Extract module names that have been brought into scope by an `as` import.
4848 extractQualAs :: Declaration -> [ModuleName]
4949 extractQualAs (PositionedDeclaration _ _ d) = extractQualAs d
50− extractQualAs (ImportDeclaration _ _ (Just am) _) = [am]
50+ extractQualAs (ImportDeclaration _ _ (Just am)) = [am]
5151 extractQualAs _ = []
5252
5353-- |
@@ -65,12 +65,12 @@ usedModules ams d =
6565 where
6666
6767 forDecls :: Declaration -> [ModuleName]
68− forDecls (ImportDeclaration mn _ _ _) =
68+ forDecls (ImportDeclaration mn _ _) =
6969 -- Regardless of whether an imported module is qualified we still need to
7070 -- take into account its import to build an accurate list of dependencies.
7171 [mn]
72− forDecls (FixityDeclaration _ _ (Just (Qualified (Just mn) _)))
73− | mn `notElem` ams = [mn]
72+ forDecls (FixityDeclaration fd)
73+ | Just mn <- extractQualFixity fd, mn `notElem` ams = [mn]
7474 forDecls (TypeInstanceDeclaration _ _ (Qualified (Just mn) _) _ _)
7575 | mn `notElem` ams = [mn]
7676 forDecls _ = []
@@ -87,6 +87,10 @@ usedModules ams d =
8787 | mn `notElem` ams = [mn]
8888 forTypes _ = []
8989
90+ extractQualFixity :: Either ValueFixity TypeFixity -> Maybe ModuleName
91+ extractQualFixity (Left (ValueFixity _ (Qualified mn _) _)) = mn
92+ extractQualFixity (Right (TypeFixity _ (Qualified mn _) _)) = mn
93+
9094-- |
9195-- Convert a strongly connected component of the module graph to a module
9296--
src/Language/PureScript/Names.hs+82−20
@@ -1,19 +1,56 @@
1−{-# LANGUAGE DeriveFunctor #-}
21{-# LANGUAGE TemplateHaskell #-}
3−{-# LANGUAGE EmptyDataDecls #-}
4−{-# LANGUAGE KindSignatures #-}
52
63-- |
74-- Data types for names
85--
96module Language.PureScript.Names where
107
11−import Control.Monad (liftM)
8+import Prelude.Compat
9+
1210import Control.Monad.Supply.Class
1311
14−import Data.List
1512import Data.Aeson
1613import Data.Aeson.TH
14+import Data.List
15+
16+-- | A sum of the possible name types, useful for error and lint messages.
17+data Name
18+ = IdentName Ident
19+ | ValOpName (OpName 'ValueOpName)
20+ | TyName (ProperName 'TypeName)
21+ | TyOpName (OpName 'TypeOpName)
22+ | DctorName (ProperName 'ConstructorName)
23+ | TyClassName (ProperName 'ClassName)
24+ | ModName ModuleName
25+ deriving (Eq, Show)
26+
27+getIdentName :: Name -> Maybe Ident
28+getIdentName (IdentName name) = Just name
29+getIdentName _ = Nothing
30+
31+getValOpName :: Name -> Maybe (OpName 'ValueOpName)
32+getValOpName (ValOpName name) = Just name
33+getValOpName _ = Nothing
34+
35+getTypeName :: Name -> Maybe (ProperName 'TypeName)
36+getTypeName (TyName name) = Just name
37+getTypeName _ = Nothing
38+
39+getTypeOpName :: Name -> Maybe (OpName 'TypeOpName)
40+getTypeOpName (TyOpName name) = Just name
41+getTypeOpName _ = Nothing
42+
43+getDctorName :: Name -> Maybe (ProperName 'ConstructorName)
44+getDctorName (DctorName name) = Just name
45+getDctorName _ = Nothing
46+
47+getClassName :: Name -> Maybe (ProperName 'ClassName)
48+getClassName (TyClassName name) = Just name
49+getClassName _ = Nothing
50+
51+getModName :: Name -> Maybe ModuleName
52+getModName (ModName name) = Just name
53+getModName _ = Nothing
1754
1855-- |
1956-- Names for value identifiers
@@ -24,36 +61,50 @@ data Ident
2461 --
2562 = Ident String
2663 -- |
27− -- A symbolic name for an infix operator
28− --
29− | Op String
30− -- |
3164 -- A generated name for an identifier
3265 --
3366 | GenIdent (Maybe String) Integer
34− deriving (Show, Read, Eq, Ord)
67+ deriving (Show, Eq, Ord)
3568
3669runIdent :: Ident -> String
3770runIdent (Ident i) = i
38−runIdent (Op op) = op
3971runIdent (GenIdent Nothing n) = "$" ++ show n
4072runIdent (GenIdent (Just name) n) = "$" ++ name ++ show n
4173
4274showIdent :: Ident -> String
43−showIdent (Op op) = '(' : op ++ ")"
44−showIdent i = runIdent i
75+showIdent = runIdent
4576
46−freshIdent :: (MonadSupply m) => String -> m Ident
47−freshIdent name = liftM (GenIdent (Just name)) fresh
77+freshIdent :: MonadSupply m => String -> m Ident
78+freshIdent name = GenIdent (Just name) <$> fresh
4879
49−freshIdent' :: (MonadSupply m) => m Ident
50−freshIdent' = liftM (GenIdent Nothing) fresh
80+freshIdent' :: MonadSupply m => m Ident
81+freshIdent' = GenIdent Nothing <$> fresh
82+
83+-- |
84+-- Operator alias names.
85+--
86+newtype OpName (a :: OpNameType) = OpName { runOpName :: String }
87+ deriving (Show, Eq, Ord)
88+
89+instance ToJSON (OpName a) where
90+ toJSON = toJSON . runOpName
91+
92+instance FromJSON (OpName a) where
93+ parseJSON = fmap OpName . parseJSON
94+
95+showOp :: OpName a -> String
96+showOp op = '(' : runOpName op ++ ")"
97+
98+-- |
99+-- The closed set of operator alias types.
100+--
101+data OpNameType = ValueOpName | TypeOpName
51102
52103-- |
53104-- Proper names, i.e. capitalized names for e.g. module names, type//data constructors.
54105--
55106newtype ProperName (a :: ProperNameType) = ProperName { runProperName :: String }
56− deriving (Show, Read, Eq, Ord)
107+ deriving (Show, Eq, Ord)
57108
58109instance ToJSON (ProperName a) where
59110 toJSON = toJSON . runProperName
@@ -78,7 +129,7 @@ coerceProperName = ProperName . runProperName
78129-- Module names
79130--
80131newtype ModuleName = ModuleName [ProperName 'Namespace]
81− deriving (Show, Read, Eq, Ord)
132+ deriving (Show, Eq, Ord)
82133
83134runModuleName :: ModuleName -> String
84135runModuleName (ModuleName pns) = intercalate "." (runProperName `map` pns)
@@ -95,12 +146,15 @@ moduleNameFromString = ModuleName . splitProperNames
95146-- A qualified name, i.e. a name with an optional module name
96147--
97148data Qualified a = Qualified (Maybe ModuleName) a
98− deriving (Show, Read, Eq, Ord, Functor)
149+ deriving (Show, Eq, Ord, Functor)
99150
100151showQualified :: (a -> String) -> Qualified a -> String
101152showQualified f (Qualified Nothing a) = f a
102153showQualified f (Qualified (Just name) a) = runModuleName name ++ "." ++ f a
103154
155+getQual :: Qualified a -> Maybe ModuleName
156+getQual (Qualified mn _) = mn
157+
104158-- |
105159-- Provide a default module name, if a name is unqualified
106160--
@@ -118,6 +172,14 @@ mkQualified name mn = Qualified (Just mn) name
118172disqualify :: Qualified a -> a
119173disqualify (Qualified _ a) = a
120174
175+-- |
176+-- Remove the qualification from a value when it is qualified with a particular
177+-- module name.
178+--
179+disqualifyFor :: Maybe ModuleName -> Qualified a -> Maybe a
180+disqualifyFor mn (Qualified mn' a) | mn == mn' = Just a
181+disqualifyFor _ _ = Nothing
182+
121183-- |
122184-- Checks whether a qualified value is actually qualified with a module reference
123185--
src/Language/PureScript/Options.hs+3−16
@@ -1,20 +1,10 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Options
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
111-- |
122-- The data type of compiler options
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.Options where
175
6+import Prelude.Compat
7+
188-- |
199-- The data type of compiler options
2010--
@@ -38,9 +28,6 @@ data Options = Options {
3828 -- |
3929 -- Remove the comments from the generated js
4030 , optionsNoComments :: Bool
41− -- |
42− -- The path to prepend to require statements
43− , optionsRequirePath :: Maybe FilePath
4431 -- |
4532 -- Generate soure maps
4633 , optionsSourceMaps :: Bool
@@ -49,4 +36,4 @@ data Options = Options {
4936-- |
5037-- Default make options
5138defaultOptions :: Options
52−defaultOptions = Options False False Nothing False False False Nothing False
39+defaultOptions = Options False False Nothing False False False False
src/Language/PureScript/Parser.hs+23−36

This diff is too big to show here.

src/Language/PureScript/Parser/Common.hs+29−7

This diff is too big to show here.

src/Language/PureScript/Parser/Declarations.hs+116−112

This diff is too big to show here.

src/Language/PureScript/Parser/JS.hsdeleted−60

This diff is too big to show here.

src/Language/PureScript/Parser/Kinds.hs+6−16

This diff is too big to show here.

src/Language/PureScript/Parser/Lexer.hs+42−36

This diff is too big to show here.

src/Language/PureScript/Parser/State.hs+2−14

This diff is too big to show here.

src/Language/PureScript/Parser/Types.hs+25−15

This diff is too big to show here.

src/Language/PureScript/Pretty.hs+2−14

This diff is too big to show here.

src/Language/PureScript/Pretty/Common.hs+9−17

This diff is too big to show here.

src/Language/PureScript/Pretty/Cpp.hs+22−18

This diff is too big to show here.

src/Language/PureScript/Pretty/JS.hs+10−25

This diff is too big to show here.

src/Language/PureScript/Pretty/Kinds.hs+11−18

This diff is too big to show here.

src/Language/PureScript/Pretty/Types.hs+22−13

This diff is too big to show here.

src/Language/PureScript/Pretty/Values.hs+13−14

This diff is too big to show here.

src/Language/PureScript/Publish.hs+28−26

This diff is too big to show here.

src/Language/PureScript/Publish/BoxesHelpers.hs+3

This diff is too big to show here.

src/Language/PureScript/Publish/ErrorsWarnings.hs+31−27

This diff is too big to show here.

src/Language/PureScript/Publish/Utils.hs+41−38

This diff is too big to show here.

src/Language/PureScript/Renamer.hs−6

This diff is too big to show here.

src/Language/PureScript/Sugar.hs+16−27

This diff is too big to show here.

src/Language/PureScript/Sugar/BindingGroups.hs+19−25

This diff is too big to show here.

src/Language/PureScript/Sugar/CaseDeclarations.hs+18−21

This diff is too big to show here.

src/Language/PureScript/Sugar/DoNotation.hs+14−16

This diff is too big to show here.

src/Language/PureScript/Sugar/Names.hs+115−190

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Common.hsnew file+68

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Env.hs+209−88

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Exports.hs+157−156

This diff is too big to show here.

src/Language/PureScript/Sugar/Names/Imports.hs+91−180

This diff is too big to show here.

src/Language/PureScript/Sugar/ObjectWildcards.hs+7−10

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators.hs+211−128

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Binders.hs+4−5

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Common.hs+11−16

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Expr.hs+6−10

This diff is too big to show here.

src/Language/PureScript/Sugar/Operators/Types.hs+4−5

This diff is too big to show here.

src/Language/PureScript/Sugar/TypeClasses.hs+12−17

This diff is too big to show here.

src/Language/PureScript/Sugar/TypeClasses/Deriving.hs+38−35

This diff is too big to show here.

src/Language/PureScript/Sugar/TypeDeclarations.hs+28−38

This diff is too big to show here.

src/Language/PureScript/Traversals.hs+27−42

This diff is too big to show here.

src/Language/PureScript/TypeChecker.hs+67−116

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Entailment.hs+38−37

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Kinds.hs+10−14

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Monad.hs+72−35

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Rows.hs+8−27

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Skolems.hs+15−30

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Subsumption.hs+12−27

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Synonyms.hs+8−24

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Types.hs+90−96

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Unify.hs+38−50

This diff is too big to show here.

src/Language/PureScript/TypeClassDictionaries.hs+4−2

This diff is too big to show here.

src/Language/PureScript/Types.hs+63−76

This diff is too big to show here.

src/System/IO/UTF8.hs+2−2

This diff is too big to show here.

stack-ghc-8.0.yamlnew file+7

This diff is too big to show here.

stack-lts-5.yamldeleted−7

This diff is too big to show here.

stack-nightly.yamldeleted−6

This diff is too big to show here.

stack.yamlmode 120000 → 100644+9−1

This diff is too big to show here.

tests/Language/PureScript/Ide/FilterSpec.hs+21−32

This diff is too big to show here.

tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+17−35

This diff is too big to show here.

tests/Language/PureScript/Ide/ImportsSpec.hs+13−8

This diff is too big to show here.

tests/Language/PureScript/Ide/Integration.hs+113−80

This diff is too big to show here.

tests/Language/PureScript/Ide/MatcherSpec.hs+18−27

This diff is too big to show here.

tests/Language/PureScript/Ide/RebuildSpec.hs+18−23

This diff is too big to show here.

tests/Language/PureScript/Ide/ReexportsSpec.hs+54−68

This diff is too big to show here.

tests/Language/PureScript/Ide/SourceFile/IntegrationSpec.hsnew file+36

This diff is too big to show here.

tests/Language/PureScript/Ide/SourceFileSpec.hsnew file+46

This diff is too big to show here.

tests/Language/PureScript/IdeSpec.hsdeleted−35

This diff is too big to show here.

tests/Main.hs+4−1

This diff is too big to show here.

tests/TestCompiler.hs+187−95

This diff is too big to show here.

tests/TestDocs.hs+3−8

This diff is too big to show here.

tests/TestPscIde.hs+9−2

This diff is too big to show here.

tests/TestPscPublish.hs+2−2

This diff is too big to show here.

tests/TestPsci.hs+24−46

This diff is too big to show here.

tests/TestUtils.hs+53−19

This diff is too big to show here.

tests/support/bower.json+7−6

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Class.pursdeleted−24

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Console.jsdeleted−18

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Console.pursdeleted−18

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Unsafe.jsdeleted−8

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff-Unsafe.pursdeleted−10

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff.jsdeleted−62

This diff is too big to show here.

tests/support/flattened/Control-Monad-Eff.pursdeleted−67

This diff is too big to show here.

tests/support/flattened/Control-Monad-ST.jsdeleted−38

This diff is too big to show here.

tests/support/flattened/Control-Monad-ST.pursdeleted−42

This diff is too big to show here.

tests/support/flattened/Data-Function.jsdeleted−233

This diff is too big to show here.

tests/support/flattened/Data-Function.pursdeleted−113

This diff is too big to show here.

tests/support/flattened/Prelude.jsdeleted−228

This diff is too big to show here.

tests/support/flattened/Prelude.pursdeleted−872

This diff is too big to show here.

tests/support/flattened/Test-Assert.jsdeleted−27

This diff is too big to show here.

tests/support/flattened/Test-Assert.pursdeleted−46

This diff is too big to show here.

tests/support/package.json+2−1

This diff is too big to show here.

tests/support/preludedeleted−1

This diff is too big to show here.

tests/support/pscide/src/ImportsSpec.purs+1−3

This diff is too big to show here.

tests/support/pscide/src/Main.purs → tests/support/pscide/src/MatcherSpec.pursrenamed+1−1

This diff is too big to show here.

tests/support/pscide/src/RebuildSpecSingleModule.purs+1−1

This diff is too big to show here.

tests/support/pscide/src/RebuildSpecWithForeign.js−2

This diff is too big to show here.

tests/support/pscide/src/RebuildSpecWithHiddenIdent.pursnew file+6

This diff is too big to show here.

tests/support/pscide/src/SourceFileSpec.pursnew file+10

This diff is too big to show here.

tests/support/setup.jsdeleted−22

This diff is too big to show here.

travis/after.shdeleted−13

This diff is too big to show here.

travis/build.shnew file+59

This diff is too big to show here.

travis/configure.shdeleted−17

This diff is too big to show here.

travis/convert-os-name.shnew file+14

This diff is too big to show here.

travis/test-install.shdeleted−18

This diff is too big to show here.