git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #2169 from purescript/0.9

Merge 0.9 branch into master

commit3154b245e37868141dee04c6cb1269028df273c4 authorPhil Freeman <paf31@cantab.net> dateMon 30 May 2016, 21:13 (10 years ago) parent95727068fd0638
582 files changed+7511−8707
.gitmodules−3 .travis.yml+66−59 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/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 psc-bundle/Main.hs+1−11 psc-docs/Main.hs+1−1 psc-ide-server/Main.hs+15−23 psc-ide-server/PROTOCOL.md+26−16 psc-ide-server/README.md+1 psc/Main.hs+27−53 psci/Main.hs+132 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 purescript.cabal+227−109 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+3−1 src/Language/PureScript/AST/Declarations.hs+57−72 src/Language/PureScript/AST/Exported.hs+12−15 src/Language/PureScript/AST/Literals.hs+2−2 src/Language/PureScript/AST/Operators.hs+2 src/Language/PureScript/AST/SourcePos.hs−3 src/Language/PureScript/AST/Traversals.hs+8−25 src/Language/PureScript/Bundle.hs+58−53 src/Language/PureScript/CodeGen.hs+8−20 src/Language/PureScript/CodeGen/JS.hs+10−18 src/Language/PureScript/CodeGen/JS/AST.hs+1−2 src/Language/PureScript/CodeGen/JS/Common.hs+2−1 src/Language/PureScript/CodeGen/JS/Optimizer.hs+5−9 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+104−107 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+2 src/Language/PureScript/Constants.hs+30−8 src/Language/PureScript/CoreFn.hs+1−1 src/Language/PureScript/CoreFn/Ann.hs+25−37 src/Language/PureScript/CoreFn/Binders.hs+2−2 src/Language/PureScript/CoreFn/Desugar.hs+17−25 src/Language/PureScript/CoreFn/Expr.hs+3−3 src/Language/PureScript/CoreFn/Meta.hs+2 src/Language/PureScript/CoreFn/Module.hs+5−14 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+17−23 src/Language/PureScript/Docs/Convert.hs+11−13 src/Language/PureScript/Docs/Convert/ReExports.hs+81−67 src/Language/PureScript/Docs/Convert/Single.hs+16−52 src/Language/PureScript/Docs/ParseAndBookmark.hs+6−10 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+21−16 src/Language/PureScript/Errors.hs+352−405 src/Language/PureScript/Errors/JSON.hs+15−22 src/Language/PureScript/Externs.hs+39−21 src/Language/PureScript/Ide.hs+16−16 src/Language/PureScript/Ide/CaseSplit.hs−6 src/Language/PureScript/Ide/Command.hs+58−60 src/Language/PureScript/Ide/Error.hs+1 src/Language/PureScript/Ide/Externs.hs+35−24 src/Language/PureScript/Ide/Filter.hs−1 src/Language/PureScript/Ide/Imports.hs+15−23 src/Language/PureScript/Ide/Matcher.hs−1 src/Language/PureScript/Ide/Pursuit.hs−1 src/Language/PureScript/Ide/Rebuild.hs+116−35 src/Language/PureScript/Ide/Reexports.hs−2 src/Language/PureScript/Ide/SourceFile.hs+3−5 src/Language/PureScript/Ide/State.hs+102−57 src/Language/PureScript/Ide/Types.hs+6−7 src/Language/PureScript/Ide/Util.hs+28−10 src/Language/PureScript/Ide/Watcher.hs+21−27 src/Language/PureScript/Interactive.hs+283 psci/PSCi/Completion.hs → src/Language/PureScript/Interactive/Completion.hs+76−80 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+8−15 src/Language/PureScript/Interactive/Types.hs+146 src/Language/PureScript/Kinds.hs+8−19 src/Language/PureScript/Linter.hs+6−23 src/Language/PureScript/Linter/Exhaustive.hs+109−78 src/Language/PureScript/Linter/Imports.hs+172−151 src/Language/PureScript/Make.hs+73−79 src/Language/PureScript/ModuleDependencies.hs+16−12 src/Language/PureScript/Names.hs+78−16 src/Language/PureScript/Options.hs+3−16 src/Language/PureScript/Parser.hs+23−36 src/Language/PureScript/Parser/Common.hs+28−6 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+41−35 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+8−16 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−12 src/Language/PureScript/Publish.hs+26−25 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+17−20 src/Language/PureScript/Sugar/DoNotation.hs+14−16 src/Language/PureScript/Sugar/Names.hs+102−182 src/Language/PureScript/Sugar/Names/Common.hs+68 src/Language/PureScript/Sugar/Names/Env.hs+204−83 src/Language/PureScript/Sugar/Names/Exports.hs+156−154 src/Language/PureScript/Sugar/Names/Imports.hs+89−179 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+11−15 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+54−103 src/Language/PureScript/TypeChecker/Entailment.hs+20−21 src/Language/PureScript/TypeChecker/Kinds.hs+8−12 src/Language/PureScript/TypeChecker/Monad.hs+4−8 src/Language/PureScript/TypeChecker/Rows.hs+7−24 src/Language/PureScript/TypeChecker/Skolems.hs+14−29 src/Language/PureScript/TypeChecker/Subsumption.hs+9−25 src/Language/PureScript/TypeChecker/Synonyms.hs+8−24 src/Language/PureScript/TypeChecker/Types.hs+39−39 src/Language/PureScript/TypeChecker/Unify.hs+30−46 src/Language/PureScript/TypeClassDictionaries.hs+2 src/Language/PureScript/Types.hs+61−74 src/System/IO/UTF8.hs+2−2 stack-lts-5.yaml−7 stack-nightly.yaml−6 stack.yaml+8−1 tests/Language/PureScript/Ide/FilterSpec.hs+1−1 tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+5−12 tests/Language/PureScript/Ide/ImportsSpec.hs+8−3 tests/Language/PureScript/Ide/Integration.hs+59−22 tests/Language/PureScript/Ide/MatcherSpec.hs+9−17 tests/Language/PureScript/Ide/RebuildSpec.hs+8−17 tests/Language/PureScript/Ide/ReexportsSpec.hs+6−3 tests/Language/PureScript/IdeSpec.hs+1−1 tests/Main.hs+4−1 tests/TestCompiler.hs+187−95 tests/TestDocs.hs+3−8 tests/TestPscIde.hs+9−2 tests/TestPscPublish.hs+1−1 tests/TestPsci.hs+24−46 tests/TestUtils.hs+43−18 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/RebuildSpecWithHiddenIdent.purs+6 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
.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+66−59
@@ -1,73 +1,80 @@
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 COVERAGE=true 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-lts-sdist
25+ os: linux
26+ dist: trusty
27+ sudo: required
28+ env: BUILD_TYPE=sdist
29+
30+ - compiler: cc-linux-lts-haddock
31+ os: linux
32+ dist: trusty
33+ sudo: required
34+ env: BUILD_TYPE=haddock
35+
36+ - compiler: cc-osx-lts-normal
37+ os: osx
38+ env: BUILD_TYPE=normal DEPLOY=true
39+
40+ - compiler: cc-osx-lts-sdist
41+ os: osx
42+ env: BUILD_TYPE=sdist
43+addons:
44+ apt:
45+ packages:
46+ - libgmp-dev
47+cache:
48+ directories:
49+ - $HOME/.local/bin
50+ - $HOME/.stack
2551install:
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
52+- | # Install stack.
53+ if test ! -f "$HOME/.local/bin/stack"
54+ then
55+ URL="https://www.stackage.org/stack/$TRAVIS_OS_NAME-x86_64"
56+ curl --location "$URL" > stack.tar.gz
57+ gunzip stack.tar.gz
58+ tar -x -f stack.tar --strip-components 1
59+ mkdir -p "$HOME/.local/bin"
60+ mv stack "$HOME/.local/bin/"
61+ fi
62+- npm install -g bower # for psc-docs / psc-publish tests
63+# Fix the CC environment variable, because Travis changes it
64+- export CC=gcc
65+- export OS_NAME=$(./travis/convert-os-name.sh)
5066script:
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"
67+- travis/build.sh
68+before_deploy:
69+- ./bundle/build.sh $OS_NAME
6070deploy:
6171 provider: releases
6272 api_key: $RELEASE_KEY
6373 file:
64− - bundle/linux64.tar.gz
65− - bundle/linux64.sha
74+ - bundle/$OS_NAME.tar.gz
75+ - bundle/$OS_NAME.sha
6676 skip_cleanup: true
6777 on:
6878 all_branches: true
6979 tags: true
70− condition: "$DEPLOY = yes"
71−cache:
72− directories:
73− - ~/cabal-sandboxes
80+ condition: "$DEPLOY = true"
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/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−
psc-bundle/Main.hs+1−11
@@ -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
@@ -36,7 +35,6 @@ data Options = Options
3635 , optionsEntryPoints :: [String]
3736 , optionsMainModule :: Maybe String
3837 , optionsNamespace :: String
39− , optionsRequirePath :: Maybe FilePath
4038 } deriving Show
4139
4240-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
@@ -63,7 +61,7 @@ app Options{..} = do
6361
6462 let entryIds = map (`ModuleIdentifier` Regular) optionsEntryPoints
6563
66− bundle input entryIds optionsMainModule optionsNamespace optionsRequirePath
64+ bundle input entryIds optionsMainModule optionsNamespace
6765
6866-- | Command line options parser.
6967options :: Parser Options
@@ -72,7 +70,6 @@ options = Options <$> some inputFile
7270 <*> many entryPoint
7371 <*> optional mainModule
7472 <*> namespace
75− <*> optional requirePath
7673 where
7774 inputFile :: Parser FilePath
7875 inputFile = strArgument $
@@ -104,19 +101,12 @@ options = Options <$> some inputFile
104101 <> showDefault
105102 <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
106103
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−
113104-- | Make it go.
114105main :: IO ()
115106main = do
116107 hSetEncoding stdout utf8
117108 hSetEncoding stderr utf8
118109 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."
120110 output <- runExceptT (app opts)
121111 case output of
122112 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-server/Main.hs+15−23
@@ -12,7 +12,6 @@
1212-- The server accepting commands for psc-ide
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
1615{-# LANGUAGE FlexibleContexts #-}
1716{-# LANGUAGE MultiParamTypeClasses #-}
1817{-# LANGUAGE OverloadedStrings #-}
@@ -73,12 +72,13 @@ data Options = Options
7372 { optionsDirectory :: Maybe FilePath
7473 , optionsOutputPath :: FilePath
7574 , optionsPort :: PortID
75+ , optionsNoWatch :: Bool
7676 , optionsDebug :: Bool
7777 }
7878
7979main :: IO ()
8080main = do
81− Options dir outputPath port debug <- execParser opts
81+ Options dir outputPath port noWatch debug <- execParser opts
8282 maybe (pure ()) setCurrentDirectory dir
8383 serverState <- newTVarIO emptyPscIdeState
8484 cwd <- getCurrentDirectory
@@ -89,31 +89,23 @@ main = do
8989 (do putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
9090 createDirectory fullOutputPath
9191 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− )
92+ putStrLn "psc-ide needs you to compile your project (for example by running pulp build)")
9493
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− }
94+ unless noWatch $
95+ void (forkFinally (watcher serverState fullOutputPath) print)
96+
97+ let conf = Configuration {confDebug = debug, confOutputPath = outputPath}
98+ env = PscIdeEnvironment {envStateVar = serverState, envConfiguration = conf}
10899 startServer port env
109100 where
110101 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")
102+ Options
103+ <$> optional (strOption (long "directory" <> short 'd'))
104+ <*> strOption (long "output-directory" <> value "output/")
105+ <*> (PortNumber . fromIntegral <$>
106+ option auto (long "port" <> short 'p' <> value (4242 :: Integer)))
107+ <*> switch (long "no-watch")
108+ <*> switch (long "debug")
117109 opts = info (version <*> helper <*> parser) mempty
118110 version = abortOption
119111 (InfoMsg (showVersion Paths.version))
psc-ide-server/PROTOCOL.md+26−16
@@ -38,15 +38,17 @@ The `type` command looks up the type for a given identifier.
3838
3939**Params:**
4040 - `search :: String`: The identifier to look for. Only matches on equality.
41− - `filters :: [Filter]`: These filters will be applied before looking for the
41+ - `filters :: (optional) [Filter]`: These filters will be applied before looking for the
4242 identifier. These filters get combined with *AND*, so a candidate must match *ALL*
4343 of them to be eligible.
44+ - `currentModule :: (optional) String`: see *Complete* command
4445```json
4546{
4647 "command": "type",
4748 "params": {
4849 "search": "filterM",
49− "filters": [Filter]
50+ "filters": [{..}],
51+ "currentModule": "Main"
5052 }
5153}
5254```
@@ -58,20 +60,25 @@ The possible types are returned in the same format as completions
5860The `complete` command looks up possible completions/corrections.
5961
6062**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.
63+ - `filters :: [Filter]`: The same as for the `type` command. A candidate must
64+ match all filters.
65+ - `matcher :: (optional) Matcher`: The strategy used for matching candidates
66+ after filtering. Results are scored internally and will be returned in the
67+ descending order where the nth element is better then the n+1-th.
68+ - `currentModule :: (optional) String`: The current modules name. If it matches
69+ with the rebuild cache non-exported modules will also be completed. You can
70+ fill the rebuild cache by using the "Rebuild" command.
71+
72+ If no matcher is given every candidate, that passes the filters, is returned
73+ in no particular order.
74+
6975```json
7076{
7177 "command": "complete",
7278 "params": {
73− "filters": [Filter],
74− "matcher": (optional) Matcher
79+ "filters": [{..}, {..}],
80+ "matcher": {..}
81+ "currentModule": "Main"
7582 }
7683}
7784```
@@ -244,10 +251,11 @@ Example:
244251
245252The `rebuild` command provides a fast rebuild for a single module. It doesn't
246253recompile the entire project though. All the modules dependencies need to be
247−loaded.
254+loaded. A successful rebuild will be stored to allow for completions of private
255+identifiers.
248256
249257Arguments:
250−- `file :: String` the path to the module to rebuild
258+ - `file :: String` the path to the module to rebuild
251259
252260```json
253261{
@@ -407,14 +415,16 @@ Hiding Import(`import Data.Array hiding (filter, filterM, join)`):
407415 }
408416]
409417```
410−### Cwd/Quit
418+### Cwd/Quit/Reset
411419`cwd` returns the working directory of the server(should be your project root).
412420
413421`quit` quits the server.
414422
423+`reset` resets all loaded modules.
424+
415425```json
416426{
417− "command": "cwd|quit"
427+ "command": "cwd|quit|reset"
418428}
419429```
420430
psc-ide-server/README.md+1
@@ -20,6 +20,7 @@ It supports the following options:
2020 project directory. Defaults to `output/`, relative to either the current
2121 directory or the directory specified by `-d`.
2222- `--debug`: Enables some logging meant for debugging
23+- `--no-watch`: Disables the filewatcher
2324- `--version`: Output psc-ide version
2425
2526## 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+132
@@ -0,0 +1,132 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE DoAndIfThenElse #-}
3+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4+{-# LANGUAGE MultiParamTypeClasses #-}
5+{-# LANGUAGE RecordWildCards #-}
6+{-# LANGUAGE ScopedTypeVariables #-}
7+{-# LANGUAGE TupleSections #-}
8+
9+module Main (main) where
10+
11+import Prelude ()
12+import Prelude.Compat
13+
14+import Data.Monoid ((<>))
15+import Data.Version (showVersion)
16+
17+import Control.Applicative (many)
18+import Control.Monad
19+import Control.Monad.IO.Class (liftIO)
20+import Control.Monad.Trans.Class
21+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
22+import Control.Monad.Trans.State.Strict (StateT, evalStateT)
23+import Control.Monad.Trans.Reader (ReaderT, runReaderT)
24+
25+import qualified Language.PureScript as P
26+import Language.PureScript.Interactive
27+
28+import qualified Options.Applicative as Opts
29+
30+import qualified Paths_purescript as Paths
31+
32+import System.Console.Haskeline
33+import System.Exit
34+import System.FilePath.Glob (glob)
35+
36+-- | Command line options
37+data PSCiOptions = PSCiOptions
38+ { psciMultiLineMode :: Bool
39+ , psciInputFile :: [FilePath]
40+ , psciInputNodeFlags :: [String]
41+ }
42+
43+multiLineMode :: Opts.Parser Bool
44+multiLineMode = Opts.switch $
45+ Opts.long "multi-line-mode"
46+ <> Opts.short 'm'
47+ <> Opts.help "Run in multi-line mode (use ^D to terminate commands)"
48+
49+inputFile :: Opts.Parser FilePath
50+inputFile = Opts.strArgument $
51+ Opts.metavar "FILE"
52+ <> Opts.help "Optional .purs files to load on start"
53+
54+nodeFlagsFlag :: Opts.Parser [String]
55+nodeFlagsFlag = Opts.option parser $
56+ Opts.long "node-opts"
57+ <> Opts.metavar "NODE_OPTS"
58+ <> Opts.value []
59+ <> Opts.help "Flags to pass to node, separated by spaces"
60+ where
61+ parser = words <$> Opts.str
62+
63+psciOptions :: Opts.Parser PSCiOptions
64+psciOptions = PSCiOptions <$> multiLineMode
65+ <*> many inputFile
66+ <*> nodeFlagsFlag
67+
68+version :: Opts.Parser (a -> a)
69+version = Opts.abortOption (Opts.InfoMsg (showVersion Paths.version)) $
70+ Opts.long "version" <>
71+ Opts.help "Show the version number" <>
72+ Opts.hidden
73+
74+getOpt :: IO PSCiOptions
75+getOpt = Opts.execParser opts
76+ where
77+ opts = Opts.info (version <*> Opts.helper <*> psciOptions) infoModList
78+ infoModList = Opts.fullDesc <> headerInfo <> footerInfo
79+ headerInfo = Opts.header "psci - Interactive mode for PureScript"
80+ footerInfo = Opts.footer $ "psci " ++ showVersion Paths.version
81+
82+-- | Parses the input and returns either a command, or an error as a 'String'.
83+getCommand :: forall m. MonadException m => Bool -> InputT m (Either String (Maybe Command))
84+getCommand singleLineMode = handleInterrupt (return (Right Nothing)) $ do
85+ firstLine <- withInterrupt $ getInputLine "> "
86+ case firstLine of
87+ Nothing -> return (Right (Just QuitPSCi)) -- Ctrl-D when input is empty
88+ Just "" -> return (Right Nothing)
89+ Just s | singleLineMode || head s == ':' -> return . fmap Just $ parseCommand s
90+ Just s -> fmap Just . parseCommand <$> go [s]
91+ where
92+ go :: [String] -> InputT m String
93+ go ls = maybe (return . unlines $ reverse ls) (go . (:ls)) =<< getInputLine " "
94+
95+-- | Get command line options and drop into the REPL
96+main :: IO ()
97+main = getOpt >>= loop
98+ where
99+ loop :: PSCiOptions -> IO ()
100+ loop PSCiOptions{..} = do
101+ inputFiles <- concat <$> traverse glob psciInputFile
102+ e <- runExceptT $ do
103+ modules <- ExceptT (loadAllModules inputFiles)
104+ unless (supportModuleIsDefined (map snd modules)) . liftIO $ do
105+ putStrLn supportModuleMessage
106+ exitFailure
107+ (externs, env) <- ExceptT . runMake . make $ modules
108+ return (modules, externs, env)
109+ case e of
110+ Left errs -> putStrLn (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure
111+ Right (modules, externs, env) -> do
112+ historyFilename <- getHistoryFilename
113+ let settings = defaultSettings { historyFile = Just historyFilename }
114+ initialState = PSCiState [] [] (zip (map snd modules) externs)
115+ config = PSCiConfig inputFiles psciInputNodeFlags env
116+ runner = flip runReaderT config
117+ . flip evalStateT initialState
118+ . runInputT (setComplete completion settings)
119+ putStrLn prologueMessage
120+ runner go
121+ where
122+ go :: InputT (StateT PSCiState (ReaderT PSCiConfig IO)) ()
123+ go = do
124+ c <- getCommand (not psciMultiLineMode)
125+ case c of
126+ Left err -> outputStrLn err >> go
127+ Right Nothing -> go
128+ Right (Just QuitPSCi) -> outputStrLn quitMessage
129+ Right (Just c') -> do
130+ handleInterrupt (outputStrLn "Interrupted.")
131+ (withInterrupt (lift (handleCommand c')))
132+ 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
purescript.cabal+227−109
@@ -1,5 +1,5 @@
11name: purescript
2−version: 0.8.5.0
2+version: 0.9.1
33cabal-version: >=1.8
44build-type: Simple
55license: MIT
@@ -20,27 +20,73 @@ 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
2882 , 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
3383 , tests/support/bower.json
3484 , tests/support/setup-win.cmd
35− , tests/support/flattened/*.purs
36− , tests/support/flattened/*.js
3785 , tests/support/psci/*.purs
3886 , tests/support/pscide/src/*.purs
3987 , tests/support/pscide/src/*.js
4088 , tests/support/pscide/src/*.fail
4189 , stack.yaml
42− , stack-lts-5.yaml
43− , stack-nightly.yaml
4490 , README.md
4591 , INSTALL.md
4692 , CONTRIBUTORS.md
@@ -52,47 +98,49 @@ source-repository head
5298
5399library
54100 build-depends: base >=4.8 && <5,
101+ aeson >= 0.8 && < 0.12,
102+ aeson-better-errors >= 0.8,
103+ ansi-terminal >= 0.6.2 && < 0.7,
55104 base-compat >=0.6.0,
56− lifted-base >= 0.2.3 && < 0.2.4,
57− monad-control >= 1.0.0.0 && < 1.1,
58− transformers-base >= 0.4.0 && < 0.5,
105+ bower-json >= 0.8,
106+ boxes >= 0.1.4 && < 0.2.0,
107+ bytestring -any,
59108 containers -any,
60− unordered-containers -any,
61− dlist -any,
62109 directory >= 1.2,
110+ dlist -any,
111+ edit-distance -any,
63112 filepath -any,
113+ fsnotify >= 0.2.1,
114+ Glob >= 0.7 && < 0.8,
115+ haskeline >= 0.7.0.0,
116+ http-types -any,
117+ language-javascript == 0.6.*,
118+ lifted-base >= 0.2.3 && < 0.2.4,
119+ monad-control >= 1.0.0.0 && < 1.1,
120+ monad-logger >= 0.3 && < 0.4,
64121 mtl >= 2.1.0 && < 2.3.0,
65− parsec -any,
66− transformers >= 0.3.0 && < 0.6,
67− transformers-compat >= 0.3.0,
68− utf8-string >= 1 && < 2,
122+ parallel >= 3.2 && < 3.3,
123+ parsec >=3.1.10,
69124 pattern-arrows >= 0.0.2 && < 0.1,
70− time -any,
71− boxes >= 0.1.4 && < 0.2.0,
72− aeson >= 0.8 && < 0.12,
73− vector -any,
74− bower-json >= 0.8,
75− aeson-better-errors >= 0.8,
76− bytestring -any,
77− text -any,
78− split -any,
79− language-javascript == 0.6.*,
80− syb -any,
81− Glob >= 0.7 && < 0.8,
125+ pipes >= 4.0.0 && < 4.2.0,
126+ pipes-http -any,
82127 process >= 1.2.0 && < 1.5,
128+ regex-tdfa -any,
83129 safe >= 0.3.9 && < 0.4,
84130 semigroups >= 0.16.2 && < 0.19,
85− parallel >= 3.2 && < 3.3,
86131 sourcemap >= 0.1.6,
132+ spdx == 0.2.*,
133+ split -any,
87134 stm >= 0.2.4.0,
88− regex-tdfa -any,
89− edit-distance -any,
90− fsnotify >= 0.2.1,
91− monad-logger >= 0.3 && < 0.4,
92− pipes >= 4.0.0 && < 4.2.0 ,
93− pipes-http -any,
94− http-types -any,
95− spdx == 0.2.*
135+ syb -any,
136+ text -any,
137+ time -any,
138+ transformers >= 0.3.0 && < 0.6,
139+ transformers-base >= 0.4.0 && < 0.5,
140+ transformers-compat >= 0.3.0,
141+ unordered-containers -any,
142+ utf8-string >= 1 && < 2,
143+ vector -any
96144
97145 exposed-modules: Language.PureScript
98146 Language.PureScript.AST
@@ -142,7 +190,6 @@ library
142190 Language.PureScript.Parser.Lexer
143191 Language.PureScript.Parser.Common
144192 Language.PureScript.Parser.Declarations
145− Language.PureScript.Parser.JS
146193 Language.PureScript.Parser.Kinds
147194 Language.PureScript.Parser.State
148195 Language.PureScript.Parser.Types
@@ -158,9 +205,10 @@ library
158205 Language.PureScript.Sugar.CaseDeclarations
159206 Language.PureScript.Sugar.DoNotation
160207 Language.PureScript.Sugar.Names
208+ Language.PureScript.Sugar.Names.Common
161209 Language.PureScript.Sugar.Names.Env
162− Language.PureScript.Sugar.Names.Imports
163210 Language.PureScript.Sugar.Names.Exports
211+ Language.PureScript.Sugar.Names.Imports
164212 Language.PureScript.Sugar.ObjectWildcards
165213 Language.PureScript.Sugar.Operators
166214 Language.PureScript.Sugar.Operators.Common
@@ -220,13 +268,38 @@ library
220268 Language.PureScript.Ide.Util
221269 Language.PureScript.Ide.Rebuild
222270
271+ Language.PureScript.Interactive
272+ Language.PureScript.Interactive.Types
273+ Language.PureScript.Interactive.Parser
274+ Language.PureScript.Interactive.Directive
275+ Language.PureScript.Interactive.Completion
276+ Language.PureScript.Interactive.IO
277+ Language.PureScript.Interactive.Message
278+ Language.PureScript.Interactive.Module
279+ Language.PureScript.Interactive.Printer
280+
223281 Control.Monad.Logger
224282 Control.Monad.Supply
225283 Control.Monad.Supply.Class
226284
227285 System.IO.UTF8
228286
229− extensions: DataKinds
287+ extensions: ConstraintKinds
288+ DataKinds
289+ DeriveFunctor
290+ EmptyDataDecls
291+ FlexibleContexts
292+ KindSignatures
293+ LambdaCase
294+ MultiParamTypeClasses
295+ NoImplicitPrelude
296+ PatternGuards
297+ PatternSynonyms
298+ RankNTypes
299+ RecordWildCards
300+ ScopedTypeVariables
301+ TupleSections
302+ ViewPatterns
230303 exposed: True
231304 buildable: True
232305 hs-source-dirs: src
@@ -234,11 +307,23 @@ library
234307 ghc-options: -Wall -O2
235308
236309executable psc
237− build-depends: base >=4 && <5, base-compat >=0.6.0,
238− containers -any, directory -any, filepath -any,
239− mtl -any, optparse-applicative >= 0.12.1, parsec -any, purescript -any,
240− time -any, transformers -any, transformers-compat -any, Glob >= 0.7 && < 0.8,
241− aeson >= 0.8 && < 0.12, bytestring -any, utf8-string >= 1 && < 2
310+ build-depends: base >=4 && <5,
311+ purescript -any,
312+ aeson >= 0.8 && < 0.12,
313+ ansi-terminal >= 0.6.2 && < 0.7,
314+ base-compat >=0.6.0,
315+ bytestring -any,
316+ containers -any,
317+ directory -any,
318+ filepath -any,
319+ Glob >= 0.7 && < 0.8,
320+ mtl -any,
321+ optparse-applicative >= 0.12.1,
322+ parsec -any,
323+ time -any,
324+ transformers -any,
325+ transformers-compat -any,
326+ utf8-string >= 1 && < 2
242327 main-is: Main.hs
243328 buildable: True
244329 hs-source-dirs: psc
@@ -246,33 +331,40 @@ executable psc
246331 ghc-options: -Wall -O2 -fno-warn-unused-do-bind -threaded -rtsopts "-with-rtsopts=-N"
247332
248333executable psci
249− build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
250− mtl -any, optparse-applicative >= 0.12.1, parsec -any,
251− haskeline >= 0.7.0.0, purescript -any, transformers -any,
252− transformers-compat -any, process -any, time -any, Glob -any, base-compat >=0.6.0,
253− boxes >= 0.1.4 && < 0.2.0
254−
334+ build-depends: base >=4 && <5,
335+ purescript -any,
336+ base-compat >=0.6.0,
337+ boxes >= 0.1.4 && < 0.2.0,
338+ containers -any,
339+ directory -any,
340+ filepath -any,
341+ Glob -any,
342+ haskeline >= 0.7.0.0,
343+ mtl -any,
344+ optparse-applicative >= 0.12.1,
345+ parsec -any,
346+ process -any,
347+ time -any,
348+ transformers -any,
349+ transformers-compat -any
255350 main-is: Main.hs
256351 buildable: True
257− hs-source-dirs: psci psci/main
258− other-modules: PSCi
259− PSCi.Types
260− PSCi.Parser
261− PSCi.Directive
262− PSCi.Completion
263− PSCi.IO
264− PSCi.Message
265− PSCi.Option
266− PSCi.Module
267− PSCi.Printer
268− Paths_purescript
352+ hs-source-dirs: psci
353+ other-modules: Paths_purescript
269354 ghc-options: -Wall -O2
270355
271356executable psc-docs
272− build-depends: base >=4 && <5, purescript -any,
273− optparse-applicative >= 0.12.1, process -any, mtl -any,
274− split -any, ansi-wl-pprint -any, directory -any,
275− filepath -any, Glob -any, transformers -any,
357+ build-depends: base >=4 && <5,
358+ purescript -any,
359+ ansi-wl-pprint -any,
360+ directory -any,
361+ filepath -any,
362+ Glob -any,
363+ mtl -any,
364+ optparse-applicative >= 0.12.1,
365+ process -any,
366+ split -any,
367+ transformers -any,
276368 transformers-compat -any
277369 main-is: Main.hs
278370 other-modules: Paths_purescript
@@ -284,7 +376,11 @@ executable psc-docs
284376 ghc-options: -Wall -O2
285377
286378executable psc-publish
287− build-depends: base >=4 && <5, purescript -any, bytestring -any, aeson -any, optparse-applicative -any
379+ build-depends: base >=4 && <5,
380+ purescript -any,
381+ aeson -any,
382+ bytestring -any,
383+ optparse-applicative -any
288384 main-is: Main.hs
289385 other-modules: Paths_purescript
290386 buildable: True
@@ -292,9 +388,15 @@ executable psc-publish
292388 ghc-options: -Wall -O2
293389
294390executable psc-hierarchy
295− build-depends: base >=4 && <5, purescript -any, optparse-applicative >= 0.12.1,
296− process -any, mtl -any, parsec -any, filepath -any, directory -any,
297− Glob -any
391+ build-depends: base >=4 && <5,
392+ purescript -any,
393+ directory -any,
394+ filepath -any,
395+ Glob -any,
396+ mtl -any,
397+ optparse-applicative >= 0.12.1,
398+ parsec -any,
399+ process -any
298400 main-is: Main.hs
299401 other-modules: Paths_purescript
300402 buildable: True
@@ -308,13 +410,13 @@ executable psc-bundle
308410 other-extensions:
309411 build-depends: base >=4 && <5,
310412 purescript -any,
311− filepath -any,
312413 directory -any,
414+ filepath -any,
415+ Glob -any,
313416 mtl -any,
314− transformers -any,
315− transformers-compat -any,
316417 optparse-applicative >= 0.12.1,
317− Glob -any
418+ transformers -any,
419+ transformers-compat -any
318420 ghc-options: -Wall -O2
319421 hs-source-dirs: psc-bundle
320422
@@ -322,19 +424,19 @@ executable psc-ide-server
322424 main-is: Main.hs
323425 other-modules: Paths_purescript
324426 other-extensions:
325− build-depends: base >=4 && <5
326− , purescript -any
327− , directory -any
328− , filepath -any
329− , monad-logger -any
330− , mtl -any
331− , transformers -any
332− , transformers-compat -any
333− , network -any
334− , optparse-applicative >= 0.12.1
335− , stm -any
336− , text -any
337− , base-compat >=0.6.0
427+ build-depends: base >=4 && <5,
428+ purescript -any,
429+ base-compat >=0.6.0,
430+ directory -any,
431+ filepath -any,
432+ monad-logger -any,
433+ mtl -any,
434+ network -any,
435+ optparse-applicative >= 0.12.1,
436+ stm -any,
437+ text -any,
438+ transformers -any,
439+ transformers-compat -any
338440 ghc-options: -Wall -O2 -threaded
339441 hs-source-dirs: psc-ide-server
340442
@@ -342,23 +444,43 @@ executable psc-ide-client
342444 main-is: Main.hs
343445 other-modules: Paths_purescript
344446 other-extensions:
345− build-depends: base >=4 && <5
346− , mtl -any
347− , text -any
348− , optparse-applicative >= 0.12.1
349− , network -any
350− , base-compat >=0.6.0
447+ build-depends: base >=4 && <5,
448+ base-compat >=0.6.0,
449+ mtl -any,
450+ network -any,
451+ optparse-applicative >= 0.12.1,
452+ text -any
351453 ghc-options: -Wall -O2
352454 hs-source-dirs: psc-ide-client
353455
354456test-suite tests
355− build-depends: base >=4 && <5, containers -any, directory -any,
356− filepath -any, mtl -any, parsec -any, purescript -any,
357− transformers -any, process -any, transformers-compat -any, time -any,
358− Glob -any, aeson-better-errors -any, bytestring -any, aeson -any,
359− base-compat -any, haskeline >= 0.7.0.0, optparse-applicative -any,
360− boxes -any, HUnit -any, hspec -any, hspec-discover -any, stm -any, text -any,
361− vector -any, utf8-string -any
457+ build-depends: base >=4 && <5,
458+ purescript -any,
459+ aeson -any,
460+ aeson-better-errors -any,
461+ base-compat -any,
462+ boxes -any,
463+ bytestring -any,
464+ containers -any,
465+ directory -any,
466+ filepath -any,
467+ Glob -any,
468+ haskeline >= 0.7.0.0,
469+ hspec -any,
470+ hspec-discover -any,
471+ HUnit -any,
472+ mtl -any,
473+ optparse-applicative -any,
474+ parsec -any,
475+ process -any,
476+ silently -any,
477+ stm -any,
478+ text -any,
479+ time -any,
480+ transformers -any,
481+ transformers-compat -any,
482+ utf8-string -any,
483+ vector -any
362484 ghc-options: -Wall
363485 type: exitcode-stdio-1.0
364486 main-is: Main.hs
@@ -377,9 +499,5 @@ test-suite tests
377499 Language.PureScript.Ide.RebuildSpec
378500 Language.PureScript.Ide.ReexportsSpec
379501 Language.PureScript.IdeSpec
380− PSCi.Completion
381− PSCi.Directive
382− PSCi.Module
383− PSCi.Types
384502 buildable: True
385− hs-source-dirs: tests psci
503+ hs-source-dirs: tests
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+3−1
@@ -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.
src/Language/PureScript/AST/Declarations.hs+57−72
@@ -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
@@ -47,9 +41,9 @@ getModuleName (Module _ _ name _ _) = name
4741addDefaultImport :: ModuleName -> Module -> Module
4842addDefaultImport toImport m@(Module ss coms mn decls exps) =
4943 if isExistingImport `any` decls || mn == toImport then m
50− else Module ss coms mn (ImportDeclaration toImport Implicit Nothing False : decls) exps
44+ else Module ss coms mn (ImportDeclaration toImport Implicit Nothing : decls) exps
5145 where
52− isExistingImport (ImportDeclaration mn' _ _ _) | mn' == toImport = True
46+ isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True
5347 isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
5448 isExistingImport _ = False
5549
@@ -64,16 +58,20 @@ data DeclarationRef
6458 -- |
6559 -- A type operator
6660 --
67− | TypeOpRef Ident
61+ | TypeOpRef (OpName 'TypeOpName)
6862 -- |
6963 -- A value
7064 --
7165 | ValueRef Ident
7266 -- |
67+ -- A value-level operator
68+ --
69+ | ValueOpRef (OpName 'ValueOpName)
70+ -- |
7371 -- A type class
7472 --
7573 | TypeClassRef (ProperName 'ClassName)
76− -- |
74+ -- |
7775 -- A type class instance, created during typeclass desugaring (name, class name, instance types)
7876 --
7977 | TypeInstanceRef Ident
@@ -82,10 +80,6 @@ data DeclarationRef
8280 --
8381 | ModuleRef ModuleName
8482 -- |
85− -- An unspecified ProperName ref. This will be replaced with a TypeClassRef
86− -- or TypeRef during name desugaring.
87− | ProperRef String
88− -- |
8983 -- A declaration reference with source position information
9084 --
9185 | PositionedDeclarationRef SourceSpan [Comment] DeclarationRef
@@ -95,41 +89,44 @@ instance Eq DeclarationRef where
9589 (TypeRef name dctors) == (TypeRef name' dctors') = name == name' && dctors == dctors'
9690 (TypeOpRef name) == (TypeOpRef name') = name == name'
9791 (ValueRef name) == (ValueRef name') = name == name'
92+ (ValueOpRef name) == (ValueOpRef name') = name == name'
9893 (TypeClassRef name) == (TypeClassRef name') = name == name'
9994 (TypeInstanceRef name) == (TypeInstanceRef name') = name == name'
10095 (ModuleRef name) == (ModuleRef name') = name == name'
101− (ProperRef name) == (ProperRef name') = name == name'
10296 (PositionedDeclarationRef _ _ r) == r' = r == r'
10397 r == (PositionedDeclarationRef _ _ r') = r == r'
10498 _ == _ = False
10599
100+getTypeRef :: DeclarationRef -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
101+getTypeRef (TypeRef name dctors) = Just (name, dctors)
102+getTypeRef (PositionedDeclarationRef _ _ r) = getTypeRef r
103+getTypeRef _ = Nothing
104+
105+getTypeOpRef :: DeclarationRef -> Maybe (OpName 'TypeOpName)
106+getTypeOpRef (TypeOpRef op) = Just op
107+getTypeOpRef (PositionedDeclarationRef _ _ r) = getTypeOpRef r
108+getTypeOpRef _ = Nothing
109+
110+getValueRef :: DeclarationRef -> Maybe Ident
111+getValueRef (ValueRef name) = Just name
112+getValueRef (PositionedDeclarationRef _ _ r) = getValueRef r
113+getValueRef _ = Nothing
114+
115+getValueOpRef :: DeclarationRef -> Maybe (OpName 'ValueOpName)
116+getValueOpRef (ValueOpRef op) = Just op
117+getValueOpRef (PositionedDeclarationRef _ _ r) = getValueOpRef r
118+getValueOpRef _ = Nothing
119+
120+getTypeClassRef :: DeclarationRef -> Maybe (ProperName 'ClassName)
121+getTypeClassRef (TypeClassRef name) = Just name
122+getTypeClassRef (PositionedDeclarationRef _ _ r) = getTypeClassRef r
123+getTypeClassRef _ = Nothing
124+
106125isModuleRef :: DeclarationRef -> Bool
107126isModuleRef (PositionedDeclarationRef _ _ r) = isModuleRef r
108127isModuleRef (ModuleRef _) = True
109128isModuleRef _ = False
110129
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−
133130-- |
134131-- The data type which specifies type of import declaration
135132--
@@ -193,14 +190,13 @@ data Declaration
193190 --
194191 | ExternDataDeclaration (ProperName 'TypeName) Kind
195192 -- |
196− -- A fixity declaration (fixity data, operator name, value the operator is an alias for)
193+ -- A fixity declaration
197194 --
198− | FixityDeclaration Fixity String (Maybe (Qualified FixityAlias))
195+ | FixityDeclaration (Either ValueFixity TypeFixity)
199196 -- |
200197 -- 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)
202198 --
203− | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName) Bool
199+ | ImportDeclaration ModuleName ImportDeclarationType (Maybe ModuleName)
204200 -- |
205201 -- A type class declaration (name, argument, implies, member declarations)
206202 --
@@ -216,30 +212,14 @@ data Declaration
216212 | PositionedDeclaration SourceSpan [Comment] Declaration
217213 deriving (Show, Read)
218214
219−data FixityAlias
220− = AliasValue Ident
221− | AliasConstructor (ProperName 'ConstructorName)
222− | AliasType (ProperName 'TypeName)
215+data ValueFixity = ValueFixity Fixity (Qualified (Either Ident (ProperName 'ConstructorName))) (OpName 'ValueOpName)
223216 deriving (Eq, Ord, Show, Read)
224217
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
218+data TypeFixity = TypeFixity Fixity (Qualified (ProperName 'TypeName)) (OpName 'TypeOpName)
219+ deriving (Eq, Ord, Show, Read)
220+
221+pattern ValueFixityDeclaration fixity name op = FixityDeclaration (Left (ValueFixity fixity name op))
222+pattern TypeFixityDeclaration fixity name op = FixityDeclaration (Right (TypeFixity fixity name op))
243223
244224-- | The members of a type class instance declaration
245225data TypeInstanceBody
@@ -298,6 +278,11 @@ isFixityDecl FixityDeclaration{} = True
298278isFixityDecl (PositionedDeclaration _ _ d) = isFixityDecl d
299279isFixityDecl _ = False
300280
281+getFixityDecl :: Declaration -> Maybe (Either ValueFixity TypeFixity)
282+getFixityDecl (FixityDeclaration fixity) = Just fixity
283+getFixityDecl (PositionedDeclaration _ _ d) = getFixityDecl d
284+getFixityDecl _ = Nothing
285+
301286-- |
302287-- Test if a declaration is a foreign import
303288--
@@ -361,12 +346,8 @@ data Expr
361346 --
362347 | Parens Expr
363348 -- |
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.
349+ -- A record property getter (e.g. `_.x`). This will be removed during
350+ -- desugaring and expanded into a lambda that reads a property from a record.
370351 --
371352 | ObjectGetter String
372353 -- |
@@ -390,6 +371,11 @@ data Expr
390371 --
391372 | Var (Qualified Ident)
392373 -- |
374+ -- An operator. This will be desugared into a function during the "operators"
375+ -- phase of desugaring.
376+ --
377+ | Op (Qualified (OpName 'ValueOpName))
378+ -- |
393379 -- Conditional (if-then-else expression)
394380 --
395381 | IfThenElse Expr Expr Expr
@@ -487,4 +473,3 @@ data DoNotationElement
487473
488474$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
489475$(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+2−2
@@ -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.
src/Language/PureScript/AST/Operators.hs+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
src/Language/PureScript/AST/SourcePos.hs−3
@@ -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 ((.=), (.:))
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+58−53
@@ -1,48 +1,32 @@
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+ , ModuleIdentifier(..)
10+ , moduleName
11+ , ModuleType(..)
12+ , ErrorMessage(..)
13+ , printErrorMessage
14+ , getExportedIdentifiers
15+ ) where
16+
3417import Prelude.Compat
3518
36−import Data.List (nub, stripPrefix)
37−import Data.Maybe (mapMaybe, catMaybes, fromMaybe)
19+import Control.Monad
20+import Control.Monad.Error.Class
21+
22+import Data.Char (chr, digitToInt)
3823import Data.Generics (everything, everywhere, mkQ, mkT)
3924import Data.Graph
25+import Data.List (nub, stripPrefix)
26+import Data.Maybe (mapMaybe, catMaybes)
4027import Data.Version (showVersion)
41−
4228import qualified Data.Set as S
4329
44−import Control.Monad
45−import Control.Monad.Error.Class
4630import Language.JavaScript.Parser
4731import Language.JavaScript.Parser.AST
4832
@@ -134,13 +118,13 @@ printErrorMessage (ErrorInModule mid e) =
134118 name ++ " (" ++ showModuleType ty ++ ")"
135119
136120-- | Calculate the ModuleIdentifier which a require(...) statement imports.
137−checkImportPath :: Maybe FilePath -> String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
138−checkImportPath _ "./foreign" m _ =
121+checkImportPath :: String -> ModuleIdentifier -> S.Set String -> Either String ModuleIdentifier
122+checkImportPath "./foreign" m _ =
139123 Right (ModuleIdentifier (moduleName m) Foreign)
140−checkImportPath requirePath name _ names
141− | Just name' <- stripPrefix (fromMaybe "../" requirePath) name
124+checkImportPath name _ names
125+ | Just name' <- stripPrefix "../" name
142126 , name' `S.member` names = Right (ModuleIdentifier name' Regular)
143−checkImportPath _ name _ _ = Left name
127+checkImportPath name _ _ = Left name
144128
145129-- | Compute the dependencies of all elements in a module, and add them to the tree.
146130--
@@ -203,11 +187,34 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
203187
204188-- String literals include the quote chars
205189fromStringLiteral :: JSExpression -> Maybe String
206−fromStringLiteral (JSStringLiteral _ str) = Just $ trimStringQuotes str
190+fromStringLiteral (JSStringLiteral _ str) = Just $ strValue str
207191fromStringLiteral _ = Nothing
208192
209−trimStringQuotes :: String -> String
210−trimStringQuotes str = reverse $ drop 1 $ reverse $ drop 1 $ str
193+strValue :: String -> String
194+strValue str = go $ drop 1 str
195+ where
196+ go ('\\' : 'b' : xs) = '\b' : go xs
197+ go ('\\' : 'f' : xs) = '\f' : go xs
198+ go ('\\' : 'n' : xs) = '\n' : go xs
199+ go ('\\' : 'r' : xs) = '\r' : go xs
200+ go ('\\' : 't' : xs) = '\t' : go xs
201+ go ('\\' : 'v' : xs) = '\v' : go xs
202+ go ('\\' : '0' : xs) = '\0' : go xs
203+ go ('\\' : 'x' : a : b : xs) = chr (a' + b') : go xs
204+ where
205+ a' = 16 * digitToInt a
206+ b' = digitToInt b
207+ go ('\\' : 'u' : a : b : c : d : xs) = chr (a' + b' + c' + d') : go xs
208+ where
209+ a' = 16 * 16 * 16 * digitToInt a
210+ b' = 16 * 16 * digitToInt b
211+ c' = 16 * digitToInt c
212+ d' = digitToInt d
213+ go ('\\' : x : xs) = x : go xs
214+ go "\"" = ""
215+ go "'" = ""
216+ go (x : xs) = x : go xs
217+ go "" = ""
211218
212219commaList :: JSCommaList a -> [a]
213220commaList JSLNil = []
@@ -222,8 +229,8 @@ trailingCommaList (JSCTLNone l) = commaList l
222229--
223230-- Each type of module element is matched using pattern guards, and everything else is bundled into the
224231-- Other constructor.
225−toModule :: forall m. (MonadError ErrorMessage m) => Maybe FilePath -> S.Set String -> ModuleIdentifier -> JSAST -> m Module
226−toModule requirePath mids mid top
232+toModule :: forall m. (MonadError ErrorMessage m) => S.Set String -> ModuleIdentifier -> JSAST -> m Module
233+toModule mids mid top
227234 | JSAstProgram smts _ <- top = Module mid <$> traverse toModuleElement smts
228235 | otherwise = err InvalidTopLevel
229236 where
@@ -231,7 +238,7 @@ toModule requirePath mids mid top
231238
232239 toModuleElement :: JSStatement -> m ModuleElement
233240 toModuleElement stmt
234− | Just (importName, importPath) <- matchRequire requirePath mids mid stmt
241+ | Just (importName, importPath) <- matchRequire mids mid stmt
235242 = pure (Require stmt importName importPath)
236243 toModuleElement stmt
237244 | Just (exported, name, decl) <- matchMember stmt
@@ -291,12 +298,11 @@ getExportedIdentifiers mname top
291298
292299-- Matches JS statements like this:
293300-- var ModuleName = require("file");
294−matchRequire :: Maybe FilePath
295− -> S.Set String
301+matchRequire :: S.Set String
296302 -> ModuleIdentifier
297303 -> JSStatement
298304 -> Maybe (String, Either String ModuleIdentifier)
299−matchRequire requirePath mids mid stmt
305+matchRequire mids mid stmt
300306 | JSVariable _ jsInit _ <- stmt
301307 , [JSVarInitExpression var varInit] <- commaList jsInit
302308 , JSIdentifier _ importName <- var
@@ -304,7 +310,7 @@ matchRequire requirePath mids mid stmt
304310 , JSMemberExpression req _ argsE _ <- jsInitEx
305311 , JSIdentifier _ "require" <- req
306312 , [ Just importPath ] <- map fromStringLiteral (commaList argsE)
307− , importPath' <- checkImportPath requirePath importPath mid mids
313+ , importPath' <- checkImportPath importPath mid mids
308314 = Just (importName, importPath')
309315 | otherwise
310316 = Nothing
@@ -350,7 +356,7 @@ matchExportsAssignment stmt
350356 = Nothing
351357
352358extractLabel :: JSPropertyName -> Maybe String
353−extractLabel (JSPropertyString _ nm) = Just (trimStringQuotes nm)
359+extractLabel (JSPropertyString _ nm) = Just $ strValue nm
354360extractLabel (JSPropertyIdent _ nm) = Just nm
355361extractLabel _ = Nothing
356362
@@ -590,16 +596,15 @@ bundle :: (MonadError ErrorMessage m)
590596 -> [ModuleIdentifier] -- ^ Entry points. These module identifiers are used as the roots for dead-code elimination
591597 -> Maybe String -- ^ An optional main module.
592598 -> String -- ^ The namespace (e.g. PS).
593− -> Maybe FilePath -- ^ The require path prefix
594599 -> m String
595−bundle inputStrs entryPoints mainModule namespace requirePath = do
600+bundle inputStrs entryPoints mainModule namespace = do
596601 input <- forM inputStrs $ \(ident, js) -> do
597602 ast <- either (throwError . ErrorInModule ident . UnableToParseModule) pure $ parse js (moduleName ident)
598603 return (ident, ast)
599604
600605 let mids = S.fromList (map (moduleName . fst) input)
601606
602− modules <- traverse (fmap withDeps . uncurry (toModule requirePath mids)) input
607+ modules <- traverse (fmap withDeps . uncurry (toModule mids)) input
603608
604609 let compiled = compile modules entryPoints
605610 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/JS.hs+10−18
@@ -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,28 @@ 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
35−import Language.PureScript.Names
29+import Language.PureScript.Crash
3630import Language.PureScript.Errors
37−import Language.PureScript.CodeGen.JS.Optimizer
31+import Language.PureScript.Names
3832import Language.PureScript.Options
3933import Language.PureScript.Traversals (sndM)
4034import qualified Language.PureScript.Constants as C
@@ -109,9 +103,8 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
109103 --
110104 importToJs :: M.Map ModuleName (Ann, ModuleName) -> ModuleName -> m JS
111105 importToJs mnLookup mn' = do
112− path <- asks optionsRequirePath
113106 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')]
107+ let moduleBody = JSApp Nothing (JSVar Nothing "require") [JSStringLiteral Nothing (".." </> runModuleName mn')]
115108 withPos ss $ JSVariableIntroduction Nothing (moduleNameToJs mnSafe) (Just moduleBody)
116109
117110 -- |
@@ -180,7 +173,6 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign_ =
180173 --
181174 accessor :: Ident -> JS -> JS
182175 accessor (Ident prop) = accessorString prop
183− accessor (Op op) = JSIndexer Nothing (JSStringLiteral Nothing op)
184176 accessor (GenIdent _ _) = internalError "GenIdent in accessor"
185177
186178 accessorString :: String -> JS -> JS
src/Language/PureScript/CodeGen/JS/AST.hs+1−2
@@ -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
src/Language/PureScript/CodeGen/JS/Common.hs+2−1
@@ -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,7 +29,6 @@ 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-- |
src/Language/PureScript/CodeGen/JS/Optimizer.hs+5−9
@@ -1,5 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−
31-- |
42-- This module optimizes code in the simplified-Javascript intermediate representation.
53--
@@ -23,22 +21,20 @@
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
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+104−107
@@ -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
@@ -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+2
@@ -5,6 +5,8 @@
55--
66module Language.PureScript.Comments where
77
8+import Prelude.Compat
9+
810import Data.Aeson.TH
911
1012data Comment
src/Language/PureScript/Constants.hs+30−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,6 +385,9 @@ dataSemiring = "Data_Semiring"
366385dataRing :: String
367386dataRing = "Data_Ring"
368387
388+dataEuclideanRing :: String
389+dataEuclideanRing = "Data_EuclideanRing"
390+
369391dataFunction :: String
370392dataFunction = "Data_Function"
371393
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+2−2
@@ -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
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+3−3
@@ -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-- |
src/Language/PureScript/CoreFn/Meta.hs+2
@@ -3,6 +3,8 @@
33--
44module Language.PureScript.CoreFn.Meta where
55
6+import Prelude.Compat
7+
68import Language.PureScript.Names
79
810-- |
src/Language/PureScript/CoreFn/Module.hs+5−14
@@ -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
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+17−23
@@ -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{..} =
src/Language/PureScript/Docs/Convert.hs+11−13
@@ -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
@@ -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+6−10
@@ -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:
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+21−16
@@ -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
@@ -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.
src/Language/PureScript/Errors.hs+352−405
@@ -1,40 +1,40 @@
11{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
2+{-# LANGUAGE NamedFieldPuns #-}
43
54module Language.PureScript.Errors where
65
7−import Prelude ()
86import Prelude.Compat
97
10−import Data.Ord (comparing)
8+import Control.Arrow ((&&&))
9+import Control.Monad
10+import Control.Monad.Error.Class (MonadError(..))
11+import Control.Monad.Trans.State.Lazy
12+import Control.Monad.Writer
13+
1114import Data.Char (isSpace)
1215import Data.Either (lefts, rights)
13−import Data.List (intercalate, transpose, nub, nubBy, sortBy, partition)
1416import Data.Foldable (fold)
17+import Data.List (intercalate, transpose, nub, nubBy, sortBy, partition)
1518import Data.Maybe (maybeToList)
16−
19+import Data.Ord (comparing)
1720import qualified Data.Map as M
1821
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
2622import Language.PureScript.AST
23+import Language.PureScript.Crash
24+import Language.PureScript.Kinds
25+import Language.PureScript.Names
2726import Language.PureScript.Pretty
28−import Language.PureScript.Pretty.Common (before)
27+import Language.PureScript.Traversals
2928import Language.PureScript.Types
30−import Language.PureScript.Names
31−import Language.PureScript.Kinds
29+import Language.PureScript.Pretty.Common (endWith)
3230import qualified Language.PureScript.Bundle as Bundle
31+import qualified Language.PureScript.Constants as C
3332
34−import qualified Text.PrettyPrint.Boxes as Box
33+import qualified System.Console.ANSI as ANSI
3534
3635import qualified Text.Parsec as P
3736import qualified Text.Parsec.Error as PE
37+import qualified Text.PrettyPrint.Boxes as Box
3838import Text.Parsec.Error (Message(..))
3939
4040-- | A type of error messages
@@ -52,42 +52,22 @@ data SimpleErrorMessage
5252 | CannotWriteFile FilePath
5353 | InfiniteType Type
5454 | InfiniteKind Kind
55− | MultipleFixities Ident
55+ | MultipleValueOpFixities (OpName 'ValueOpName)
56+ | MultipleTypeOpFixities (OpName 'TypeOpName)
5657 | OrphanTypeDeclaration Ident
57− | OrphanFixityDeclaration String
5858 | RedefinedModule ModuleName [SourceSpan]
5959 | RedefinedIdent Ident
6060 | 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
61+ | UnknownName (Qualified Name)
62+ | UnknownImport ModuleName Name
7763 | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
64+ | UnknownExport Name
7865 | 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)
66+ | ScopeConflict Name [ModuleName]
67+ | ScopeShadowing Name (Maybe ModuleName) [ModuleName]
68+ | DeclConflict Name Name
69+ | ExportConflict (Qualified Name) (Qualified Name)
8770 | DuplicateModuleName ModuleName
88− | DuplicateClassExport (ProperName 'ClassName)
89− | DuplicateValueExport Ident
90− | DuplicateTypeOpExport Ident
9171 | DuplicateTypeArgument String
9272 | InvalidDoBind
9373 | InvalidDoLet
@@ -102,7 +82,7 @@ data SimpleErrorMessage
10282 | KindsDoNotUnify Kind Kind
10383 | ConstrainedTypeUnified Type Type
10484 | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
105− | NoInstanceFound (Qualified (ProperName 'ClassName)) [Type]
85+ | NoInstanceFound Constraint
10686 | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
10787 | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
10888 | CannotFindDerivingType (ProperName 'TypeName)
@@ -128,35 +108,27 @@ data SimpleErrorMessage
128108 | ShadowedTypeVar String
129109 | UnusedTypeVar String
130110 | WildcardInferredType Type
131− | HoleInferredType String Type
111+ | HoleInferredType String Type [(Ident, Type)]
132112 | MissingTypeDeclaration Ident Type
133− | NotExhaustivePattern [[Binder]] Bool
134113 | OverlappingPattern [[Binder]] Bool
135114 | IncompleteExhaustivityCheck
136− | ClassOperator (ProperName 'ClassName) Ident
137115 | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
138116 | ImportHidingModule ModuleName
139117 | UnusedImport ModuleName
140118 | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
141119 | UnusedDctorImport (ProperName 'TypeName)
142120 | 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)
148121 | DuplicateSelectiveImport ModuleName
149122 | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
150− | DuplicateImportRef String
151− | DuplicateExportRef String
123+ | DuplicateImportRef Name
124+ | DuplicateExportRef Name
152125 | IntOutOfRange Integer String Integer Integer
153− | RedundantEmptyHidingImport ModuleName
154126 | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
155127 | ImplicitImport ModuleName [DeclarationRef]
156128 | HidingImport ModuleName [DeclarationRef]
157129 | CaseBinderLengthDiffers Int [Binder]
158130 | IncorrectAnonymousArgument
159− | InvalidOperatorInBinder Ident Ident
131+ | InvalidOperatorInBinder (Qualified (OpName 'ValueOpName)) (Qualified Ident)
160132 | DeprecatedRequirePath
161133 | CannotGeneralizeRecursiveFunction Ident Type
162134 deriving (Show)
@@ -241,42 +213,22 @@ errorCode em = case unwrapErrorMessage em of
241213 CannotWriteFile{} -> "CannotWriteFile"
242214 InfiniteType{} -> "InfiniteType"
243215 InfiniteKind{} -> "InfiniteKind"
244− MultipleFixities{} -> "MultipleFixities"
216+ MultipleValueOpFixities{} -> "MultipleValueOpFixities"
217+ MultipleTypeOpFixities{} -> "MultipleTypeOpFixities"
245218 OrphanTypeDeclaration{} -> "OrphanTypeDeclaration"
246− OrphanFixityDeclaration{} -> "OrphanFixityDeclaration"
247219 RedefinedModule{} -> "RedefinedModule"
248220 RedefinedIdent{} -> "RedefinedIdent"
249221 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"
222+ UnknownName{} -> "UnknownName"
223+ UnknownImport{} -> "UnknownImport"
266224 UnknownImportDataConstructor{} -> "UnknownImportDataConstructor"
225+ UnknownExport{} -> "UnknownExport"
267226 UnknownExportDataConstructor{} -> "UnknownExportDataConstructor"
268227 ScopeConflict{} -> "ScopeConflict"
269228 ScopeShadowing{} -> "ScopeShadowing"
270− ConflictingTypeDecls{} -> "ConflictingTypeDecls"
271− ConflictingCtorDecls{} -> "ConflictingCtorDecls"
272− TypeConflictsWithClass{} -> "TypeConflictsWithClass"
273− CtorConflictsWithClass{} -> "CtorConflictsWithClass"
274− ClassConflictsWithType{} -> "ClassConflictsWithType"
275− ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"
229+ DeclConflict{} -> "DeclConflict"
230+ ExportConflict{} -> "ExportConflict"
276231 DuplicateModuleName{} -> "DuplicateModuleName"
277− DuplicateClassExport{} -> "DuplicateClassExport"
278− DuplicateValueExport{} -> "DuplicateValueExport"
279− DuplicateTypeOpExport{} -> "DuplicateTypeOpExport"
280232 DuplicateTypeArgument{} -> "DuplicateTypeArgument"
281233 InvalidDoBind -> "InvalidDoBind"
282234 InvalidDoLet -> "InvalidDoLet"
@@ -319,27 +271,19 @@ errorCode em = case unwrapErrorMessage em of
319271 WildcardInferredType{} -> "WildcardInferredType"
320272 HoleInferredType{} -> "HoleInferredType"
321273 MissingTypeDeclaration{} -> "MissingTypeDeclaration"
322− NotExhaustivePattern{} -> "NotExhaustivePattern"
323274 OverlappingPattern{} -> "OverlappingPattern"
324275 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
325− ClassOperator{} -> "ClassOperator"
326276 MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"
327277 ImportHidingModule{} -> "ImportHidingModule"
328278 UnusedImport{} -> "UnusedImport"
329279 UnusedExplicitImport{} -> "UnusedExplicitImport"
330280 UnusedDctorImport{} -> "UnusedDctorImport"
331281 UnusedDctorExplicitImport{} -> "UnusedDctorExplicitImport"
332− DeprecatedOperatorDecl{} -> "DeprecatedOperatorDecl"
333− DeprecatedOperatorSection{} -> "DeprecatedOperatorSection"
334− DeprecatedQualifiedSyntax{} -> "DeprecatedQualifiedSyntax"
335− DeprecatedClassImport{} -> "DeprecatedClassImport"
336− DeprecatedClassExport{} -> "DeprecatedClassExport"
337282 DuplicateSelectiveImport{} -> "DuplicateSelectiveImport"
338283 DuplicateImport{} -> "DuplicateImport"
339284 DuplicateImportRef{} -> "DuplicateImportRef"
340285 DuplicateExportRef{} -> "DuplicateExportRef"
341286 IntOutOfRange{} -> "IntOutOfRange"
342− RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
343287 ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
344288 ImplicitImport{} -> "ImplicitImport"
345289 HidingImport{} -> "HidingImport"
@@ -381,14 +325,17 @@ addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint
381325
382326-- | A map from rigid type variable name/unknown variable pairs to new variables.
383327data TypeMap = TypeMap
384− { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
385− , umNextSkolem :: Int
386− , umUnknownMap :: M.Map Int Int
387− , umNextUnknown :: Int
328+ { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
329+ -- ^ a map from skolems to their new names, including source and naming info
330+ , umUnknownMap :: M.Map Int Int
331+ -- ^ a map from unification variables to their new names
332+ , umNextIndex :: Int
333+ -- ^ unknowns and skolems share a source of names during renaming, to
334+ -- avoid overlaps in error messages. This is the next label for either case.
388335 } deriving Show
389336
390337defaultUnknownMap :: TypeMap
391−defaultUnknownMap = TypeMap M.empty 0 M.empty 0
338+defaultUnknownMap = TypeMap M.empty M.empty 0
392339
393340-- | How critical the issue is
394341data Level = Error | Warning deriving Show
@@ -407,16 +354,16 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
407354 m <- get
408355 case M.lookup u (umUnknownMap m) of
409356 Nothing -> do
410− let u' = umNextUnknown m
411− put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextUnknown = u' + 1 }
357+ let u' = umNextIndex m
358+ put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextIndex = u' + 1 }
412359 return (TUnknown u')
413360 Just u' -> return (TUnknown u')
414361 replaceTypes (Skolem name s sko ss) = do
415362 m <- get
416363 case M.lookup s (umSkolemMap m) of
417364 Nothing -> do
418− let s' = umNextSkolem m
419− put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextSkolem = s' + 1 }
365+ let s' = umNextIndex m
366+ put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextIndex = s' + 1 }
420367 return (Skolem name s' sko ss)
421368 Just (_, s', _) -> return (Skolem name s' sko ss)
422369 replaceTypes other = return other
@@ -430,14 +377,14 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
430377 gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
431378 gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
432379 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
433− gSimple (NoInstanceFound cl ts) = NoInstanceFound cl <$> traverse f ts
380+ gSimple (NoInstanceFound con) = NoInstanceFound <$> overConstraintArgs (traverse f) con
434381 gSimple (OverlappingInstances cl ts insts) = OverlappingInstances cl <$> traverse f ts <*> pure insts
435382 gSimple (PossiblyInfiniteInstance cl ts) = PossiblyInfiniteInstance cl <$> traverse f ts
436383 gSimple (CannotDerive cl ts) = CannotDerive cl <$> traverse f ts
437384 gSimple (ExpectedType ty k) = ExpectedType <$> f ty <*> pure k
438385 gSimple (OrphanInstance nm cl ts) = OrphanInstance nm cl <$> traverse f ts
439386 gSimple (WildcardInferredType ty) = WildcardInferredType <$> f ty
440− gSimple (HoleInferredType name ty) = HoleInferredType name <$> f ty
387+ gSimple (HoleInferredType name ty env) = HoleInferredType name <$> f ty <*> traverse (sndM f) env
441388 gSimple (MissingTypeDeclaration nm ty) = MissingTypeDeclaration nm <$> f ty
442389 gSimple (CannotGeneralizeRecursiveFunction nm ty) = CannotGeneralizeRecursiveFunction nm <$> f ty
443390
@@ -457,18 +404,16 @@ wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ error
457404-- TODO Other possible suggestions:
458405-- WildcardInferredType - source span not small enough
459406-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
460−-- DeprecatedClassExport, DeprecatedClassImport, DeprecatedOperatorSection, would want to replace smaller span?
461407errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
462408errorSuggestion err = case err of
463409 UnusedImport{} -> emptySuggestion
464− RedundantEmptyHidingImport{} -> emptySuggestion
465410 DuplicateImport{} -> emptySuggestion
466− DeprecatedQualifiedSyntax name qualName -> suggest $
467− "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
468411 UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
469412 ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
470413 ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
471414 HidingImport mn refs -> suggest $ importSuggestion mn refs Nothing
415+ MissingTypeDeclaration ident ty -> suggest $ showIdent ident ++ " :: " ++ prettyPrintType ty
416+ WildcardInferredType ty -> suggest $ prettyPrintType ty
472417 _ -> Nothing
473418
474419 where
@@ -483,20 +428,81 @@ errorSuggestion err = case err of
483428 qstr (Just mn) = " as " ++ runModuleName mn
484429 qstr Nothing = ""
485430
431+suggestionSpan :: ErrorMessage -> Maybe SourceSpan
432+suggestionSpan e =
433+ getSpan (unwrapErrorMessage e) <$> errorSpan e
434+ where
435+ startOnly SourceSpan{spanName, spanStart} = SourceSpan {spanName, spanStart, spanEnd = spanStart}
436+
437+ getSpan simple ss =
438+ case simple of
439+ MissingTypeDeclaration{} -> startOnly ss
440+ _ -> ss
441+
486442showSuggestion :: SimpleErrorMessage -> String
487443showSuggestion suggestion = case errorSuggestion suggestion of
488444 Just (ErrorSuggestion x) -> x
489445 _ -> ""
490446
447+ansiColor :: (ANSI.ColorIntensity, ANSI.Color) -> String
448+ansiColor (intesity, color) =
449+ ANSI.setSGRCode [ANSI.SetColor ANSI.Foreground intesity color]
450+
451+ansiColorReset :: String
452+ansiColorReset =
453+ ANSI.setSGRCode [ANSI.Reset]
454+
455+colorCode :: Maybe (ANSI.ColorIntensity, ANSI.Color) -> String -> String
456+colorCode codeColor code = case codeColor of
457+ Nothing -> code
458+ Just cc -> concat [ansiColor cc, code, ansiColorReset]
459+
460+colorCodeBox :: Maybe (ANSI.ColorIntensity, ANSI.Color) -> Box.Box -> Box.Box
461+colorCodeBox codeColor b = case codeColor of
462+ Nothing -> b
463+ Just cc
464+ | Box.rows b == 1 ->
465+ Box.text (ansiColor cc) Box.<> b `endWith` Box.text ansiColorReset
466+
467+ | 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
468+ [ Box.vcat Box.top $ replicate (Box.rows b) $ Box.text $ ansiColor cc
469+ , b
470+ , Box.vcat Box.top $ replicate (Box.rows b) $ Box.text ansiColorReset
471+ ]
472+
473+
474+-- | Default color intesity and color for code
475+defaultCodeColor :: (ANSI.ColorIntensity, ANSI.Color)
476+defaultCodeColor = (ANSI.Dull, ANSI.Yellow)
477+
478+-- | `prettyPrintSingleError` Options
479+data PPEOptions = PPEOptions
480+ { ppeCodeColor :: Maybe (ANSI.ColorIntensity, ANSI.Color) -- ^ Color code with this color... or not
481+ , ppeFull :: Bool -- ^ Should write a full error message?
482+ , ppeLevel :: Level -- ^ Should this report an error or a warning?
483+ , ppeShowWiki :: Bool -- ^ Should show a link to error message's wiki page?
484+ }
485+
486+-- | Default options for PPEOptions
487+defaultPPEOptions :: PPEOptions
488+defaultPPEOptions = PPEOptions
489+ { ppeCodeColor = Just defaultCodeColor
490+ , ppeFull = False
491+ , ppeLevel = Error
492+ , ppeShowWiki = True
493+ }
494+
495+
491496-- |
492497-- Pretty print a single error, simplifying if necessary
493498--
494−prettyPrintSingleError :: Bool -> Level -> Bool -> ErrorMessage -> Box.Box
495−prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap $ do
499+prettyPrintSingleError :: PPEOptions -> ErrorMessage -> Box.Box
500+prettyPrintSingleError (PPEOptions codeColor full level showWiki) e = flip evalState defaultUnknownMap $ do
496501 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
497502 um <- get
498503 return (prettyPrintErrorMessage um em)
499504 where
505+ (markCode, markCodeBox) = (colorCode &&& colorCodeBox) codeColor
500506
501507 -- Pretty print an ErrorMessage
502508 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
@@ -505,9 +511,10 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
505511 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
506512 ] ++
507513 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− ]
514+ [ Box.moveDown 1 $ paras
515+ [ line $ "See " ++ wikiUri e ++ " for more information, "
516+ , line $ "or to contribute content related to this " ++ levelText ++ "."
517+ ]
511518 | showWiki
512519 ]
513520 where
@@ -522,11 +529,11 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
522529 skolemInfo :: (String, Int, Maybe SourceSpan) -> Box.Box
523530 skolemInfo (name, s, ss) =
524531 paras $
525− line (name ++ show s ++ " is a rigid type variable")
532+ line (markCode (name ++ show s) ++ " is a rigid type variable")
526533 : foldMap (return . line . (" bound at " ++) . displayStartEndPos) ss
527534
528535 unknownInfo :: Int -> Box.Box
529− unknownInfo u = line $ "_" ++ show u ++ " is an unknown type"
536+ unknownInfo u = line $ markCode ("t" ++ show u) ++ " is an unknown type"
530537
531538 renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
532539 renderSimpleErrorMessage (CannotGetFileInfo path) =
@@ -545,35 +552,35 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
545552 paras $ [ line "Unable to parse foreign module:"
546553 , indent . line $ path
547554 ] ++
548− (map (indent . line) (concatMap Bundle.printErrorMessage (maybeToList extra)))
555+ map (indent . line) (concatMap Bundle.printErrorMessage (maybeToList extra))
549556 renderSimpleErrorMessage (ErrorParsingModule err) =
550557 paras [ line "Unable to parse module: "
551558 , prettyPrintParseError err
552559 ]
553560 renderSimpleErrorMessage (MissingFFIModule mn) =
554− line $ "The foreign module implementation for module " ++ runModuleName mn ++ " is missing."
561+ line $ "The foreign module implementation for module " ++ markCode (runModuleName mn) ++ " is missing."
555562 renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
556− paras [ line $ "An unnecessary foreign module implementation was provided for module " ++ runModuleName mn ++ ": "
563+ paras [ line $ "An unnecessary foreign module implementation was provided for module " ++ markCode (runModuleName mn) ++ ": "
557564 , indent . line $ path
558− , line $ "Module " ++ runModuleName mn ++ " does not contain any foreign import declarations, so a foreign module is not necessary."
565+ , line $ "Module " ++ markCode (runModuleName mn) ++ " does not contain any foreign import declarations, so a foreign module is not necessary."
559566 ]
560567 renderSimpleErrorMessage (MissingFFIImplementations mn idents) =
561− paras [ line $ "The following values are not defined in the foreign module for module " ++ runModuleName mn ++ ": "
568+ paras [ line $ "The following values are not defined in the foreign module for module " ++ markCode (runModuleName mn) ++ ": "
562569 , indent . paras $ map (line . runIdent) idents
563570 ]
564571 renderSimpleErrorMessage (UnusedFFIImplementations mn idents) =
565− paras [ line $ "The following definitions in the foreign module for module " ++ runModuleName mn ++ " are unused: "
572+ paras [ line $ "The following definitions in the foreign module for module " ++ markCode (runModuleName mn) ++ " are unused: "
566573 , indent . paras $ map (line . runIdent) idents
567574 ]
568575 renderSimpleErrorMessage (InvalidFFIIdentifier mn ident) =
569− paras [ line $ "In the FFI module for " ++ runModuleName mn ++ ":"
576+ paras [ line $ "In the FFI module for " ++ markCode (runModuleName mn) ++ ":"
570577 , indent . paras $
571− [ line $ "The identifier `" ++ ident ++ "` is not valid in PureScript."
578+ [ line $ "The identifier " ++ markCode ident ++ " is not valid in PureScript."
572579 , line "Note that exported identifiers in FFI modules must be valid PureScript identifiers."
573580 ]
574581 ]
575582 renderSimpleErrorMessage (MultipleFFIModules mn paths) =
576− paras [ line $ "Multiple foreign module implementations have been provided for module " ++ runModuleName mn ++ ": "
583+ paras [ line $ "Multiple foreign module implementations have been provided for module " ++ markCode (runModuleName mn) ++ ": "
577584 , indent . paras $ map line paths
578585 ]
579586 renderSimpleErrorMessage InvalidDoBind =
@@ -584,126 +591,78 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
584591 line "The same name was used more than once in a let binding."
585592 renderSimpleErrorMessage (InfiniteType ty) =
586593 paras [ line "An infinite type was inferred for an expression: "
587− , indent $ typeAsBox ty
594+ , markCodeBox $ indent $ typeAsBox ty
588595 ]
589596 renderSimpleErrorMessage (InfiniteKind ki) =
590597 paras [ line "An infinite kind was inferred for a type: "
591− , indent $ line $ prettyPrintKind ki
598+ , indent $ line $ markCode $ prettyPrintKind ki
592599 ]
593− renderSimpleErrorMessage (MultipleFixities name) =
594− line $ "There are multiple fixity/precedence declarations for " ++ showIdent name
600+ renderSimpleErrorMessage (MultipleValueOpFixities op) =
601+ line $ "There are multiple fixity/precedence declarations for operator " ++ markCode (showOp op)
602+ renderSimpleErrorMessage (MultipleTypeOpFixities op) =
603+ line $ "There are multiple fixity/precedence declarations for type operator " ++ markCode (showOp op)
595604 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."
605+ line $ "The type declaration for " ++ markCode (showIdent nm) ++ " should be followed by its definition."
599606 renderSimpleErrorMessage (RedefinedModule name filenames) =
600− paras [ line ("The module " ++ runModuleName name ++ " has been defined multiple times:")
607+ paras [ line ("The module " ++ markCode (runModuleName name) ++ " has been defined multiple times:")
601608 , indent . paras $ map (line . displaySourceSpan) filenames
602609 ]
603610 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
611+ line $ "The value " ++ markCode (showIdent name) ++ " has been defined multiple times"
612+ renderSimpleErrorMessage (UnknownName name) =
613+ line $ "Unknown " ++ printName name
614+ renderSimpleErrorMessage (UnknownImport mn name) =
615+ paras [ line $ "Cannot import " ++ printName (Qualified Nothing name) ++ " from module " ++ markCode (runModuleName mn)
621616 , line "It either does not exist or the module does not export it."
622617 ]
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
627− , line "It either does not exist or the module does not export it."
628− ]
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− ]
647618 renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
648− line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon
619+ line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ markCode (runProperName dcon) ++ " for type " ++ markCode (runProperName tcon)
620+ renderSimpleErrorMessage (UnknownExport name) =
621+ line $ "Cannot export unknown " ++ printName (Qualified Nothing name)
649622 renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
650− line $ "Cannot export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon ++ ", as it has not been declared."
623+ line $ "Cannot export data constructor " ++ markCode (runProperName dcon) ++ " for type " ++ markCode (runProperName tcon) ++ ", as it has not been declared."
651624 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
625+ paras [ line $ "Conflicting definitions are in scope for " ++ printName (Qualified Nothing nm) ++ " from the following modules:"
626+ , indent $ paras $ map (line . markCode . runModuleName) ms
654627 ]
655628 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
629+ paras [ line $ "Shadowed definitions are in scope for " ++ printName (Qualified Nothing nm) ++ " from the following open imports:"
630+ , indent $ paras $ map (line . markCode . ("import " ++) . runModuleName) ms
658631 , line $ "These will be ignored and the " ++ case exmn of
659− Just exmn' -> "declaration from " ++ runModuleName exmn' ++ " will be used."
632+ Just exmn' -> "declaration from " ++ markCode (runModuleName exmn') ++ " will be used."
660633 Nothing -> "local declaration will be used."
661634 ]
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."
635+ renderSimpleErrorMessage (DeclConflict new existing) =
636+ line $ "Declaration for " ++ printName (Qualified Nothing new) ++ " conflicts with an existing " ++ nameType existing ++ " of the same name."
637+ renderSimpleErrorMessage (ExportConflict new existing) =
638+ line $ "Export for " ++ printName new ++ " conflicts with " ++ runName existing
674639 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
640+ line $ "Module " ++ markCode (runModuleName mn) ++ " has been defined multiple times."
682641 renderSimpleErrorMessage (CycleInDeclaration nm) =
683− line $ "The value of " ++ showIdent nm ++ " is undefined here, so this reference is not allowed."
642+ line $ "The value of " ++ markCode (showIdent nm) ++ " is undefined here, so this reference is not allowed."
684643 renderSimpleErrorMessage (CycleInModules mns) =
685644 paras [ line "There is a cycle in module dependencies in these modules: "
686− , indent $ paras (map (line . runModuleName) mns)
645+ , indent $ paras (map (line . markCode . runModuleName) mns)
687646 ]
688647 renderSimpleErrorMessage (CycleInTypeSynonym name) =
689648 paras [ line $ case name of
690− Just pn -> "A cycle appears in the definition of type synonym " ++ runProperName pn
649+ Just pn -> "A cycle appears in the definition of type synonym " ++ markCode (runProperName pn)
691650 Nothing -> "A cycle appears in a set of type synonym definitions."
692651 , line "Cycles are disallowed because they can lead to loops in the type checker."
693652 , line "Consider using a 'newtype' instead."
694653 ]
695654 renderSimpleErrorMessage (NameIsUndefined ident) =
696− line $ "Value " ++ showIdent ident ++ " is undefined."
655+ line $ "Value " ++ markCode (showIdent ident) ++ " is undefined."
697656 renderSimpleErrorMessage (UndefinedTypeVariable name) =
698− line $ "Type variable " ++ runProperName name ++ " is undefined."
657+ line $ "Type variable " ++ markCode (runProperName name) ++ " is undefined."
699658 renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
700− paras [ line $ "Type synonym " ++ showQualified runProperName name ++ " is partially applied."
659+ paras [ line $ "Type synonym " ++ markCode (showQualified runProperName name) ++ " is partially applied."
701660 , line "Type synonyms must be applied to all of their type arguments."
702661 ]
703662 renderSimpleErrorMessage (EscapedSkolem binding) =
704663 paras $ [ line "A type variable has escaped its scope." ]
705664 <> foldMap (\expr -> [ line "Relevant expression: "
706− , indent $ prettyPrintValue valueDepth expr
665+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr
707666 ]) binding
708667 renderSimpleErrorMessage (TypesDoNotUnify u1 u2)
709668 = let (sorted1, sorted2) = sortRows u1 u2
@@ -725,39 +684,56 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
725684 , rowFromList (sortBy (comparing fst) sd2 ++ map (fst &&& snd . snd) common, r2)
726685 )
727686 in paras [ line "Could not match type"
728− , indent $ typeAsBox sorted1
687+ , markCodeBox $ indent $ typeAsBox sorted1
729688 , line "with type"
730− , indent $ typeAsBox sorted2
689+ , markCodeBox $ indent $ typeAsBox sorted2
731690 ]
732691
733692 renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
734693 paras [ line "Could not match kind"
735− , indent $ line $ prettyPrintKind k1
694+ , indent $ line $ markCode $ prettyPrintKind k1
736695 , line "with kind"
737− , indent $ line $ prettyPrintKind k2
696+ , indent $ line $ markCode $ prettyPrintKind k2
738697 ]
739698 renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
740699 paras [ line "Could not match constrained type"
741− , indent $ typeAsBox t1
700+ , markCodeBox $ indent $ typeAsBox t1
742701 , line "with type"
743− , indent $ typeAsBox t2
702+ , markCodeBox $ indent $ typeAsBox t2
744703 ]
745704 renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
746705 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− ]
706+ , markCodeBox $ indent $ Box.hsep 1 Box.left
707+ [ line (showQualified runProperName nm)
708+ , Box.vcat Box.left (map typeAtomAsBox ts)
709+ ]
750710 , line "The following instances were found:"
751711 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
752712 , line "Overlapping type class instances can lead to different behavior based on the order of module imports, and for that reason are not recommended."
753713 , line "They may be disallowed completely in a future version of the compiler."
754714 ]
755715 renderSimpleErrorMessage OverlappingInstances{} = internalError "OverlappingInstances: empty instance list"
756− renderSimpleErrorMessage (NoInstanceFound nm ts) =
716+ renderSimpleErrorMessage (NoInstanceFound (Constraint C.Fail [ TypeLevelString message ] _)) =
717+ paras [ line "A custom type error occurred while solving type class constraints:"
718+ , indent . paras . map line . lines $ message
719+ ]
720+ renderSimpleErrorMessage (NoInstanceFound (Constraint C.Partial
721+ _
722+ (Just (PartialConstraintData bs b)))) =
723+ paras [ line "A case expression could not be determined to cover all inputs."
724+ , line "The following additional cases are required to cover all inputs:\n"
725+ , indent $ paras $
726+ Box.hsep 1 Box.left
727+ (map (paras . map (line . markCode)) (transpose bs))
728+ : [line "..." | not b]
729+ , line "Alternatively, add a Partial constraint to the type of the enclosing value."
730+ ]
731+ renderSimpleErrorMessage (NoInstanceFound (Constraint nm ts _)) =
757732 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− ]
733+ , markCodeBox $ indent $ Box.hsep 1 Box.left
734+ [ line (showQualified runProperName nm)
735+ , Box.vcat Box.left (map typeAtomAsBox ts)
736+ ]
761737 , paras [ line "The instance head contains unknown type variables. Consider adding a type annotation."
762738 | any containsUnknowns ts
763739 ]
@@ -770,130 +746,128 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
770746 go _ = False
771747 renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
772748 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− ]
749+ , markCodeBox $ indent $ Box.hsep 1 Box.left
750+ [ line (showQualified runProperName nm)
751+ , Box.vcat Box.left (map typeAtomAsBox ts)
752+ ]
776753 , line "is possibly infinite."
777754 ]
778755 renderSimpleErrorMessage (CannotDerive nm ts) =
779756 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− ]
757+ , markCodeBox $ indent $ Box.hsep 1 Box.left
758+ [ line (showQualified runProperName nm)
759+ , Box.vcat Box.left (map typeAtomAsBox ts)
760+ ]
783761 ]
784762 renderSimpleErrorMessage (CannotFindDerivingType nm) =
785− line $ "Cannot derive a type class instance, because the type declaration for " ++ runProperName nm ++ " could not be found."
763+ line $ "Cannot derive a type class instance, because the type declaration for " ++ markCode (runProperName nm) ++ " could not be found."
786764 renderSimpleErrorMessage (DuplicateLabel l expr) =
787− paras $ [ line $ "Label " ++ show l ++ " appears more than once in a row type." ]
765+ paras $ [ line $ "Label " ++ markCode l ++ " appears more than once in a row type." ]
788766 <> foldMap (\expr' -> [ line "Relevant expression: "
789− , indent $ prettyPrintValue valueDepth expr'
767+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr'
790768 ]) expr
791769 renderSimpleErrorMessage (DuplicateTypeArgument name) =
792− line $ "Type argument " ++ show name ++ " appears more than once."
770+ line $ "Type argument " ++ markCode name ++ " appears more than once."
793771 renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
794− line $ "Multiple value declarations exist for " ++ showIdent nm ++ "."
772+ line $ "Multiple value declarations exist for " ++ markCode (showIdent nm) ++ "."
795773 renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
796− line $ "Argument list lengths differ in declaration " ++ showIdent ident
774+ line $ "Argument list lengths differ in declaration " ++ markCode (showIdent ident)
797775 renderSimpleErrorMessage (OverlappingArgNames ident) =
798776 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration " ++) . showIdent) ident
799777 renderSimpleErrorMessage (MissingClassMember ident) =
800− line $ "Type class member " ++ showIdent ident ++ " has not been implemented."
778+ line $ "Type class member " ++ markCode (showIdent ident) ++ " has not been implemented."
801779 renderSimpleErrorMessage (ExtraneousClassMember ident className) =
802− line $ showIdent ident ++ " is not a member of type class " ++ showQualified runProperName className
780+ line $ "" ++ markCode (showIdent ident) ++ " is not a member of type class " ++ markCode (showQualified runProperName className)
803781 renderSimpleErrorMessage (ExpectedType ty kind) =
804− paras [ line "In a type-annotated expression x :: t, the type t must have kind *."
782+ paras [ line $ "In a type-annotated expression " ++ markCode "x :: t" ++ ", the type " ++ markCode "t" ++ " must have kind " ++ markCode "*" ++ "."
805783 , line "The error arises from the type"
806− , indent $ typeAsBox ty
784+ , markCodeBox $ indent $ typeAsBox ty
807785 , line "having the kind"
808− , indent $ line $ prettyPrintKind kind
786+ , indent $ line $ markCode $ prettyPrintKind kind
809787 , line "instead."
810788 ]
811789 renderSimpleErrorMessage (IncorrectConstructorArity nm) =
812− line $ "Data constructor " ++ showQualified runProperName nm ++ " was given the wrong number of arguments in a case expression."
790+ line $ "Data constructor " ++ markCode (showQualified runProperName nm) ++ " was given the wrong number of arguments in a case expression."
813791 renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
814792 paras [ line "Expression"
815− , indent $ prettyPrintValue valueDepth expr
793+ , markCodeBox $ indent $ prettyPrintValue valueDepth expr
816794 , line "does not have type"
817− , indent $ typeAsBox ty
795+ , markCodeBox $ indent $ typeAsBox ty
818796 ]
819797 renderSimpleErrorMessage (PropertyIsMissing prop) =
820− line $ "Type of expression lacks required label " ++ show prop ++ "."
798+ line $ "Type of expression lacks required label " ++ markCode prop ++ "."
821799 renderSimpleErrorMessage (AdditionalProperty prop) =
822− line $ "Type of expression contains additional label " ++ show prop ++ "."
800+ line $ "Type of expression contains additional label " ++ markCode prop ++ "."
823801 renderSimpleErrorMessage (CannotApplyFunction fn arg) =
824802 paras [ line "A function of type"
825− , indent $ typeAsBox fn
803+ , markCodeBox $ indent $ typeAsBox fn
826804 , line "can not be applied to the argument"
827− , indent $ prettyPrintValue valueDepth arg
805+ , markCodeBox $ indent $ prettyPrintValue valueDepth arg
828806 ]
829807 renderSimpleErrorMessage TypeSynonymInstance =
830808 line "Type class instances for type synonyms are disallowed."
831809 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− ]
810+ paras [ line $ "Type class instance " ++ markCode (showIdent nm) ++ " for "
811+ , markCodeBox $ indent $ Box.hsep 1 Box.left
812+ [ line (showQualified runProperName cnm)
813+ , Box.vcat Box.left (map typeAtomAsBox ts)
814+ ]
836815 , line "is an orphan instance."
837816 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
838817 , line "Consider moving the instance, if possible, or using a newtype wrapper."
839818 ]
840819 renderSimpleErrorMessage (InvalidNewtype name) =
841− paras [ line $ "Newtype " ++ runProperName name ++ " is invalid."
820+ paras [ line $ "Newtype " ++ markCode (runProperName name) ++ " is invalid."
842821 , line "Newtypes must define a single constructor with a single argument."
843822 ]
844823 renderSimpleErrorMessage (InvalidInstanceHead ty) =
845824 paras [ line "Type class instance head is invalid due to use of type"
846− , indent $ typeAsBox ty
825+ , markCodeBox $ indent $ typeAsBox ty
847826 , 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."
848827 ]
849828 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
829+ paras [ line $ "An export for " ++ markCode (prettyPrintExport x) ++ " requires the following to also be exported: "
830+ , indent $ paras $ map (line . markCode . prettyPrintExport) ys
852831 ]
853832 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
833+ paras [ line $ "An export for " ++ markCode (prettyPrintExport x) ++ " requires the following data constructor to also be exported: "
834+ , indent $ line $ markCode $ runProperName ctor
856835 ]
857836 renderSimpleErrorMessage (ShadowedName nm) =
858− line $ "Name '" ++ showIdent nm ++ "' was shadowed."
837+ line $ "Name " ++ markCode (showIdent nm) ++ " was shadowed."
859838 renderSimpleErrorMessage (ShadowedTypeVar tv) =
860− line $ "Type variable '" ++ tv ++ "' was shadowed."
839+ line $ "Type variable " ++ markCode tv ++ " was shadowed."
861840 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− ]
841+ line $ "Type variable " ++ markCode tv ++ " was declared but not used."
868842 renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
869− line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors."
843+ line $ "Importing type " ++ markCode (runProperName name ++ "(..)") ++ " from " ++ markCode (runModuleName mn) ++ " is misleading as it has no exported data constructors."
870844 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
845+ paras [ line "hiding imports cannot be used to hide modules."
846+ , line $ "An attempt was made to hide the import of " ++ markCode (runModuleName name)
873847 ]
874848 renderSimpleErrorMessage (WildcardInferredType ty) =
875849 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
850+ , markCodeBox $ indent $ typeAsBox ty
881851 ]
852+ renderSimpleErrorMessage (HoleInferredType name ty env) =
853+ paras $ [ line $ "Hole '" ++ markCode name ++ "' has the inferred type "
854+ , markCodeBox $ indent $ typeAsBox ty
855+ ] ++ if null env then [] else envInfo
856+ where
857+ envInfo :: [Box.Box]
858+ envInfo = [ line "in the following context:"
859+ , indent $ paras
860+ [ Box.hcat Box.left [ Box.text (showIdent ident <> " :: ")
861+ , markCodeBox $ typeAsBox ty'
862+ ]
863+ | (ident, ty') <- take 5 env
864+ ]
865+ ]
882866 renderSimpleErrorMessage (MissingTypeDeclaration ident ty) =
883− paras [ line $ "No type declaration was provided for the top-level declaration of " ++ showIdent ident ++ "."
867+ paras [ line $ "No type declaration was provided for the top-level declaration of " ++ markCode (showIdent ident) ++ "."
884868 , 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."
869+ , line $ "The inferred type of " ++ markCode (showIdent ident) ++ " was:"
870+ , markCodeBox $ indent $ typeAsBox ty
897871 ]
898872 renderSimpleErrorMessage (OverlappingPattern bs b) =
899873 paras $ [ line "A case expression contains unreachable cases:\n"
@@ -905,109 +879,51 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
905879 , line "You may want to decompose your data types into smaller types."
906880 ]
907881 renderSimpleErrorMessage (UnusedImport name) =
908− line $ "The import of module " ++ runModuleName name ++ " is redundant"
882+ line $ "The import of module " ++ markCode (runModuleName name) ++ " is redundant"
909883
910884 renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
911− paras [ line $ "The import of module " ++ runModuleName mn ++ " contains the following unused references:"
885+ paras [ line $ "The import of module " ++ markCode (runModuleName mn) ++ " contains the following unused references:"
912886 , indent $ paras $ map line names
913887 , line "It could be replaced with:"
914− , indent $ line $ showSuggestion msg ]
888+ , indent $ line $ markCode $ showSuggestion msg ]
915889
916890 renderSimpleErrorMessage (UnusedDctorImport name) =
917− line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
891+ line $ "The import of type " ++ markCode (runProperName name) ++ " includes data constructors but only the type is used"
918892
919893 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− ]
894+ paras [ line $ "The import of type " ++ markCode (runProperName name) ++ " includes the following unused data constructors:"
895+ , indent $ paras $ map (line . markCode . runProperName) names ]
977896
978897 renderSimpleErrorMessage (DuplicateSelectiveImport name) =
979− line $ "There is an existing import of " ++ runModuleName name ++ ", consider merging the import lists"
898+ line $ "There is an existing import of " ++ markCode (runModuleName name) ++ ", consider merging the import lists"
980899
981900 renderSimpleErrorMessage (DuplicateImport name imp qual) =
982− line $ "Duplicate import of " ++ prettyPrintImport name imp qual
901+ line $ "Duplicate import of " ++ markCode (prettyPrintImport name imp qual)
983902
984− renderSimpleErrorMessage (DuplicateImportRef ref) =
985− line $ "Import list contains multiple references to " ++ ref
903+ renderSimpleErrorMessage (DuplicateImportRef name) =
904+ line $ "Import list contains multiple references to " ++ printName (Qualified Nothing name)
986905
987− renderSimpleErrorMessage (DuplicateExportRef ref) =
988− line $ "Export list contains multiple references to " ++ ref
906+ renderSimpleErrorMessage (DuplicateExportRef name) =
907+ line $ "Export list contains multiple references to " ++ printName (Qualified Nothing name)
989908
990909 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."
910+ paras [ line $ "Integer value " ++ markCode (show value) ++ " is out of range for the " ++ backend ++ " backend."
911+ , line $ "Acceptable values fall within the range " ++ markCode (show lo) ++ " to " ++ markCode (show hi) ++ " (inclusive)." ]
996912
997913 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
914+ paras [ line $ "Module " ++ markCode (runModuleName importedModule) ++ " was imported as " ++ markCode (runModuleName asModule) ++ " with unspecified imports."
915+ , line $ "As there are multiple modules being imported as " ++ markCode (runModuleName asModule) ++ ", consider using the explicit form:"
916+ , indent $ line $ markCode $ showSuggestion msg
1001917 ]
1002918
1003919 renderSimpleErrorMessage msg@(ImplicitImport mn _) =
1004− paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
1005− , indent $ line $ showSuggestion msg
920+ paras [ line $ "Module " ++ markCode (runModuleName mn) ++ " has unspecified imports, consider using the explicit form: "
921+ , indent $ line $ markCode $ showSuggestion msg
1006922 ]
1007923
1008924 renderSimpleErrorMessage msg@(HidingImport mn _) =
1009− paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the inclusive form: "
1010− , indent $ line $ showSuggestion msg
925+ paras [ line $ "Module " ++ markCode (runModuleName mn) ++ " has unspecified imports, consider using the inclusive form: "
926+ , indent $ line $ markCode $ showSuggestion msg
1011927 ]
1012928
1013929 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
@@ -1020,7 +936,7 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1020936 line "An anonymous function argument appears in an invalid context."
1021937
1022938 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 ++ "."
939+ paras [ line $ "Operator " ++ markCode (showQualified showOp op) ++ " cannot be used in a pattern as it is an alias for function " ++ showQualified showIdent fn ++ "."
1024940 , line "Only aliases for data constructors may be used in patterns."
1025941 ]
1026942
@@ -1028,9 +944,9 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1028944 line "The require-path option is deprecated and will be removed in PureScript 0.9."
1029945
1030946 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
947+ paras [ line $ "Unable to generalize the type of the recursive function " ++ markCode (showIdent ident) ++ "."
948+ , line $ "The inferred type of " ++ markCode (showIdent ident) ++ " was:"
949+ , markCodeBox $ indent $ typeAsBox ty
1034950 , line "Try adding a type signature."
1035951 ]
1036952
@@ -1038,42 +954,43 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1038954 renderHint (ErrorUnifyingTypes t1 t2) detail =
1039955 paras [ detail
1040956 , Box.hsep 1 Box.top [ line "while trying to match type"
1041− , typeAsBox t1
957+ , markCodeBox $ typeAsBox t1
1042958 ]
1043959 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "with type"
1044− , typeAsBox t2
960+ , markCodeBox $ typeAsBox t2
1045961 ]
1046962 ]
1047963 renderHint (ErrorInExpression expr) detail =
1048964 paras [ detail
1049965 , Box.hsep 1 Box.top [ Box.text "in the expression"
1050− , prettyPrintValue valueDepth expr
966+ , markCodeBox $ markCodeBox $ prettyPrintValue valueDepth expr
1051967 ]
1052968 ]
1053969 renderHint (ErrorInModule mn) detail =
1054− paras [ line $ "in module " ++ runModuleName mn
970+ paras [ line $ "in module " ++ markCode (runModuleName mn)
1055971 , detail
1056972 ]
1057973 renderHint (ErrorInSubsumption t1 t2) detail =
1058974 paras [ detail
1059975 , Box.hsep 1 Box.top [ line "while checking that type"
1060− , typeAsBox t1
976+ , markCodeBox $ typeAsBox t1
1061977 ]
1062978 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "is at least as general as type"
1063− , typeAsBox t2
979+ , markCodeBox $ typeAsBox t2
1064980 ]
1065981 ]
1066982 renderHint (ErrorInInstance nm ts) detail =
1067983 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− ]
984+ , line "in type class instance"
985+ , markCodeBox $ indent $ Box.hsep 1 Box.top
986+ [ line $ showQualified runProperName nm
987+ , Box.vcat Box.left (map typeAtomAsBox ts)
988+ ]
1072989 ]
1073990 renderHint (ErrorCheckingKind ty) detail =
1074991 paras [ detail
1075992 , Box.hsep 1 Box.top [ line "while checking the kind of"
1076− , typeAsBox ty
993+ , markCodeBox $ typeAsBox ty
1077994 ]
1078995 ]
1079996 renderHint ErrorCheckingGuard detail =
@@ -1083,43 +1000,43 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
10831000 renderHint (ErrorInferringType expr) detail =
10841001 paras [ detail
10851002 , Box.hsep 1 Box.top [ line "while inferring the type of"
1086− , prettyPrintValue valueDepth expr
1003+ , markCodeBox $ prettyPrintValue valueDepth expr
10871004 ]
10881005 ]
10891006 renderHint (ErrorCheckingType expr ty) detail =
10901007 paras [ detail
10911008 , Box.hsep 1 Box.top [ line "while checking that expression"
1092− , prettyPrintValue valueDepth expr
1009+ , markCodeBox $ prettyPrintValue valueDepth expr
10931010 ]
10941011 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "has type"
1095− , typeAsBox ty
1012+ , markCodeBox $ typeAsBox ty
10961013 ]
10971014 ]
10981015 renderHint (ErrorCheckingAccessor expr prop) detail =
10991016 paras [ detail
11001017 , Box.hsep 1 Box.top [ line "while checking type of property accessor"
1101− , prettyPrintValue valueDepth (Accessor prop expr)
1018+ , markCodeBox $ prettyPrintValue valueDepth (Accessor prop expr)
11021019 ]
11031020 ]
11041021 renderHint (ErrorInApplication f t a) detail =
11051022 paras [ detail
11061023 , Box.hsep 1 Box.top [ line "while applying a function"
1107− , prettyPrintValue valueDepth f
1024+ , markCodeBox $ prettyPrintValue valueDepth f
11081025 ]
11091026 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "of type"
1110− , typeAsBox t
1027+ , markCodeBox $ typeAsBox t
11111028 ]
11121029 , Box.moveRight 2 $ Box.hsep 1 Box.top [ line "to argument"
1113− , prettyPrintValue valueDepth a
1030+ , markCodeBox $ prettyPrintValue valueDepth a
11141031 ]
11151032 ]
11161033 renderHint (ErrorInDataConstructor nm) detail =
11171034 paras [ detail
1118− , line $ "in data constructor " ++ runProperName nm
1035+ , line $ "in data constructor " ++ markCode (runProperName nm)
11191036 ]
11201037 renderHint (ErrorInTypeConstructor nm) detail =
11211038 paras [ detail
1122− , line $ "in type constructor " ++ runProperName nm
1039+ , line $ "in type constructor " ++ markCode (runProperName nm)
11231040 ]
11241041 renderHint (ErrorInBindingGroup nms) detail =
11251042 paras [ detail
@@ -1131,25 +1048,55 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
11311048 ]
11321049 renderHint (ErrorInTypeSynonym name) detail =
11331050 paras [ detail
1134− , line $ "in type synonym " ++ runProperName name
1051+ , line $ "in type synonym " ++ markCode (runProperName name)
11351052 ]
11361053 renderHint (ErrorInValueDeclaration n) detail =
11371054 paras [ detail
1138− , line $ "in value declaration " ++ showIdent n
1055+ , line $ "in value declaration " ++ markCode (showIdent n)
11391056 ]
11401057 renderHint (ErrorInTypeDeclaration n) detail =
11411058 paras [ detail
1142− , line $ "in type declaration for " ++ showIdent n
1059+ , line $ "in type declaration for " ++ markCode (showIdent n)
11431060 ]
11441061 renderHint (ErrorInForeignImport nm) detail =
11451062 paras [ detail
1146− , line $ "in foreign import " ++ showIdent nm
1063+ , line $ "in foreign import " ++ markCode (showIdent nm)
11471064 ]
11481065 renderHint (PositionedError srcSpan) detail =
11491066 paras [ line $ "at " ++ displaySourceSpan srcSpan
11501067 , detail
11511068 ]
11521069
1070+ printName :: Qualified Name -> String
1071+ printName qn = nameType (disqualify qn) ++ " " ++ markCode (runName qn)
1072+
1073+ nameType :: Name -> String
1074+ nameType (IdentName _) = "value"
1075+ nameType (ValOpName _) = "operator"
1076+ nameType (TyName _) = "type"
1077+ nameType (TyOpName _) = "type operator"
1078+ nameType (DctorName _) = "data constructor"
1079+ nameType (TyClassName _) = "type class"
1080+ nameType (ModName _) = "module"
1081+
1082+ runName :: Qualified Name -> String
1083+ runName (Qualified mn (IdentName name)) =
1084+ showQualified showIdent (Qualified mn name)
1085+ runName (Qualified mn (ValOpName op)) =
1086+ showQualified showOp (Qualified mn op)
1087+ runName (Qualified mn (TyName name)) =
1088+ showQualified runProperName (Qualified mn name)
1089+ runName (Qualified mn (TyOpName op)) =
1090+ showQualified showOp (Qualified mn op)
1091+ runName (Qualified mn (DctorName name)) =
1092+ showQualified runProperName (Qualified mn name)
1093+ runName (Qualified mn (TyClassName name)) =
1094+ showQualified runProperName (Qualified mn name)
1095+ runName (Qualified Nothing (ModName name)) =
1096+ runModuleName name
1097+ runName (Qualified _ ModName{}) =
1098+ internalError "qualified ModName in runName"
1099+
11531100 valueDepth :: Int
11541101 valueDepth | full = 1000
11551102 | otherwise = 3
@@ -1230,10 +1177,10 @@ prettyPrintRef :: DeclarationRef -> String
12301177prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
12311178prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
12321179prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1233−prettyPrintRef (TypeOpRef ident) = "type " ++ showIdent ident
1180+prettyPrintRef (TypeOpRef op) = "type " ++ showOp op
12341181prettyPrintRef (ValueRef ident) = showIdent ident
1182+prettyPrintRef (ValueOpRef op) = showOp op
12351183prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1236−prettyPrintRef (ProperRef name) = name
12371184prettyPrintRef (TypeInstanceRef ident) = showIdent ident
12381185prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
12391186prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
@@ -1241,32 +1188,32 @@ prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
12411188-- |
12421189-- Pretty print multiple errors
12431190--
1244−prettyPrintMultipleErrors :: Bool -> MultipleErrors -> String
1245−prettyPrintMultipleErrors full = unlines . map renderBox . prettyPrintMultipleErrorsBox full
1191+prettyPrintMultipleErrors :: PPEOptions -> MultipleErrors -> String
1192+prettyPrintMultipleErrors ppeOptions = unlines . map renderBox . prettyPrintMultipleErrorsBox ppeOptions
12461193
12471194-- |
12481195-- Pretty print multiple warnings
12491196--
1250−prettyPrintMultipleWarnings :: Bool -> MultipleErrors -> String
1251−prettyPrintMultipleWarnings full = unlines . map renderBox . prettyPrintMultipleWarningsBox full
1197+prettyPrintMultipleWarnings :: PPEOptions -> MultipleErrors -> String
1198+prettyPrintMultipleWarnings ppeOptions = unlines . map renderBox . prettyPrintMultipleWarningsBox ppeOptions
12521199
12531200-- | Pretty print warnings as a Box
1254−prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> [Box.Box]
1255−prettyPrintMultipleWarningsBox = prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning"
1201+prettyPrintMultipleWarningsBox :: PPEOptions -> MultipleErrors -> [Box.Box]
1202+prettyPrintMultipleWarningsBox ppeOptions = prettyPrintMultipleErrorsWith (ppeOptions { ppeLevel = Warning }) "Warning found:" "Warning"
12561203
12571204-- | Pretty print errors as a Box
1258−prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> [Box.Box]
1259−prettyPrintMultipleErrorsBox = prettyPrintMultipleErrorsWith Error "Error found:" "Error"
1205+prettyPrintMultipleErrorsBox :: PPEOptions -> MultipleErrors -> [Box.Box]
1206+prettyPrintMultipleErrorsBox ppeOptions = prettyPrintMultipleErrorsWith (ppeOptions { ppeLevel = Error }) "Error found:" "Error"
12601207
1261−prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> [Box.Box]
1262−prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) =
1263− let result = prettyPrintSingleError full level True e
1208+prettyPrintMultipleErrorsWith :: PPEOptions -> String -> String -> MultipleErrors -> [Box.Box]
1209+prettyPrintMultipleErrorsWith ppeOptions intro _ (MultipleErrors [e]) =
1210+ let result = prettyPrintSingleError ppeOptions e
12641211 in [ Box.vcat Box.left [ Box.text intro
12651212 , result
12661213 ]
12671214 ]
1268−prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) =
1269− let result = map (prettyPrintSingleError full level True) es
1215+prettyPrintMultipleErrorsWith ppeOptions _ intro (MultipleErrors es) =
1216+ let result = map (prettyPrintSingleError ppeOptions) es
12701217 in concat $ zipWith withIntro [1 :: Int ..] result
12711218 where
12721219 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+39−21
@@ -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,6 +46,8 @@ 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]
5353 } deriving (Show, Read)
@@ -71,9 +71,22 @@ data ExternsFixity = ExternsFixity
7171 -- | The precedence level of the operator
7272 , efPrecedence :: Precedence
7373 -- | The operator symbol
74− , efOperator :: String
74+ , efOperator :: OpName 'ValueOpName
7575 -- | The value the operator is an alias for
76− , efAlias :: Maybe (Qualified FixityAlias)
76+ , efAlias :: Qualified (Either Ident (ProperName 'ConstructorName))
77+ } deriving (Show, Read)
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
88+ -- | The value the operator is an alias for
89+ , efTypeAlias :: Qualified (ProperName 'TypeName)
7790 } deriving (Show, Read)
7891
7992-- | A type or value declaration appearing in an externs file
@@ -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
@@ -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+16−16
@@ -12,13 +12,9 @@
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
@@ -40,6 +36,7 @@ import Data.Maybe (catMaybes, mapMaybe)
4036import Data.Monoid
4137import Data.Text (Text)
4238import qualified Data.Text as T
39+import qualified Language.PureScript as P
4340import qualified Language.PureScript.Ide.CaseSplit as CS
4441import Language.PureScript.Ide.Command
4542import Language.PureScript.Ide.Completion
@@ -64,10 +61,10 @@ handleCommand :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
6461handleCommand (Load [] []) = loadAllModules
6562handleCommand (Load modules deps) =
6663 loadModulesAndDeps modules deps
67−handleCommand (Type search filters) =
68− findType search filters
69−handleCommand (Complete filters matcher) =
70− findCompletions filters matcher
64+handleCommand (Type search filters currentModule) =
65+ findType search filters currentModule
66+handleCommand (Complete filters matcher currentModule) =
67+ findCompletions filters matcher currentModule
7168handleCommand (Pursuit query Package) =
7269 findPursuitPackages query
7370handleCommand (Pursuit query Identifier) =
@@ -94,17 +91,20 @@ handleCommand (Rebuild file) =
9491 rebuildFile file
9592handleCommand Cwd =
9693 TextResult . T.pack <$> liftIO getCurrentDirectory
94+handleCommand Reset = resetPscIdeState *> pure (TextResult "State has been reset.")
9795handleCommand Quit = liftIO exitSuccess
9896
9997findCompletions :: (PscIde m, MonadLogger m) =>
100− [Filter] -> Matcher -> m Success
101−findCompletions filters matcher =
102− CompletionResult . mapMaybe completionFromMatch . getCompletions filters matcher <$> getAllModulesWithReexports
98+ [Filter] -> Matcher -> Maybe P.ModuleName -> m Success
99+findCompletions filters matcher currentModule = do
100+ modules <- getAllModulesWithReexportsAndCache currentModule
101+ pure . CompletionResult . mapMaybe completionFromMatch . getCompletions filters matcher $ modules
103102
104103findType :: (PscIde m, MonadLogger m) =>
105− DeclIdent -> [Filter] -> m Success
106−findType search filters =
107− CompletionResult . mapMaybe completionFromMatch . getExactMatches search filters <$> getAllModulesWithReexports
104+ DeclIdent -> [Filter] -> Maybe P.ModuleName -> m Success
105+findType search filters currentModule = do
106+ modules <- getAllModulesWithReexportsAndCache currentModule
107+ pure . CompletionResult . mapMaybe completionFromMatch . getExactMatches search filters $ modules
108108
109109findPursuitCompletions :: (MonadIO m, MonadLogger m) =>
110110 PursuitQuery -> m Success
@@ -116,14 +116,14 @@ findPursuitPackages :: (MonadIO m, MonadLogger m) =>
116116findPursuitPackages (PursuitQuery q) =
117117 PursuitResult <$> liftIO (findPackagesForModuleIdent q)
118118
119−loadExtern ::(PscIde m, MonadLogger m, MonadError PscIdeError m) =>
119+loadExtern :: (PscIde m, MonadLogger m, MonadError PscIdeError m) =>
120120 FilePath -> m ()
121121loadExtern fp = do
122122 m <- readExternFile fp
123123 insertModule m
124124
125125printModules :: (PscIde m) => m Success
126−printModules = printModules' <$> getPscIdeState
126+printModules = printModules' . pscIdeStateModules <$> getPscIdeState
127127
128128printModules' :: M.Map ModuleIdent [ExternDecl] -> Success
129129printModules' = ModuleList . M.keys
src/Language/PureScript/Ide/CaseSplit.hs−6
@@ -12,14 +12,8 @@
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 #-}
2116{-# LANGUAGE PackageImports #-}
22−{-# LANGUAGE RecordWildCards #-}
2317
2418module Language.PureScript.Ide.CaseSplit
2519 ( WildcardAnnotations()
src/Language/PureScript/Ide/Command.hs+58−60
@@ -12,9 +12,7 @@
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
@@ -23,10 +21,8 @@ import Prelude.Compat
2321
2422import Control.Monad
2523import Data.Aeson
26−import Data.Maybe
2724import Data.Text (Text)
28−import Language.PureScript (ModuleName,
29− moduleNameFromString)
25+import qualified Language.PureScript as P
3026import Language.PureScript.Ide.CaseSplit
3127import Language.PureScript.Ide.Filter
3228import Language.PureScript.Ide.Matcher
@@ -38,12 +34,14 @@ data Command
3834 , loadDependencies :: [ModuleIdent]
3935 }
4036 | Type
41− { typeSearch :: DeclIdent
42− , typeFilters :: [Filter]
37+ { typeSearch :: DeclIdent
38+ , typeFilters :: [Filter]
39+ , typeCurrentModule :: Maybe P.ModuleName
4340 }
4441 | Complete
45− { completeFilters :: [Filter]
46− , completeMatcher :: Matcher
42+ { completeFilters :: [Filter]
43+ , completeMatcher :: Matcher
44+ , completeCurrentModule :: Maybe P.ModuleName
4745 }
4846 | Pursuit
4947 { pursuitQuery :: PursuitQuery
@@ -65,10 +63,11 @@ data Command
6563 | List { listType :: ListType }
6664 | Rebuild FilePath -- ^ Rebuild the specified file using the loaded externs
6765 | Cwd
66+ | Reset
6867 | Quit
6968
7069data ImportCommand
71− = AddImplicitImport ModuleName
70+ = AddImplicitImport P.ModuleName
7271 | AddImportForIdentifier DeclIdent
7372 deriving (Show, Eq)
7473
@@ -76,12 +75,10 @@ instance FromJSON ImportCommand where
7675 parseJSON = withObject "ImportCommand" $ \o -> do
7776 (command :: String) <- o .: "importCommand"
7877 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)
78+ "addImplicitImport" ->
79+ AddImplicitImport <$> (P.moduleNameFromString <$> o .: "module")
80+ "addImport" ->
81+ AddImportForIdentifier <$> o .: "identifier"
8582 _ -> mzero
8683
8784data ListType = LoadedModules | Imports FilePath | AvailableModules
@@ -90,68 +87,69 @@ instance FromJSON ListType where
9087 parseJSON = withObject "ListType" $ \o -> do
9188 (listType' :: String) <- o .: "type"
9289 case listType' of
93− "import" -> do
94− fp <- o .: "file"
95− return (Imports fp)
96− "loadedModules" -> return LoadedModules
97− "availableModules" -> return AvailableModules
90+ "import" -> Imports <$> o .: "file"
91+ "loadedModules" -> pure LoadedModules
92+ "availableModules" -> pure AvailableModules
9893 _ -> mzero
9994
10095instance FromJSON Command where
10196 parseJSON = withObject "command" $ \o -> do
10297 (command :: String) <- o .: "command"
10398 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"
99+ "list" -> List <$> o .:? "params" .!= LoadedModules
100+ "cwd" -> pure Cwd
101+ "quit" -> pure Quit
102+ "reset" -> pure Reset
103+ "load" -> do
104+ params' <- o .:? "params"
105+ case params' of
106+ Nothing -> pure (Load [] [])
107+ Just params ->
108+ Load
109+ <$> params .:? "modules" .!= []
110+ <*> params .:? "dependencies" .!= []
114111 "type" -> do
115112 params <- o .: "params"
116− search <- params .: "search"
117− filters <- params .: "filters"
118− return $ Type search filters
113+ Type
114+ <$> params .: "search"
115+ <*> params .: "filters"
116+ <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")
119117 "complete" -> do
120118 params <- o .: "params"
121− filters <- params .:? "filters"
122− matcher <- params .:? "matcher"
123− return $ Complete (fromMaybe [] filters) (fromMaybe mempty matcher)
119+ Complete
120+ <$> params .:? "filters" .!= []
121+ <*> params .:? "matcher" .!= mempty
122+ <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")
124123 "pursuit" -> do
125124 params <- o .: "params"
126− query <- params .: "query"
127− queryType <- params .: "type"
128− return $ Pursuit query queryType
125+ Pursuit
126+ <$> params .: "query"
127+ <*> params .: "type"
129128 "caseSplit" -> do
130129 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'
130+ CaseSplit
131+ <$> params .: "line"
132+ <*> params .: "begin"
133+ <*> params .: "end"
134+ <*> (mkAnnotations <$> params .: "annotations")
135+ <*> params .: "type"
139136 "addClause" -> do
140137 params <- o .: "params"
141− line <- params .: "line"
142− annotations <- params .: "annotations"
143− return $ AddClause line (if annotations
144− then explicitAnnotations
145− else noAnnotations)
138+ AddClause
139+ <$> params .: "line"
140+ <*> (mkAnnotations <$> params .: "annotations")
146141 "import" -> do
147142 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
143+ Import
144+ <$> params .: "file"
145+ <*> params .:? "outfile"
146+ <*> params .:? "filters" .!= []
147+ <*> params .: "importCommand"
153148 "rebuild" -> do
154149 params <- o .: "params"
155− filePath <- params .: "file"
156− return $ Rebuild filePath
150+ Rebuild
151+ <$> params .: "file"
157152 _ -> mzero
153+ where
154+ mkAnnotations True = explicitAnnotations
155+ mkAnnotations False = noAnnotations
src/Language/PureScript/Ide/Error.hs+1
@@ -17,6 +17,7 @@ module Language.PureScript.Ide.Error
1717 (ErrorMsg, PscIdeError(..), textError)
1818 where
1919
20+import Prelude.Compat
2021import Data.Aeson
2122import Data.Monoid
2223import Data.Text (Text, pack)
src/Language/PureScript/Ide/Externs.hs+35−24
@@ -12,11 +12,7 @@
1212-- Handles externs files for psc-ide
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
1715{-# LANGUAGE OverloadedStrings #-}
18−{-# LANGUAGE RecordWildCards #-}
19−{-# LANGUAGE ScopedTypeVariables #-}
2016
2117module Language.PureScript.Ide.Externs
2218 ( ExternDecl(..),
@@ -45,10 +41,9 @@ import Language.PureScript.Ide.Types
4541import Language.PureScript.Ide.Util
4642
4743import qualified Language.PureScript as P
48−import qualified Language.PureScript.Externs as PE
4944
5045readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
51− FilePath -> m PE.ExternsFile
46+ FilePath -> m P.ExternsFile
5247readExternFile fp = do
5348 parseResult <- liftIO (decodeStrict <$> BS.readFile fp)
5449 case parseResult of
@@ -61,15 +56,15 @@ moduleNameToText = T.pack . P.runModuleName
6156identToText :: P.Ident -> Text
6257identToText = T.pack . P.runIdent
6358
64−convertExterns :: PE.ExternsFile -> Module
65−convertExterns ef = (moduleName, exportDecls ++ importDecls ++ decls)
59+convertExterns :: P.ExternsFile -> Module
60+convertExterns ef = (moduleName, exportDecls ++ importDecls ++ decls ++ operatorDecls ++ tyOperatorDecls)
6661 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)
62+ moduleName = moduleNameToText (P.efModuleName ef)
63+ importDecls = convertImport <$> P.efImports ef
64+ exportDecls = mapMaybe (convertExport . unwrapPositionedRef) (P.efExports ef)
65+ operatorDecls = convertOperator <$> P.efFixities ef
66+ tyOperatorDecls = convertTypeOperator <$> P.efTypeFixities ef
67+ otherDecls = mapMaybe convertDecl (P.efDeclarations ef)
7368
7469 typeClassFilter = foldMap removeTypeDeclarationsForClass (filter isTypeClassDeclaration otherDecls)
7570 decls = nub $ appEndo typeClassFilter otherDecls
@@ -85,26 +80,42 @@ isTypeClassDeclaration :: ExternDecl -> Bool
8580isTypeClassDeclaration TypeClassDeclaration{} = True
8681isTypeClassDeclaration _ = False
8782
88−convertImport :: PE.ExternsImport -> ExternDecl
83+convertImport :: P.ExternsImport -> ExternDecl
8984convertImport ei = Dependency
90− (moduleNameToText (PE.eiModule ei))
85+ (moduleNameToText (P.eiModule ei))
9186 []
92− (moduleNameToText <$> PE.eiImportedAs ei)
87+ (moduleNameToText <$> P.eiImportedAs ei)
9388
9489convertExport :: P.DeclarationRef -> Maybe ExternDecl
9590convertExport (P.ModuleRef mn) = Just (Export (moduleNameToText mn))
9691convertExport _ = Nothing
9792
98−convertDecl :: PE.ExternsDeclaration -> Maybe ExternDecl
99−convertDecl PE.EDType{..} = Just $ TypeDeclaration edTypeName edTypeKind
100−convertDecl PE.EDTypeSynonym{..} = Just $
93+convertDecl :: P.ExternsDeclaration -> Maybe ExternDecl
94+convertDecl P.EDType{..} = Just $ TypeDeclaration edTypeName edTypeKind
95+convertDecl P.EDTypeSynonym{..} = Just $
10196 TypeSynonymDeclaration edTypeSynonymName edTypeSynonymType
102−convertDecl PE.EDDataConstructor{..} = Just $
97+convertDecl P.EDDataConstructor{..} = Just $
10398 DataConstructor (runProperNameT edDataCtorName) edDataCtorTypeCtor edDataCtorType
104−convertDecl PE.EDValue{..} = Just $
99+convertDecl P.EDValue{..} = Just $
105100 ValueDeclaration (identToText edValueName) edValueType
106−convertDecl PE.EDClass{..} = Just $ TypeClassDeclaration edClassName
107−convertDecl PE.EDInstance{} = Nothing
101+convertDecl P.EDClass{..} = Just $ TypeClassDeclaration edClassName
102+convertDecl P.EDInstance{} = Nothing
103+
104+convertOperator :: P.ExternsFixity -> ExternDecl
105+convertOperator P.ExternsFixity{..} =
106+ ValueOperator
107+ efOperator
108+ (T.pack (P.showQualified (either P.runIdent P.runProperName) efAlias))
109+ efPrecedence
110+ efAssociativity
111+
112+convertTypeOperator :: P.ExternsTypeFixity -> ExternDecl
113+convertTypeOperator P.ExternsTypeFixity{..} =
114+ TypeOperator
115+ efTypeOperator
116+ (T.pack (P.showQualified P.runProperName efTypeAlias))
117+ efTypePrecedence
118+ efTypeAssociativity
108119
109120unwrapPositioned :: P.Declaration -> P.Declaration
110121unwrapPositioned (P.PositionedDeclaration _ _ x) = x
src/Language/PureScript/Ide/Filter.hs−1
@@ -14,7 +14,6 @@
1414
1515{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1616{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
1817
1918module Language.PureScript.Ide.Filter
2019 ( Filter
src/Language/PureScript/Ide/Imports.hs+15−23
@@ -12,10 +12,6 @@
1212-- Provides functionality to manage imports
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE LambdaCase #-}
18−{-# LANGUAGE MultiParamTypeClasses #-}
1915{-# LANGUAGE OverloadedStrings #-}
2016{-# LANGUAGE PackageImports #-}
2117
@@ -34,6 +30,7 @@ module Language.PureScript.Ide.Imports
3430 )
3531 where
3632
33+import Prelude.Compat
3734import Control.Applicative ((<|>))
3835import Control.Monad.Error.Class
3936import Control.Monad.IO.Class
@@ -95,9 +92,9 @@ parseImportsWithModuleName ls = do
9592 (P.Module _ _ mn decls _) <- moduleParse ls
9693 pure (mn, concatMap mkImport (unwrapPositioned <$> decls))
9794 where
98− mkImport (P.ImportDeclaration mn (P.Explicit refs) qual _) =
95+ mkImport (P.ImportDeclaration mn (P.Explicit refs) qual) =
9996 [Import mn (P.Explicit (unwrapPositionedRef <$> refs)) qual]
100− mkImport (P.ImportDeclaration mn it qual _) = [Import mn it qual]
97+ mkImport (P.ImportDeclaration mn it qual) = [Import mn it qual]
10198 mkImport _ = []
10299
103100sliceImportSection :: [Text] -> Either String (P.ModuleName, [Text], [Import], [Text])
@@ -212,15 +209,18 @@ addExplicitImport' decl moduleName imports =
212209 then imports
213210 else updateAtFirstOrPrepend matches (insertDeclIntoImport decl) freshImport imports
214211 where
215− refFromDeclaration (TypeClassDeclaration n) = P.TypeClassRef n
212+ refFromDeclaration (TypeClassDeclaration n) =
213+ P.TypeClassRef n
216214 refFromDeclaration (DataConstructor n tn _) =
217215 P.TypeRef tn (Just [P.ProperName (T.unpack n)])
218− refFromDeclaration (TypeDeclaration n _) = P.TypeRef n (Just [])
216+ refFromDeclaration (TypeDeclaration n _) =
217+ P.TypeRef n (Just [])
218+ refFromDeclaration (ValueOperator op _ _ _) =
219+ P.ValueOpRef op
220+ refFromDeclaration (TypeOperator op _ _ _) =
221+ P.TypeOpRef op
219222 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)
223+ P.ValueRef $ P.Ident $ T.unpack (identifierFromExternDecl d)
224224
225225 -- | Adds a declaration to an import:
226226 -- TypeDeclaration "Maybe" + Data.Maybe (maybe) -> Data.Maybe(Maybe, maybe)
@@ -233,10 +233,8 @@ addExplicitImport' decl moduleName imports =
233233 insertDeclIntoRefs (DataConstructor dtor tn _) refs =
234234 let
235235 dtor' = P.ProperName (T.unpack dtor)
236− -- TODO: Get rid of this once typeclasses can't be imported like types
237− refs' = properRefToTypeRef <$> refs
238236 in
239− updateAtFirstOrPrepend (matchType tn) (insertDtor dtor') (P.TypeRef tn (Just [dtor'])) refs'
237+ updateAtFirstOrPrepend (matchType tn) (insertDtor dtor') (P.TypeRef tn (Just [dtor'])) refs
240238 insertDeclIntoRefs dr refs = List.nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
241239
242240 insertDtor dtor (P.TypeRef tn' dtors) =
@@ -247,11 +245,6 @@ addExplicitImport' decl moduleName imports =
247245 Nothing -> P.TypeRef tn' Nothing
248246 insertDtor _ refs = refs
249247
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−
255248 matchType :: P.ProperName 'P.TypeName -> P.DeclarationRef -> Bool
256249 matchType tn (P.TypeRef n _) = tn == n
257250 matchType _ _ = False
@@ -348,8 +341,7 @@ parseImport :: Text -> Maybe Import
348341parseImport t =
349342 case P.lex "<psc-ide>" (T.unpack t)
350343 >>= P.runTokenParser "<psc-ide>" P.parseImportDeclaration' of
351− Right (mn, P.Explicit refs, mmn, _) ->
344+ Right (mn, P.Explicit refs, mmn) ->
352345 Just (Import mn (P.Explicit (unwrapPositionedRef <$> refs)) mmn)
353− Right (mn, idt, mmn, _) -> Just (Import mn idt mmn)
346+ Right (mn, idt, mmn) -> Just (Import mn idt mmn)
354347 Left _ -> Nothing
355−
src/Language/PureScript/Ide/Matcher.hs−1
@@ -14,7 +14,6 @@
1414
1515{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1616{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE ScopedTypeVariables #-}
1817
1918module Language.PureScript.Ide.Matcher
2019 ( Matcher
src/Language/PureScript/Ide/Pursuit.hs−1
@@ -13,7 +13,6 @@
1313-----------------------------------------------------------------------------
1414
1515{-# LANGUAGE OverloadedStrings #-}
16−{-# LANGUAGE ScopedTypeVariables #-}
1716
1817module Language.PureScript.Ide.Pursuit where
1918
src/Language/PureScript/Ide/Rebuild.hs+116−35
@@ -1,74 +1,151 @@
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
10−
11−import Language.PureScript.Ide.Error
12−import Language.PureScript.Ide.State
13−import Language.PureScript.Ide.Types
7+module Language.PureScript.Ide.Rebuild
8+ ( rebuildFile
9+ ) where
1410
1511import Control.Monad.Error.Class
1612import Control.Monad.IO.Class
1713import "monad-logger" Control.Monad.Logger
18−import Control.Monad.Reader.Class
14+import Control.Monad.Reader
1915import Control.Monad.Trans.Except
2016import qualified Data.Map.Lazy as M
2117import Data.Maybe (fromJust, mapMaybe)
18+import Data.Monoid ((<>))
2219import qualified Data.Set as S
2320import qualified Language.PureScript as P
2421import 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)
22+import Language.PureScript.Ide.Error
23+import Language.PureScript.Ide.State
24+import Language.PureScript.Ide.Types
25+import Language.PureScript.Ide.Util
26+import Prelude.Compat
27+import System.IO.UTF8 (readUTF8File)
2928
29+-- | Given a filepath performs the following steps:
30+--
31+-- * Reads and parses a PureScript module from the filepath.
32+--
33+-- * Builds a dependency graph for the parsed module from the already loaded
34+-- ExternsFiles.
35+--
36+-- * Attempts to find an FFI definition file for the module by looking
37+-- for a file with the same filepath except for a .js extension.
38+--
39+-- * Passes all the created artifacts to @rebuildModule@.
40+--
41+-- * If the rebuilding succeeds, returns a @RebuildSuccess@ with the generated
42+-- warnings, and if rebuilding fails, returns a @RebuildError@ with the
43+-- generated errors.
3044rebuildFile
3145 :: (PscIde m, MonadLogger m, MonadError PscIdeError m)
3246 => FilePath
3347 -> m Success
3448rebuildFile path = do
3549
36− input <- liftIO $ readUTF8File path
50+ input <- liftIO (readUTF8File path)
3751
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."
52+ m <- case snd <$> P.parseModuleFromFile id (path, input) of
53+ Left parseError -> throwError
54+ . RebuildError
55+ . toJSONErrors False P.Error
56+ $ P.MultipleErrors [P.toPositionedError parseError]
57+ Right m -> pure m
4358
44− externs <- sortExterns m . M.delete (P.getModuleName m) =<< getExternFiles
59+ -- Externs files must be sorted ahead of time, so that they get applied
60+ -- correctly to the 'Environment'.
61+ externs <- sortExterns m =<< getExternFiles
4562
4663 outputDirectory <- confOutputPath . envConfiguration <$> ask
4764
48− let foreignModule = replaceExtension path "js"
49− foreignExists <- liftIO (doesFileExist foreignModule)
65+ -- For rebuilding, we want to 'RebuildAlways', but for inferring foreign
66+ -- modules using their file paths, we need to specify the path in the 'Map'.
67+ let filePathMap = M.singleton (P.getModuleName m) (Left P.RebuildAlways)
68+ foreigns <- P.inferForeignModules (M.singleton (P.getModuleName m) (Right path))
5069
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
70+ let makeEnv = MakeActionsEnv outputDirectory filePathMap foreigns False
71+ -- Rebuild the single module using the cached externs
5772 (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
73+ . P.runMake P.defaultOptions
74+ . P.rebuildModule (buildMakeActions
75+ >>= shushProgress $ makeEnv) externs $ m
6176 case result of
62− Left errors -> throwError . RebuildError $ toJSONErrors False P.Error errors
63− Right _ -> pure . RebuildSuccess $ toJSONErrors False P.Warning warnings
77+ Left errors -> throwError (RebuildError (toJSONErrors False P.Error errors))
78+ Right _ -> do
79+ rebuildModuleOpen makeEnv externs m
80+ pure (RebuildSuccess (toJSONErrors False P.Warning warnings))
6481
82+-- | Rebuilds a module but opens up its export list first and stores the result
83+-- inside the rebuild cache
84+rebuildModuleOpen
85+ :: (PscIde m, MonadLogger m, MonadError PscIdeError m)
86+ => MakeActionsEnv
87+ -> [P.ExternsFile]
88+ -> P.Module
89+ -> m ()
90+rebuildModuleOpen makeEnv externs m = do
91+ (openResult, _) <- liftIO
92+ . P.runMake P.defaultOptions
93+ . P.rebuildModule (buildMakeActions
94+ >>= shushProgress
95+ >>= shushCodegen
96+ $ makeEnv) externs $ openModuleExports m
97+ case openResult of
98+ Left _ ->
99+ throwError (GeneralError "Failed when rebuilding with open exports")
100+ Right result -> do
101+ $(logDebug)
102+ ("Setting Rebuild cache: " <> runModuleNameT (P.efModuleName result))
103+ setCachedRebuild result
104+
105+-- | Parameters we can access while building our @MakeActions@
106+data MakeActionsEnv =
107+ MakeActionsEnv
108+ { maeOutputDirectory :: FilePath
109+ , maeFilePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
110+ , maeForeignPathMap :: M.Map P.ModuleName FilePath
111+ , maePrefixComment :: Bool
112+ }
113+
114+-- | Builds the default @MakeActions@ from a @MakeActionsEnv@
115+buildMakeActions :: MakeActionsEnv -> P.MakeActions P.Make
116+buildMakeActions MakeActionsEnv{..} =
117+ P.buildMakeActions
118+ maeOutputDirectory
119+ maeFilePathMap
120+ maeForeignPathMap
121+ maePrefixComment
122+
123+-- | Shuts the compiler up about progress messages
124+shushProgress :: P.MakeActions P.Make -> MakeActionsEnv -> P.MakeActions P.Make
125+shushProgress ma _ =
126+ ma { P.progress = \_ -> pure () }
127+
128+-- | Stops any kind of codegen (also silences errors about missing or unused FFI
129+-- files though)
130+shushCodegen :: P.MakeActions P.Make -> MakeActionsEnv -> P.MakeActions P.Make
131+shushCodegen ma MakeActionsEnv{..} =
132+ ma { P.codegen = \_ _ _ -> pure () }
133+
134+-- | Returns a topologically sorted list of dependent ExternsFiles for the given
135+-- module. Throws an error if there is a cyclic dependency within the
136+-- ExternsFiles
65137sortExterns
66138 :: (PscIde m, MonadError PscIdeError m)
67139 => P.Module
68140 -> M.Map P.ModuleName P.ExternsFile
69141 -> m [P.ExternsFile]
70142sortExterns m ex = do
71− sorted' <- runExceptT . P.sortModules . (:) m . map mkShallowModule . M.elems $ ex
143+ sorted' <- runExceptT
144+ . P.sortModules
145+ . (:) m
146+ . map mkShallowModule
147+ . M.elems
148+ . M.delete (P.getModuleName m) $ ex
72149 case sorted' of
73150 Left _ -> throwError (GeneralError "There was a cycle in the dependencies")
74151 Right (sorted, graph) -> do
@@ -78,8 +155,12 @@ sortExterns m ex = do
78155 mkShallowModule P.ExternsFile{..} =
79156 P.Module undefined [] efModuleName (map mkImport efImports) Nothing
80157 mkImport (P.ExternsImport mn it iq) =
81− P.ImportDeclaration mn it iq False
158+ P.ImportDeclaration mn it iq
82159 getExtern mn = M.lookup mn ex
83160 -- Sort a list so its elements appear in the same order as in another list.
84161 inOrderOf :: (Ord a) => [a] -> [a] -> [a]
85162 inOrderOf xs ys = let s = S.fromList xs in filter (`S.member` s) ys
163+
164+-- | Removes a modules export list.
165+openModuleExports :: P.Module -> P.Module
166+openModuleExports (P.Module ss cs mn decls _) = P.Module ss cs mn decls Nothing
src/Language/PureScript/Ide/Reexports.hs−2
@@ -14,8 +14,6 @@
1414-----------------------------------------------------------------------------
1515
1616{-# LANGUAGE OverloadedStrings #-}
17−{-# LANGUAGE PatternGuards #-}
18−{-# LANGUAGE TupleSections #-}
1917
2018module Language.PureScript.Ide.Reexports where
2119
src/Language/PureScript/Ide/SourceFile.hs+3−5
@@ -12,8 +12,6 @@
1212-- Getting declarations from PureScript sourcefiles
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE FlexibleContexts #-}
16−{-# LANGUAGE MultiParamTypeClasses #-}
1715{-# LANGUAGE OverloadedStrings #-}
1816
1917module Language.PureScript.Ide.SourceFile where
@@ -68,14 +66,14 @@ getImportsForFile fp = do
6866 let imports = getImports module'
6967 pure (mkModuleImport . unwrapPositionedImport <$> imports)
7068 where
71− mkModuleImport (D.ImportDeclaration mn importType' qualifier _) =
69+ mkModuleImport (D.ImportDeclaration mn importType' qualifier) =
7270 ModuleImport
7371 (T.pack (N.runModuleName mn))
7472 importType'
7573 (T.pack . N.runModuleName <$> qualifier)
7674 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
75+ unwrapPositionedImport (D.ImportDeclaration mn importType' qualifier) =
76+ D.ImportDeclaration mn (unwrapImportType importType') qualifier
7977 unwrapPositionedImport x = x
8078 unwrapImportType (D.Explicit decls) = D.Explicit (map unwrapPositionedRef decls)
8179 unwrapImportType (D.Hiding decls) = D.Hiding (map unwrapPositionedRef decls)
src/Language/PureScript/Ide/State.hs+102−57
@@ -12,15 +12,23 @@
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+ ( getPscIdeState
21+ , getExternFiles
22+ , getModule
23+ , getModuleWithReexports
24+ , getAllModulesWithReexports
25+ , getAllModulesWithReexportsAndCache
26+ , insertModule
27+ , insertModuleSTM
28+ , getCachedRebuild
29+ , resetPscIdeState
30+ , setCachedRebuild
31+ ) where
2432
2533import Prelude ()
2634import Prelude.Compat
@@ -30,69 +38,106 @@ import Control.Monad.IO.Class
3038import "monad-logger" Control.Monad.Logger
3139import Control.Monad.Reader.Class
3240import qualified Data.Map.Lazy as M
33−import Data.Maybe (catMaybes)
41+import Data.Maybe (mapMaybe)
3442import Data.Monoid
35−import qualified Data.Text as T
3643import Language.PureScript.Externs
3744import Language.PureScript.Ide.Externs
3845import Language.PureScript.Ide.Reexports
3946import Language.PureScript.Ide.Types
40−import Language.PureScript.Names
47+import Language.PureScript.Ide.Util
48+import qualified Language.PureScript as P
4149
42−getPscIdeState :: (PscIde m) =>
43− m (M.Map ModuleIdent [ExternDecl])
50+-- | Resets the PscIdeState to emptyPscIdeState
51+resetPscIdeState :: PscIde m => m ()
52+resetPscIdeState = do
53+ stateVar <- envStateVar <$> ask
54+ liftIO $ atomically (writeTVar stateVar emptyPscIdeState)
55+
56+-- | Gets the entire PscIdeState
57+getPscIdeState :: PscIde m => m PscIdeState
4458getPscIdeState = do
4559 stateVar <- envStateVar <$> ask
46− liftIO $ pscStateModules <$> readTVarIO stateVar
60+ liftIO (readTVarIO stateVar)
4761
48−getExternFiles :: (PscIde m) =>
49− m (M.Map ModuleName ExternsFile)
62+-- | Gets all loaded ExternFiles
63+getExternFiles :: (PscIde m) => m (M.Map P.ModuleName ExternsFile)
5064getExternFiles = do
5165 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) =>
66+ liftIO (pscIdeStateExternsFiles <$> readTVarIO stateVar)
67+
68+-- | Gets all loaded Modules and resolves Reexports
69+getAllModulesWithReexports :: (PscIde m) => m [Module]
70+getAllModulesWithReexports = getAllModulesWithReexports' <$> getPscIdeState
71+
72+-- | Pure version of @getAllModulesWithReexports@
73+getAllModulesWithReexports' :: PscIdeState -> [Module]
74+getAllModulesWithReexports' state =
75+ mapMaybe (getModuleWithReexports' state) (M.keys (pscIdeStateModules state))
76+
77+-- | Checks if the given ModuleName matches the last rebuild cache and if it
78+-- does, runs @getAllModulesWithReexports@ with the cached module replacing the
79+-- loaded module
80+getAllModulesWithReexportsAndCache
81+ :: (PscIde m)
82+ => Maybe P.ModuleName
83+ -> m [Module]
84+getAllModulesWithReexportsAndCache Nothing = getAllModulesWithReexports
85+getAllModulesWithReexportsAndCache (Just mn) = do
86+ state <- getPscIdeState
87+ cachedRebuild <- getCachedRebuild
88+ case cachedRebuild of
89+ Just (cachedIdent, ef) | cachedIdent == mn ->
90+ pure (getAllModulesWithReexports' (insertModule' ef state))
91+ _ -> getAllModulesWithReexports
92+
93+-- | Looks up a single Module inside the loaded Modules
94+getModule :: (PscIde m, MonadLogger m) => ModuleIdent -> m (Maybe Module)
95+getModule m = getModule' <$> getPscIdeState <*> pure m
96+
97+-- | Pure version of @getModule@
98+getModule' :: PscIdeState -> ModuleIdent -> Maybe Module
99+getModule' ps mi = (mi,) <$> M.lookup mi (pscIdeStateModules ps)
100+
101+-- | Looks up a single Module and resolves its Reexports
102+getModuleWithReexports :: PscIde m => ModuleIdent -> m (Maybe Module)
103+getModuleWithReexports i = getModuleWithReexports' <$> getPscIdeState <*> pure i
104+
105+-- | Pure version of @getModuleWithReexports@
106+getModuleWithReexports' :: PscIdeState -> ModuleIdent -> Maybe Module
107+getModuleWithReexports' ps mi =
108+ resolveReexports (pscIdeStateModules ps) <$> getModule' ps mi
109+
110+-- | Inserts an @ExternsFile@ into the PscIdeState. Also converts the
111+-- ExternsFile into psc-ide's internal Declaration format
112+insertModule :: (PscIde m, MonadLogger m) =>
85113 ExternsFile -> m ()
86114insertModule externsFile = do
87− env <- ask
115+ stateVar <- envStateVar <$> ask
88116 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− }
117+ $(logDebug) $ "Inserting Module: " <> runModuleNameT moduleName
118+ liftIO . atomically $ insertModuleSTM stateVar externsFile
119+
120+-- | STM version of insertModule
121+insertModuleSTM :: TVar PscIdeState -> ExternsFile -> STM ()
122+insertModuleSTM st ef = modifyTVar st (insertModule' ef)
123+
124+-- | Pure version of insertModule
125+insertModule' :: ExternsFile -> PscIdeState -> PscIdeState
126+insertModule' ef state =
127+ state
128+ { pscIdeStateExternsFiles =
129+ M.insert (efModuleName ef) ef (pscIdeStateExternsFiles state)
130+ , pscIdeStateModules = let (mn, decls) = convertExterns ef
131+ in M.insert mn decls (pscIdeStateModules state)
132+ }
133+
134+-- | Sets rebuild cache to the given ExternsFile
135+setCachedRebuild :: PscIde m => ExternsFile -> m ()
136+setCachedRebuild ef = do
137+ st <- envStateVar <$> ask
138+ liftIO . atomically . modifyTVar st $ \x ->
139+ x { pscIdeStateCachedRebuild = Just (efModuleName ef, ef) }
140+
141+-- | Retrieves the rebuild cache
142+getCachedRebuild :: PscIde m => m (Maybe (P.ModuleName, ExternsFile))
143+getCachedRebuild = pscIdeStateCachedRebuild <$> getPscIdeState
src/Language/PureScript/Ide/Types.hs+6−7
@@ -12,11 +12,7 @@
1212-- Type definitions for psc-ide
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE ConstraintKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1815{-# LANGUAGE OverloadedStrings #-}
19−{-# LANGUAGE ScopedTypeVariables #-}
2016
2117module Language.PureScript.Ide.Types where
2218
@@ -65,6 +61,8 @@ data ExternDecl
6561 P.Type -- The "type"
6662 -- | An exported module
6763 | TypeClassDeclaration (P.ProperName 'P.ClassName)
64+ | ValueOperator (P.OpName 'P.ValueOpName) Ident P.Precedence P.Associativity
65+ | TypeOperator (P.OpName 'P.TypeOpName) Ident P.Precedence P.Associativity
6866 | Export ModuleIdent -- The exported Modules name
6967 deriving (Show,Eq,Ord)
7068
@@ -86,12 +84,13 @@ type PscIde m = (MonadIO m, MonadReader PscIdeEnvironment m)
8684
8785data PscIdeState =
8886 PscIdeState
89− { pscStateModules :: M.Map Text [ExternDecl]
90− , externsFiles :: M.Map P.ModuleName ExternsFile
87+ { pscIdeStateModules :: M.Map Text [ExternDecl]
88+ , pscIdeStateExternsFiles :: M.Map P.ModuleName ExternsFile
89+ , pscIdeStateCachedRebuild :: Maybe (P.ModuleName, ExternsFile)
9190 } deriving Show
9291
9392emptyPscIdeState :: PscIdeState
94−emptyPscIdeState = PscIdeState M.empty M.empty
93+emptyPscIdeState = PscIdeState M.empty M.empty Nothing
9594
9695data Match = Match ModuleIdent ExternDecl
9796 deriving (Show, Eq)
src/Language/PureScript/Ide/Util.hs+28−10
@@ -16,6 +16,7 @@
1616
1717module Language.PureScript.Ide.Util where
1818
19+import Prelude.Compat
1920import Data.Aeson
2021import Data.Text (Text)
2122import qualified Data.Text as T
@@ -30,6 +31,12 @@ runProperNameT = T.pack . P.runProperName
3031runIdentT :: P.Ident -> Text
3132runIdentT = T.pack . P.runIdent
3233
34+runOpNameT :: P.OpName a -> Text
35+runOpNameT = T.pack . P.runOpName
36+
37+runModuleNameT :: P.ModuleName -> Text
38+runModuleNameT = T.pack . P.runModuleName
39+
3340prettyTypeT :: P.Type -> Text
3441prettyTypeT = T.unwords . fmap T.strip . T.lines . T.pack . P.prettyPrintType
3542
@@ -40,6 +47,8 @@ identifierFromExternDecl (TypeSynonymDeclaration name _) = runProperNameT name
4047identifierFromExternDecl (DataConstructor name _ _) = name
4148identifierFromExternDecl (TypeClassDeclaration name) = runProperNameT name
4249identifierFromExternDecl (ModuleDecl name _) = name
50+identifierFromExternDecl (ValueOperator op _ _ _) = runOpNameT op
51+identifierFromExternDecl (TypeOperator op _ _ _) = runOpNameT op
4352identifierFromExternDecl Dependency{} = "~Dependency~"
4453identifierFromExternDecl Export{} = "~Export~"
4554
@@ -47,16 +56,25 @@ identifierFromMatch :: Match -> Text
4756identifierFromMatch (Match _ ed) = identifierFromExternDecl ed
4857
4958completionFromMatch :: 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"
59+completionFromMatch (Match m d) = case d of
60+ ValueDeclaration name type' -> Just $ Completion (m, name, prettyTypeT type')
61+ TypeDeclaration name kind -> Just $ Completion (m, runProperNameT name, T.pack $ P.prettyPrintKind kind)
62+ TypeSynonymDeclaration name kind -> Just $ Completion (m, runProperNameT name, prettyTypeT kind)
63+ DataConstructor name _ type' -> Just $ Completion (m, name, prettyTypeT type')
64+ TypeClassDeclaration name -> Just $ Completion (m, runProperNameT name, "class")
65+ ModuleDecl name _ -> Just $ Completion ("module", name, "module")
66+ ValueOperator op ref precedence associativity -> Just $ Completion (m, runOpNameT op, showFixity precedence associativity ref op)
67+ TypeOperator op ref precedence associativity -> Just $ Completion (m, runOpNameT op, showFixity precedence associativity ref op)
68+ Dependency{} -> Nothing
69+ Export{} -> Nothing
70+ where
71+ showFixity p a r o =
72+ let asso = case a of
73+ P.Infix -> "infix"
74+ P.Infixl -> "infixl"
75+ P.Infixr -> "infixr"
76+ in T.unwords [asso, T.pack (show p), r, "as", runOpNameT o]
77+
6078
6179encodeT :: (ToJSON a) => a -> Text
6280encodeT = toStrict . decodeUtf8 . encode
src/Language/PureScript/Ide/Watcher.hs+21−27
@@ -12,44 +12,38 @@
1212-- File watcher for externs files
1313-----------------------------------------------------------------------------
1414
15−{-# LANGUAGE RecordWildCards #-}
16−
1715module Language.PureScript.Ide.Watcher where
1816
19−import Prelude ()
20−import Prelude.Compat
21−
2217import Control.Concurrent (threadDelay)
2318import Control.Concurrent.STM
2419import Control.Monad
2520import Control.Monad.Trans.Except
26−import qualified Data.Map as M
27−import Data.Maybe (isJust)
28−import Language.PureScript.Externs
2921import Language.PureScript.Ide.Externs
3022import Language.PureScript.Ide.State
3123import Language.PureScript.Ide.Types
24+import Prelude
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 PscIdeState -> Event -> IO ()
31+reloadFile _ Removed{} = pure ()
32+reloadFile stateVar ev = do
33+ let fp = eventPath ev
34+ ef' <- runExceptT (readExternFile fp)
35+ case ef' of
36+ Left _ -> pure ()
37+ Right ef -> do
38+ atomically (insertModuleSTM stateVar ef)
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−
41+-- | Installs filewatchers for the given directory and reloads ExternsFiles when
42+-- they change on disc
5043watcher :: 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)
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+283
@@ -0,0 +1,283 @@
1+{-# LANGUAGE DoAndIfThenElse #-}
2+{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4+{-# LANGUAGE MultiParamTypeClasses #-}
5+{-# LANGUAGE RecordWildCards #-}
6+{-# LANGUAGE TupleSections #-}
7+{-# LANGUAGE DataKinds #-}
8+
9+module Language.PureScript.Interactive
10+ ( handleCommand
11+ , module Interactive
12+
13+ -- TODO: remove these exports
14+ , make
15+ , runMake
16+ ) where
17+
18+import Prelude ()
19+import Prelude.Compat
20+
21+import Data.List (intercalate, nub, sort, find, foldl')
22+import qualified Data.Map as M
23+
24+import Control.Monad.IO.Class (MonadIO, liftIO)
25+import Control.Monad.State.Class
26+import Control.Monad.Reader.Class
27+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
28+import Control.Monad.Trans.State.Strict (StateT, runStateT)
29+import Control.Monad.Writer.Strict (Writer(), runWriter)
30+
31+import qualified Language.PureScript as P
32+import qualified Language.PureScript.Names as N
33+
34+import Language.PureScript.Interactive.Completion as Interactive
35+import Language.PureScript.Interactive.IO as Interactive
36+import Language.PureScript.Interactive.Message as Interactive
37+import Language.PureScript.Interactive.Module as Interactive
38+import Language.PureScript.Interactive.Parser as Interactive
39+import Language.PureScript.Interactive.Printer as Interactive
40+import Language.PureScript.Interactive.Types as Interactive
41+
42+import System.Exit
43+import System.Process (readProcessWithExitCode)
44+
45+-- | Pretty-print errors
46+printErrors :: MonadIO m => P.MultipleErrors -> m ()
47+printErrors = liftIO . putStrLn . P.prettyPrintMultipleErrors P.defaultPPEOptions
48+
49+-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
50+-- options and ignores the warning messages.
51+runMake :: P.Make a -> IO (Either P.MultipleErrors a)
52+runMake mk = fst <$> P.runMake P.defaultOptions mk
53+
54+-- | Rebuild a module, using the cached externs data for dependencies.
55+rebuild
56+ :: [P.ExternsFile]
57+ -> P.Module
58+ -> P.Make (P.ExternsFile, P.Environment)
59+rebuild loadedExterns m = do
60+ externs <- P.rebuildModule buildActions loadedExterns m
61+ return (externs, foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment (loadedExterns ++ [externs]))
62+ where
63+ buildActions :: P.MakeActions P.Make
64+ buildActions =
65+ (P.buildMakeActions modulesDir
66+ filePathMap
67+ M.empty
68+ False) { P.progress = const (return ()) }
69+
70+ filePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
71+ filePathMap = M.singleton (P.getModuleName m) (Left P.RebuildAlways)
72+
73+-- | Build the collection of modules from scratch. This is usually done on startup.
74+make
75+ :: [(FilePath, P.Module)]
76+ -> P.Make ([P.ExternsFile], P.Environment)
77+make ms = do
78+ foreignFiles <- P.inferForeignModules filePathMap
79+ externs <- P.make (buildActions foreignFiles) (map snd ms)
80+ return (externs, foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment externs)
81+ where
82+ buildActions :: M.Map P.ModuleName FilePath -> P.MakeActions P.Make
83+ buildActions foreignFiles =
84+ P.buildMakeActions modulesDir
85+ filePathMap
86+ foreignFiles
87+ False
88+
89+ filePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
90+ filePathMap = M.fromList $ map (\(fp, m) -> (P.getModuleName m, Right fp)) ms
91+
92+-- | Performs a PSCi command
93+handleCommand
94+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
95+ => Command
96+ -> m ()
97+handleCommand ShowHelp = liftIO $ putStrLn helpMessage
98+handleCommand ResetState = handleResetState
99+handleCommand (Expression val) = handleExpression 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+handleResetState = do
114+ modify $ updateImportedModules (const [])
115+ . updateLets (const [])
116+ files <- asks psciLoadedFiles
117+ e <- runExceptT $ do
118+ modules <- ExceptT . liftIO $ loadAllModules files
119+ (externs, _) <- ExceptT . liftIO . runMake . make $ modules
120+ return (map snd modules, externs)
121+ case e of
122+ Left errs -> printErrors errs
123+ Right (modules, externs) -> modify (updateLoadedExterns (const (zip modules externs)))
124+
125+-- | Takes a value expression and evaluates it with the current state.
126+--
127+-- TODO: factor out the Node process runner, so that we can use PSCi in other settings.
128+handleExpression
129+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
130+ => P.Expr
131+ -> m ()
132+handleExpression val = do
133+ st <- get
134+ let m = createTemporaryModule True st val
135+ nodeArgs <- asks ((++ [indexFile]) . psciNodeFlags)
136+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
137+ case e of
138+ Left errs -> printErrors errs
139+ Right _ -> do
140+ liftIO $ writeFile indexFile "require('$PSCI')['$main']();"
141+ process <- liftIO findNodeProcess
142+ result <- liftIO $ traverse (\node -> readProcessWithExitCode node nodeArgs "") process
143+ case result of
144+ Just (ExitSuccess, out, _) -> liftIO $ putStrLn out
145+ Just (ExitFailure _, _, err) -> liftIO $ putStrLn err
146+ Nothing -> liftIO $ putStrLn "Couldn't find node.js"
147+
148+-- |
149+-- Takes a list of declarations and updates the environment, then run a make. If the declaration fails,
150+-- restore the original environment.
151+--
152+handleDecls
153+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
154+ => [P.Declaration]
155+ -> m ()
156+handleDecls ds = do
157+ st <- gets (updateLets (++ ds))
158+ let m = createTemporaryModule False st (P.Literal (P.ObjectLiteral []))
159+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
160+ case e of
161+ Left err -> printErrors err
162+ Right _ -> put st
163+
164+-- | Show actual loaded modules in psci.
165+handleShowLoadedModules
166+ :: (MonadState PSCiState m, MonadIO m)
167+ => m ()
168+handleShowLoadedModules = do
169+ loadedModules <- gets psciLoadedExterns
170+ liftIO $ putStrLn (readModules loadedModules)
171+ where
172+ readModules = unlines . sort . nub . map (P.runModuleName . P.getModuleName . fst)
173+
174+-- | Show the imported modules in psci.
175+handleShowImportedModules
176+ :: (MonadState PSCiState m, MonadIO m)
177+ => m ()
178+handleShowImportedModules = do
179+ PSCiState { psciImportedModules = importedModules } <- get
180+ liftIO $ showModules importedModules >>= putStrLn
181+ return ()
182+ where
183+ showModules = return . unlines . sort . map showModule
184+ showModule (mn, declType, asQ) =
185+ "import " ++ N.runModuleName mn ++ showDeclType declType ++
186+ foldMap (\mn' -> " as " ++ N.runModuleName mn') asQ
187+
188+ showDeclType P.Implicit = ""
189+ showDeclType (P.Explicit refs) = refsList refs
190+ showDeclType (P.Hiding refs) = " hiding " ++ refsList refs
191+ refsList refs = " (" ++ commaList (map showRef refs) ++ ")"
192+
193+ showRef :: P.DeclarationRef -> String
194+ showRef (P.TypeRef pn dctors) = N.runProperName pn ++ "(" ++ maybe ".." (commaList . map N.runProperName) dctors ++ ")"
195+ showRef (P.TypeOpRef op) = "type " ++ N.showOp op
196+ showRef (P.ValueRef ident) = N.runIdent ident
197+ showRef (P.ValueOpRef op) = N.showOp op
198+ showRef (P.TypeClassRef pn) = "class " ++ N.runProperName pn
199+ showRef (P.TypeInstanceRef ident) = N.runIdent ident
200+ showRef (P.ModuleRef name) = "module " ++ N.runModuleName name
201+ showRef (P.PositionedDeclarationRef _ _ ref) = showRef ref
202+
203+ commaList :: [String] -> String
204+ commaList = intercalate ", "
205+
206+-- | Imports a module, preserving the initial state on failure.
207+handleImport
208+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
209+ => ImportedModule
210+ -> m ()
211+handleImport im = do
212+ st <- gets (updateImportedModules (im :))
213+ let m = createTemporaryModuleForImports st
214+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
215+ case e of
216+ Left errs -> printErrors errs
217+ Right _ -> put st
218+
219+-- | Takes a value and prints its type
220+handleTypeOf
221+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
222+ => P.Expr
223+ -> m ()
224+handleTypeOf val = do
225+ st <- get
226+ let m = createTemporaryModule False st val
227+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
228+ case e of
229+ Left errs -> printErrors errs
230+ Right (_, env') ->
231+ case M.lookup (P.ModuleName [P.ProperName "$PSCI"], P.Ident "it") (P.names env') of
232+ Just (ty, _, _) -> liftIO . putStrLn . P.prettyPrintType $ ty
233+ Nothing -> liftIO $ putStrLn "Could not find type"
234+
235+-- | Takes a type and prints its kind
236+handleKindOf
237+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
238+ => P.Type
239+ -> m ()
240+handleKindOf typ = do
241+ st <- get
242+ let m = createTemporaryModuleForKind st typ
243+ mName = P.ModuleName [P.ProperName "$PSCI"]
244+ e <- liftIO . runMake $ rebuild (map snd (psciLoadedExterns st)) m
245+ case e of
246+ Left errs -> printErrors errs
247+ Right (_, env') ->
248+ case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
249+ Just (_, typ') -> do
250+ let chk = (P.emptyCheckState env') { P.checkCurrentModule = Just mName }
251+ k = check (P.kindOf typ') chk
252+
253+ check :: StateT P.CheckState (ExceptT P.MultipleErrors (Writer P.MultipleErrors)) a -> P.CheckState -> Either P.MultipleErrors (a, P.CheckState)
254+ check sew = fst . runWriter . runExceptT . runStateT sew
255+ case k of
256+ Left err -> printErrors err
257+ Right (kind, _) -> liftIO . putStrLn . P.prettyPrintKind $ kind
258+ Nothing -> liftIO $ putStrLn "Could not find kind"
259+
260+-- | Browse a module and displays its signature
261+handleBrowse
262+ :: (MonadReader PSCiConfig m, MonadState PSCiState m, MonadIO m)
263+ => P.ModuleName
264+ -> m ()
265+handleBrowse moduleName = do
266+ st <- get
267+ env <- asks psciEnvironment
268+ if isModInEnv moduleName st
269+ then liftIO . putStrLn $ printModuleSignatures moduleName env
270+ else case lookupUnQualifiedModName moduleName st of
271+ Just unQualifiedName ->
272+ if isModInEnv unQualifiedName st
273+ then liftIO . putStrLn $ printModuleSignatures unQualifiedName env
274+ else failNotInEnv moduleName
275+ Nothing ->
276+ failNotInEnv moduleName
277+ where
278+ isModInEnv modName =
279+ any ((== modName) . P.getModuleName . fst) . psciLoadedExterns
280+ failNotInEnv modName =
281+ liftIO $ putStrLn $ "Module '" ++ N.runModuleName modName ++ "' is not valid."
282+ lookupUnQualifiedModName quaModName st =
283+ (\(modName,_,_) -> modName) <$> find ( \(_, _, mayQuaName) -> mayQuaName == Just quaModName) (psciImportedModules st)
psci/PSCi/Completion.hs → src/Language/PureScript/Interactive/Completion.hsrenamed+76−80
@@ -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
@@ -40,15 +93,6 @@ data CompletionContext
4093 | CtxFixed String
4194 deriving (Show, Read)
4295
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
51−
5296-- |
5397-- Decide what kind of completion we need based on input. This function expects
5498-- a list of complete words (to the left of the cursor) as the first argument,
@@ -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+8−15
@@ -1,25 +1,22 @@
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
2522 let moduleNamesIdent = (filter ((== moduleName) . fst) . M.keys) names
@@ -28,7 +25,7 @@ printModuleSignatures moduleName (P.Environment {..}) =
2825
2926 in
3027 -- print each component
31− (outputStr . unlines . map trimEnd . lines . Box.render . Box.vsep 1 Box.left)
28+ (unlines . map trimEnd . lines . Box.render . Box.vsep 1 Box.left)
3229 [ printModule's (mapMaybe (showTypeClass . findTypeClass typeClasses)) moduleTypeClasses -- typeClasses
3330 , printModule's (mapMaybe (showType typeClasses dataConstructors typeSynonyms . findType types)) moduleTypes -- types
3431 , printModule's (map (showNameType . findNameType names)) moduleNamesIdent -- functions
@@ -58,7 +55,7 @@ printModuleSignatures moduleName (P.Environment {..}) =
5855 if null constrs
5956 then Box.text ""
6057 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)
58+ 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)
6259 Box.<> Box.text ") <= "
6360 className =
6461 Box.text (P.runProperName name)
@@ -125,7 +122,3 @@ printModuleSignatures moduleName (P.Environment {..}) =
125122 mapFirstRest f g (x:xs) = f x : map g xs
126123
127124 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+146
@@ -0,0 +1,146 @@
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+ , psciNodeFlags :: [String]
17+ , psciEnvironment :: P.Environment
18+ } deriving Show
19+
20+-- | The PSCI state.
21+--
22+-- Holds a list of imported modules, loaded files, and partial let bindings.
23+-- The let bindings are partial,
24+-- because it makes more sense to apply the binding to the final evaluated expression.
25+data PSCiState = PSCiState
26+ { psciImportedModules :: [ImportedModule]
27+ , psciLetBindings :: [P.Declaration]
28+ , psciLoadedExterns :: [(P.Module, P.ExternsFile)]
29+ } deriving Show
30+
31+initialPSCiState :: PSCiState
32+initialPSCiState = PSCiState [] [] []
33+
34+-- | All of the data that is contained by an ImportDeclaration in the AST.
35+-- That is:
36+--
37+-- * A module name, the name of the module which is being imported
38+-- * An ImportDeclarationType which specifies whether there is an explicit
39+-- import list, a hiding list, or neither.
40+-- * If the module is imported qualified, its qualified name in the importing
41+-- module. Otherwise, Nothing.
42+--
43+type ImportedModule = (P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)
44+
45+psciImportedModuleNames :: PSCiState -> [P.ModuleName]
46+psciImportedModuleNames (PSCiState{psciImportedModules = is}) =
47+ map (\(mn, _, _) -> mn) is
48+
49+allImportsOf :: P.Module -> PSCiState -> [ImportedModule]
50+allImportsOf m (PSCiState{psciImportedModules = is}) =
51+ filter isImportOfThis is
52+ where
53+ name = P.getModuleName m
54+ isImportOfThis (name', _, _) = name == name'
55+
56+-- * State helpers
57+
58+-- | Updates the imported modules in the state record.
59+updateImportedModules :: ([ImportedModule] -> [ImportedModule]) -> PSCiState -> PSCiState
60+updateImportedModules f st = st { psciImportedModules = f (psciImportedModules st) }
61+
62+-- | Updates the loaded externs files in the state record.
63+updateLoadedExterns :: ([(P.Module, P.ExternsFile)] -> [(P.Module, P.ExternsFile)]) -> PSCiState -> PSCiState
64+updateLoadedExterns f st = st { psciLoadedExterns = f (psciLoadedExterns st) }
65+
66+-- | Updates the let bindings in the state record.
67+updateLets :: ([P.Declaration] -> [P.Declaration]) -> PSCiState -> PSCiState
68+updateLets f st = st { psciLetBindings = f (psciLetBindings st) }
69+
70+-- * Commands
71+
72+-- |
73+-- Valid Meta-commands for PSCI
74+--
75+data Command
76+ -- |
77+ -- A purescript expression
78+ --
79+ = Expression P.Expr
80+ -- |
81+ -- Show the help (ie, list of directives)
82+ --
83+ | ShowHelp
84+ -- |
85+ -- Import a module from a loaded file
86+ --
87+ | Import ImportedModule
88+ -- |
89+ -- Browse a module
90+ --
91+ | BrowseModule P.ModuleName
92+ -- |
93+ -- Exit PSCI
94+ --
95+ | QuitPSCi
96+ -- |
97+ -- Reset the state of the REPL
98+ --
99+ | ResetState
100+ -- |
101+ -- Add some declarations to the current evaluation context.
102+ --
103+ | Decls [P.Declaration]
104+ -- |
105+ -- Find the type of an expression
106+ --
107+ | TypeOf P.Expr
108+ -- |
109+ -- Find the kind of an expression
110+ --
111+ | KindOf P.Type
112+ -- |
113+ -- Shows information about the current state of the REPL
114+ --
115+ | ShowInfo ReplQuery
116+
117+data ReplQuery
118+ = QueryLoaded
119+ | QueryImport
120+ deriving (Eq, Show)
121+
122+-- | A list of all ReplQuery values.
123+replQueries :: [ReplQuery]
124+replQueries = [QueryLoaded, QueryImport]
125+
126+replQueryStrings :: [String]
127+replQueryStrings = map showReplQuery replQueries
128+
129+showReplQuery :: ReplQuery -> String
130+showReplQuery QueryLoaded = "loaded"
131+showReplQuery QueryImport = "import"
132+
133+parseReplQuery :: String -> Maybe ReplQuery
134+parseReplQuery "loaded" = Just QueryLoaded
135+parseReplQuery "import" = Just QueryImport
136+parseReplQuery _ = Nothing
137+
138+data Directive
139+ = Help
140+ | Quit
141+ | Reset
142+ | Browse
143+ | Type
144+ | Kind
145+ | Show
146+ deriving (Eq, Show)
src/Language/PureScript/Kinds.hs+8−19
@@ -2,35 +2,24 @@
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
21+ -- | Type-level strings
22+ | Symbol
3423 deriving (Show, Read, Eq, Ord)
3524
3625$(A.deriveJSON A.defaultOptions ''Kind)
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+109−78
@@ -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)
@@ -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 :: MonadSupply m => ([[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−151
@@ -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
8460
85− let scope = maybe nullImports (\(_, imps, _) -> imps) (M.lookup mn env)
61+ -- TODO: this needs some work to be easier to understand
62+
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,55 @@ 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)
172+ :: Eq a
164173 => ModuleName
165174 -> M.Map (Qualified a) [ImportRecord a]
166− -> (Qualified a -> Name)
167− -> [(ModuleName, Name)]
175+ -> (a -> Name)
176+ -> [(ModuleName, Qualified Name)]
168177 extractByQual k m toName = mapMaybe go (M.toList m)
169178 where
170179 go (q@(Qualified mnq _), is)
171180 | isUnqualified q =
172181 case find (isQualifiedWith k) (map importName is) of
173− Just (Qualified _ name) -> Just (k, toName $ Qualified mnq name)
182+ Just (Qualified _ name) -> Just (k, Qualified mnq (toName name))
174183 _ -> Nothing
175184 | 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"
185+ case importName (head is) of
186+ Qualified (Just mn') name -> Just (mn', Qualified mnq (toName name))
187+ _ -> internalError "unqualified name in extractByQual"
179188 go _ = Nothing
180189
181190lintImportDecl
182191 :: forall m
183− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
192+ . MonadWriter MultipleErrors m
184193 => Env
185194 -> ModuleName
186195 -> Maybe ModuleName
187− -> [Name]
196+ -> [Qualified Name]
188197 -> ImportDeclarationType
189198 -> Bool
190− -> m ()
199+ -> m Bool
191200lintImportDecl env mni qualifierName names declType allowImplicit =
192201 case declType of
193202 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)
203+ Nothing ->
204+ if null allRefs
205+ then unused
206+ else unless' allowImplicit (checkImplicit ImplicitImport)
207+ Just q -> unless' (q `elem` mapMaybe getQual names) unused
208+ Hiding _ -> unless' allowImplicit (checkImplicit HidingImport)
199209 Explicit [] -> unused
200210 Explicit declrefs -> checkExplicit declrefs
201211
@@ -203,82 +213,103 @@ lintImportDecl env mni qualifierName names declType allowImplicit =
203213
204214 checkImplicit
205215 :: (ModuleName -> [DeclarationRef] -> SimpleErrorMessage)
206− -> m ()
216+ -> m Bool
207217 checkImplicit warning =
208218 if null allRefs
209219 then unused
210− else tell $ errorMessage $ warning mni allRefs
220+ else warn (warning mni (map simplifyTypeRef allRefs))
221+ where
222+ -- Replace explicit type refs with data constructor lists from listing the
223+ -- used constructors explicity `T(X, Y, [...])` to `T(..)` for suggestion
224+ -- message.
225+ simplifyTypeRef :: DeclarationRef -> DeclarationRef
226+ simplifyTypeRef (TypeRef name (Just dctors))
227+ | not (null dctors) = TypeRef name Nothing
228+ simplifyTypeRef other = other
211229
212230 checkExplicit
213231 :: [DeclarationRef]
214− -> m ()
232+ -> m Bool
215233 checkExplicit declrefs = do
216234 let idents = nub (mapMaybe runDeclRef declrefs)
217− dctors = mapMaybe (matchDctor qualifierName) names
218− usedNames = mapMaybe (matchName (typeForDCtor mni) qualifierName) names
235+ dctors = mapMaybe (getDctorName <=< disqualifyFor qualifierName) names
236+ usedNames = mapMaybe (matchName (typeForDCtor mni) <=< disqualifyFor qualifierName) names
219237 diff = idents \\ usedNames
220− case (length diff, length idents) of
221− (0, _) -> return ()
238+
239+ didWarn <- case (length diff, length idents) of
240+ (0, _) -> return False
222241 (n, m) | n == m -> unused
223− _ -> tell $ errorMessage $ UnusedExplicitImport mni diff qualifierName allRefs
242+ _ -> warn (UnusedExplicitImport mni diff qualifierName allRefs)
224243
225− -- If we've not already warned a type is unused, check its data constructors
226− forM_ (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
244+ didWarn' <- forM (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
227245 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
246+ -- If we've not already warned a type is unused, check its data constructors
247+ unless' (runProperName tn `notElem` usedNames) $
248+ case (c, dctors `intersect` allCtors) of
249+ (_, []) | c /= Just [] -> warn (UnusedDctorImport tn)
250+ (Just ctors, dctors') ->
251+ let ddiff = ctors \\ dctors'
252+ in unless' (null ddiff) $ warn $ UnusedDctorExplicitImport tn ddiff
253+ _ -> return False
254+
255+ return (didWarn || or didWarn')
256+
257+ unused :: m Bool
258+ unused = warn (UnusedImport mni)
259+
260+ warn :: SimpleErrorMessage -> m Bool
261+ warn err = tell (errorMessage err) >> return True
262+
263+ -- Unless the boolean is true, run the action. Return false when the action is
264+ -- not run, otherwise return whatever the action does.
265+ --
266+ -- The return value is intended for cases where we want to track whether some
267+ -- work was done, as there may be further conditions in the action that mean
268+ -- it ends up doing nothing.
269+ unless' :: Bool -> m Bool -> m Bool
270+ unless' False m = m
271+ unless' True _ = return False
239272
240273 allRefs :: [DeclarationRef]
241274 allRefs = findUsedRefs env mni qualifierName names
242275
243276 dtys
244277 :: ModuleName
245− -> [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
246− dtys mn = maybe [] exportedTypes $ envModuleExports <$> mn `M.lookup` env
278+ -> M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
279+ dtys mn = maybe M.empty exportedTypes $ envModuleExports <$> mn `M.lookup` env
247280
248281 dctorsForType
249282 :: ModuleName
250283 -> ProperName 'TypeName
251284 -> [ProperName 'ConstructorName]
252− dctorsForType mn tn =
253− maybe [] getDctors (find matches $ dtys mn)
254− where
255− matches ((ty, _),_) = ty == tn
256− getDctors ((_,ctors),_) = ctors
285+ dctorsForType mn tn = maybe [] fst $ tn `M.lookup` dtys mn
257286
258287 typeForDCtor
259288 :: ModuleName
260289 -> ProperName 'ConstructorName
261290 -> 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
291+ typeForDCtor mn pn = fst <$> find (elem pn . fst . snd) (M.toList (dtys mn))
267292
268−findUsedRefs :: Env -> ModuleName -> Maybe ModuleName -> [Name] -> [DeclarationRef]
269−findUsedRefs env mni qualifierName names =
293+findUsedRefs
294+ :: Env
295+ -> ModuleName
296+ -> Maybe ModuleName
297+ -> [Qualified Name]
298+ -> [DeclarationRef]
299+findUsedRefs env mni qn names =
270300 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
301+ classRefs = TypeClassRef <$> mapMaybe (getClassName <=< disqualifyFor qn) names
302+ valueRefs = ValueRef <$> mapMaybe (getIdentName <=< disqualifyFor qn) names
303+ valueOpRefs = ValueOpRef <$> mapMaybe (getValOpName <=< disqualifyFor qn) names
304+ typeOpRefs = TypeOpRef <$> mapMaybe (getTypeOpName <=< disqualifyFor qn) names
305+ types = mapMaybe (getTypeName <=< disqualifyFor qn) names
306+ dctors = mapMaybe (getDctorName <=< disqualifyFor qn) names
276307 typesWithDctors = reconstructTypeRefs dctors
277308 typesWithoutDctors = filter (`M.notMember` typesWithDctors) types
278309 typesRefs
279310 = map (flip TypeRef (Just [])) typesWithoutDctors
280311 ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
281− in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs
312+ in classRefs ++ typeOpRefs ++ typesRefs ++ valueRefs ++ valueOpRefs
282313
283314 where
284315
@@ -287,7 +318,8 @@ findUsedRefs env mni qualifierName names =
287318 -> M.Map (ProperName 'TypeName) [ProperName 'ConstructorName]
288319 reconstructTypeRefs = foldr accumDctors M.empty
289320 where
290− accumDctors dctor = M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
321+ accumDctors dctor =
322+ M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
291323
292324 findTypeForDctor
293325 :: ModuleName
@@ -296,32 +328,20 @@ findUsedRefs env mni qualifierName names =
296328 findTypeForDctor mn dctor =
297329 case mn `M.lookup` env of
298330 Just (_, _, exps) ->
299− case find (elem dctor . snd . fst) (exportedTypes exps) of
300− Just ((ty, _), _) -> ty
331+ case find (elem dctor . fst . snd) (M.toList (exportedTypes exps)) of
332+ Just (ty, _) -> ty
301333 Nothing -> internalError $ "missing type for data constructor " ++ runProperName dctor ++ " in findTypeForDctor"
302334 Nothing -> internalError $ "missing module " ++ runModuleName mn ++ " in findTypeForDctor"
303335
304336matchName
305337 :: (ProperName 'ConstructorName -> Maybe (ProperName 'TypeName))
306− -> Maybe ModuleName
307338 -> Name
308339 -> 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
340+matchName _ (IdentName x) = Just $ showIdent x
341+matchName _ (TyName x) = Just $ runProperName x
342+matchName _ (TyClassName x) = Just $ runProperName x
343+matchName lookupDc (DctorName x) = runProperName <$> lookupDc x
344+matchName _ _ = Nothing
325345
326346runDeclRef :: DeclarationRef -> Maybe String
327347runDeclRef (PositionedDeclarationRef _ _ ref) = runDeclRef ref
@@ -330,15 +350,16 @@ runDeclRef (TypeRef pn _) = Just $ runProperName pn
330350runDeclRef (TypeClassRef pn) = Just $ runProperName pn
331351runDeclRef _ = Nothing
332352
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
353+checkDuplicateImports
354+ :: MonadWriter MultipleErrors m
355+ => ModuleName
356+ -> [ImportDef]
357+ -> (ImportDef, ImportDef)
358+ -> m [ImportDef]
359+checkDuplicateImports mn xs ((_, t1, q1), (pos, t2, q2)) =
360+ if t1 == t2 && q1 == q2
361+ then do
362+ maybe id warnWithPosition pos $
363+ tell $ errorMessage $ DuplicateImport mn t2 q2
364+ return $ (pos, t2, q2) : xs
365+ else return xs
src/Language/PureScript/Make.hs+73−79
@@ -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,46 @@ 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)
4639import Data.Either (partitionEithers)
47−import Data.Time.Clock
48−import Data.String (fromString)
4940import Data.Foldable (for_)
41+import Data.List (foldl', sort)
42+import Data.Maybe (fromMaybe, catMaybes)
43+import Data.String (fromString)
44+import Data.Time.Clock
5045import Data.Traversable (for)
5146import Data.Version (showVersion)
52−import Data.Aeson (encode, decode)
5347import qualified Data.ByteString.Lazy as B
5448import qualified Data.ByteString.UTF8 as BU8
55−import qualified Data.Set as S
5649import qualified Data.Map as M
50+import qualified Data.Set as S
5751
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
7252import Language.PureScript.AST
73−import Language.PureScript.Externs
53+import Language.PureScript.Crash
7454import Language.PureScript.Environment
7555import Language.PureScript.Errors
56+import Language.PureScript.Externs
7657import Language.PureScript.Linter
7758import Language.PureScript.ModuleDependencies
7859import Language.PureScript.Names
@@ -82,14 +63,25 @@ import Language.PureScript.Pretty.Common(SMap(..))
8263import Language.PureScript.Renamer
8364import Language.PureScript.Sugar
8465import Language.PureScript.TypeChecker
85−import qualified Language.PureScript.Constants as C
66+import qualified Language.JavaScript.Parser as JS
8667import qualified Language.PureScript.Bundle as Bundle
87−import qualified Language.PureScript.Parser as PSParser
88−
8968import qualified Language.PureScript.CodeGen.JS as J
69+import qualified Language.PureScript.Constants as C
9070import qualified Language.PureScript.CoreFn as CF
71+import qualified Language.PureScript.Parser as PSParser
72+
9173import qualified Paths_purescript as Paths
9274
75+import SourceMap
76+import SourceMap.Types
77+
78+import System.Directory (doesFileExist, getModificationTime, createDirectoryIfMissing, getCurrentDirectory)
79+import System.FilePath ((</>), takeDirectory, makeRelative, splitPath, normalise, replaceExtension)
80+import System.IO.Error (tryIOError)
81+import System.IO.UTF8 (readUTF8File, writeUTF8File)
82+
83+import qualified Text.Parsec as Parsec
84+
9385-- | Progress messages from the make process
9486data ProgressMessage
9587 = CompilingModule ModuleName
@@ -107,31 +99,22 @@ renderProgressMessage (CompilingModule mn) = "Compiling " ++ runModuleName mn
10799--
108100-- * The details of how files are read/written etc.
109101--
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
102+data MakeActions m = MakeActions
103+ { getInputTimestamp :: ModuleName -> m (Either RebuildPolicy (Maybe UTCTime))
104+ -- ^ Get the timestamp for the input file(s) for a module. If there are multiple
105+ -- files (@.purs@ and foreign files, for example) the timestamp should be for
114106 -- 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− --
122107 , 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.
108+ -- ^ Get the timestamp for the output files for a module. This should be the
109+ -- timestamp for the oldest modified file, or 'Nothing' if any of the required
110+ -- output files are missing.
126111 , readExterns :: ModuleName -> m (FilePath, Externs)
127− -- |
128− -- Run the code generator for the module and write any required output files.
129− --
112+ -- ^ Read the externs file for a module as a string and also return the actual
113+ -- path for the file.
130114 , codegen :: CF.Module CF.Ann -> Environment -> Externs -> SupplyT m ()
131− -- |
132− -- Respond to a progress update.
133− --
115+ -- ^ Run the code generator for the module and write any required output files.
134116 , progress :: ProgressMessage -> m ()
117+ -- ^ Respond to a progress update.
135118 }
136119
137120-- |
@@ -157,11 +140,11 @@ rebuildModule :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options
157140rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
158141 progress $ CompilingModule moduleName
159142 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]
143+ withPrim = importPrim m
144+ lint withPrim
145+ ((Module ss coms _ elaborated exps, env'), nextVar) <- runSupplyT 0 $ do
146+ [desugared] <- desugar externs [withPrim]
163147 runCheck' env $ typeCheckModule desugared
164− checkExhaustiveModule env' checked
165148 regrouped <- createBindingGroups moduleName . collapseBindingGroups $ elaborated
166149 let mod' = Module ss coms moduleName regrouped exps
167150 corefn = CF.moduleToCoreFn env' mod'
@@ -179,11 +162,8 @@ rebuildModule MakeActions{..} externs m@(Module _ _ moduleName _ _) = do
179162make :: forall m. (Monad m, MonadBaseControl IO m, MonadReader Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
180163 => MakeActions m
181164 -> [Module]
182− -> m Environment
165+ -> m [ExternsFile]
183166make ma@MakeActions{..} ms = do
184− requirePath <- asks optionsRequirePath
185− when (isJust requirePath) $ tell $ errorMessage DeprecatedRequirePath
186−
187167 checkModuleNamesAreUnique
188168
189169 (sorted, graph) <- sortModules ms
@@ -202,7 +182,7 @@ make ma@MakeActions{..} ms = do
202182
203183 -- Bundle up all the externs and return them as an Environment
204184 (_, 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
185+ return externs
206186
207187 where
208188 checkModuleNamesAreUnique :: m ()
@@ -304,10 +284,28 @@ makeIO f io = do
304284 e <- liftIO $ tryIOError io
305285 either (throwError . singleError . f) return e
306286
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
287+-- | Read a text file in the 'Make' monad, capturing any errors using the
288+-- 'MonadError' instance.
289+readTextFile :: FilePath -> Make String
290+readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
291+
292+-- | Infer the module name for a module by looking for the same filename with
293+-- a .js extension.
294+inferForeignModules
295+ :: forall m
296+ . MonadIO m
297+ => M.Map ModuleName (Either RebuildPolicy FilePath)
298+ -> m (M.Map ModuleName FilePath)
299+inferForeignModules = fmap (M.mapMaybe id) . traverse inferForeignModule
300+ where
301+ inferForeignModule :: Either RebuildPolicy FilePath -> m (Maybe FilePath)
302+ inferForeignModule (Left _) = return Nothing
303+ inferForeignModule (Right path) = do
304+ let jsFile = replaceExtension path "js"
305+ exists <- liftIO $ doesFileExist jsFile
306+ if exists
307+ then return (Just jsFile)
308+ else return Nothing
311309
312310-- |
313311-- A set of make actions that read and write modules from the given directory.
@@ -324,7 +322,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
324322 getInputTimestamp :: ModuleName -> Make (Either RebuildPolicy (Maybe UTCTime))
325323 getInputTimestamp mn = do
326324 let path = fromMaybe (internalError "Module has no filename in 'make'") $ M.lookup mn filePathMap
327− e1 <- traverseEither getTimestamp path
325+ e1 <- traverse getTimestamp path
328326 fPath <- maybe (return Nothing) getTimestamp $ M.lookup mn foreigns
329327 return $ fmap (max fPath) e1
330328
@@ -375,7 +373,7 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
375373 genSourceMap dir mapFile extraLines mappings = do
376374 let pathToDir = iterate (".." </>) ".." !! length (splitPath $ normalise outputDir)
377375 sourceFile = case mappings of
378− ((SMap file _ _):_) -> Just $ pathToDir </> makeRelative dir file
376+ (SMap file _ _ : _) -> Just $ pathToDir </> makeRelative dir file
379377 _ -> Nothing
380378 let rawMapping = SourceMapping { smFile = "index.js", smSourceRoot = Nothing, smMappings =
381379 map (\(SMap _ orig gen) -> Mapping {
@@ -414,9 +412,6 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
414412 progress :: ProgressMessage -> Make ()
415413 progress = liftIO . putStrLn . renderProgressMessage
416414
417−readTextFile :: FilePath -> Make String
418−readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ readUTF8File path
419−
420415-- |
421416-- Check that the declarations in a given PureScript module match with those
422417-- in its corresponding foreign module.
@@ -464,11 +459,10 @@ checkForeignDecls m path = do
464459 (errs, _) ->
465460 Left errs
466461
467− -- TODO: Handling for parenthesised operators should be removed after 0.9.
468462 -- We ignore the error message here, just being told it's an invalid
469463 -- identifier should be enough.
470464 parseIdent :: String -> Either String Ident
471− parseIdent str = try str <|> try ("(" ++ str ++ ")")
465+ parseIdent str = try str
472466 where
473467 try s = either (const (Left str)) Right $ do
474468 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+78−16
@@ -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,10 +61,6 @@ 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
@@ -35,19 +68,37 @@ data Ident
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
76+
77+freshIdent :: MonadSupply m => String -> m Ident
78+freshIdent name = GenIdent (Just name) <$> fresh
79+
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, Read, Eq, Ord)
88+
89+instance ToJSON (OpName a) where
90+ toJSON = toJSON . runOpName
4591
46−freshIdent :: (MonadSupply m) => String -> m Ident
47−freshIdent name = liftM (GenIdent (Just name)) fresh
92+instance FromJSON (OpName a) where
93+ parseJSON = fmap OpName . parseJSON
4894
49−freshIdent' :: (MonadSupply m) => m Ident
50−freshIdent' = liftM (GenIdent Nothing) fresh
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.
@@ -101,6 +152,9 @@ showQualified :: (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
@@ -1,36 +1,23 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Parser
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 parsers for core data types:
13−--
14−-- [@Language.PureScript.Parser.Kinds@] Parser for kinds
15−--
16−-- [@Language.PureScript.Parser.Values@] Parser for values
17−--
18−-- [@Language.PureScript.Parser.Types@] Parser for types
19−--
20−-- [@Language.PureScript.Parser.Declaration@] Parsers for declarations and modules
21−--
22−-- [@Language.PureScript.Parser.State@] Parser state, including indentation
23−--
24−-- [@Language.PureScript.Parser.Common@] Common parsing utility functions
25−--
26−-----------------------------------------------------------------------------
27−
28−module Language.PureScript.Parser (module P) where
29−
30−import Language.PureScript.Parser.Common as P
31−import Language.PureScript.Parser.Types as P
32−import Language.PureScript.Parser.State as P
33−import Language.PureScript.Parser.Kinds as P
34−import Language.PureScript.Parser.Lexer as P
35−import Language.PureScript.Parser.Declarations as P
36−import Language.PureScript.Parser.JS as P
1+-- |
2+-- A collection of parsers for core data types:
3+--
4+-- [@Language.PureScript.Parser.Kinds@] Parser for kinds
5+--
6+-- [@Language.PureScript.Parser.Values@] Parser for values
7+--
8+-- [@Language.PureScript.Parser.Types@] Parser for types
9+--
10+-- [@Language.PureScript.Parser.Declaration@] Parsers for declarations and modules
11+--
12+-- [@Language.PureScript.Parser.State@] Parser state, including indentation
13+--
14+-- [@Language.PureScript.Parser.Common@] Common parsing utility functions
15+--
16+module Language.PureScript.Parser (module P) where
17+
18+import Language.PureScript.Parser.Common as P
19+import Language.PureScript.Parser.Declarations as P
20+import Language.PureScript.Parser.Kinds as P
21+import Language.PureScript.Parser.Lexer as P
22+import Language.PureScript.Parser.State as P
23+import Language.PureScript.Parser.Types as P
src/Language/PureScript/Parser/Common.hs+28−6
@@ -1,23 +1,33 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−
31-- |
4−-- Constants, and utility functions to be used when parsing
2+-- Constants and utility functions to be used when parsing
53--
64module Language.PureScript.Parser.Common where
75
6+import Prelude.Compat
7+
88import Control.Applicative
99import Control.Monad (guard)
1010
11+import Language.PureScript.AST.SourcePos
1112import Language.PureScript.Comments
13+import Language.PureScript.Names
1214import Language.PureScript.Parser.Lexer
1315import Language.PureScript.Parser.State
14−import Language.PureScript.Names
1516
1617import qualified Text.Parsec as P
1718
19+-- |
20+-- Parse a general proper name.
21+--
1822properName :: TokenParser (ProperName a)
1923properName = ProperName <$> uname
2024
25+-- |
26+-- Parse a proper name for a type.
27+--
28+typeName :: TokenParser (ProperName 'TypeName)
29+typeName = ProperName <$> tyname
30+
2131-- |
2232-- Parse a module name
2333--
@@ -42,10 +52,16 @@ parseQualified parser = part []
4252 qual path = if null path then Nothing else Just $ ModuleName path
4353
4454-- |
45−-- Parse an identifier or parenthesized operator
55+-- Parse an identifier.
4656--
4757parseIdent :: TokenParser Ident
48−parseIdent = (Ident <$> identifier) <|> (Op <$> parens symbol)
58+parseIdent = Ident <$> identifier
59+
60+-- |
61+-- Parse an operator.
62+--
63+parseOperator :: TokenParser (OpName a)
64+parseOperator = OpName <$> symbol
4965
5066-- |
5167-- Run the first parser, then match the second if possible, applying the specified function on a successful match
@@ -120,3 +136,9 @@ readComments = P.lookAhead $ ptComments <$> P.anyToken
120136--
121137runTokenParser :: FilePath -> TokenParser a -> [PositionedToken] -> Either P.ParseError a
122138runTokenParser filePath p = P.runParser p (ParseState 0) filePath
139+
140+-- |
141+-- Convert from Parsec sourcepos
142+--
143+toSourcePos :: P.SourcePos -> SourcePos
144+toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)
src/Language/PureScript/Parser/Declarations.hs+116−112
@@ -1,22 +1,19 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE TupleSections #-}
4−
51-- |
62-- Parsers for module definitions and declarations
73--
8−module Language.PureScript.Parser.Declarations (
9− parseDeclaration,
10− parseModule,
11− parseModules,
12− parseModulesFromFiles,
13− parseValue,
14− parseGuard,
15− parseBinder,
16− parseBinderNoParens,
17− parseImportDeclaration',
18− parseLocalDeclaration
19−) where
4+module Language.PureScript.Parser.Declarations
5+ ( parseDeclaration
6+ , parseModule
7+ , parseModulesFromFiles
8+ , parseModuleFromFile
9+ , parseValue
10+ , parseGuard
11+ , parseBinder
12+ , parseBinderNoParens
13+ , parseImportDeclaration'
14+ , parseLocalDeclaration
15+ , toPositionedError
16+ ) where
2017
2118import Prelude hiding (lex)
2219
@@ -46,13 +43,20 @@ import qualified Text.Parsec.Expr as P
4643-- |
4744-- Read source position information
4845--
49−withSourceSpan :: (SourceSpan -> [Comment] -> a -> a) -> P.Parsec [PositionedToken] u a -> P.Parsec [PositionedToken] u a
46+withSourceSpan
47+ :: (SourceSpan -> [Comment] -> a -> a)
48+ -> P.Parsec [PositionedToken] u a
49+ -> P.Parsec [PositionedToken] u a
5050withSourceSpan f p = do
5151 start <- P.getPosition
5252 comments <- C.readComments
5353 x <- p
5454 end <- P.getPosition
55− let sp = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)
55+ input <- P.getInput
56+ let end' = case input of
57+ pt:_ -> ptPrevEndPos pt
58+ _ -> Nothing
59+ let sp = SourceSpan (P.sourceName start) (C.toSourcePos start) (C.toSourcePos $ fromMaybe end end')
5660 return $ f sp comments x
5761
5862kindedIdent :: TokenParser (String, Maybe Kind)
@@ -62,7 +66,7 @@ kindedIdent = (, Nothing) <$> identifier
6266parseDataDeclaration :: TokenParser Declaration
6367parseDataDeclaration = do
6468 dtype <- (reserved "data" *> return Data) <|> (reserved "newtype" *> return Newtype)
65− name <- indented *> properName
69+ name <- indented *> typeName
6670 tyArgs <- many (indented *> kindedIdent)
6771 ctors <- P.option [] $ do
6872 indented *> equals
@@ -76,7 +80,7 @@ parseTypeDeclaration =
7680
7781parseTypeSynonymDeclaration :: TokenParser Declaration
7882parseTypeSynonymDeclaration =
79− TypeSynonymDeclaration <$> (reserved "type" *> indented *> properName)
83+ TypeSynonymDeclaration <$> (reserved "type" *> indented *> typeName)
8084 <*> many (indented *> kindedIdent)
8185 <*> (indented *> equals *> noWildcards parsePolyType)
8286
@@ -93,6 +97,7 @@ parseValueDeclaration = do
9397 where
9498 parseValueWithWhereClause :: TokenParser Expr
9599 parseValueWithWhereClause = do
100+ C.indented
96101 value <- parseValue
97102 whereClause <- P.optionMaybe $ do
98103 C.indented
@@ -103,7 +108,7 @@ parseValueDeclaration = do
103108
104109parseExternDeclaration :: TokenParser Declaration
105110parseExternDeclaration = reserved "foreign" *> indented *> reserved "import" *> indented *>
106− (ExternDataDeclaration <$> (reserved "data" *> indented *> properName)
111+ (ExternDataDeclaration <$> (reserved "data" *> indented *> typeName)
107112 <*> (indented *> doubleColon *> parseKind)
108113 <|> (do ident <- parseIdent
109114 ty <- indented *> doubleColon *> noWildcards parsePolyType
@@ -122,38 +127,33 @@ parseFixityDeclaration :: TokenParser Declaration
122127parseFixityDeclaration = do
123128 fixity <- parseFixity
124129 indented
125− alias <- P.optionMaybe $ parseQualified aliased <* reserved "as"
126− name <- symbol
127− return $ FixityDeclaration fixity name alias
130+ FixityDeclaration
131+ <$> ((Right <$> typeFixity fixity) <|> (Left <$> valueFixity fixity))
128132 where
129− aliased = (AliasValue . Ident <$> identifier)
130− <|> (AliasConstructor <$> properName)
131− <|> reserved "type" *> (AliasType <$> properName)
133+ typeFixity fixity =
134+ TypeFixity fixity
135+ <$> (reserved "type" *> parseQualified typeName)
136+ <*> (reserved "as" *> parseOperator)
137+ valueFixity fixity =
138+ ValueFixity fixity
139+ <$> parseQualified ((Left <$> parseIdent) <|> (Right <$> properName))
140+ <*> (reserved "as" *> parseOperator)
132141
133142parseImportDeclaration :: TokenParser Declaration
134−parseImportDeclaration = do
135− (mn, declType, asQ, isOldSyntax) <- parseImportDeclaration'
136− return $ ImportDeclaration mn declType asQ isOldSyntax
143+parseImportDeclaration = withSourceSpan PositionedDeclaration $ do
144+ (mn, declType, asQ) <- parseImportDeclaration'
145+ return $ ImportDeclaration mn declType asQ
137146
138−parseImportDeclaration' :: TokenParser (ModuleName, ImportDeclarationType, Maybe ModuleName, Bool)
147+parseImportDeclaration' :: TokenParser (ModuleName, ImportDeclarationType, Maybe ModuleName)
139148parseImportDeclaration' = do
140149 reserved "import"
141150 indented
142− qualImport <|> stdImport
151+ moduleName' <- moduleName
152+ declType <- reserved "hiding" *> qualifyingList Hiding <|> qualifyingList Explicit
153+ qName <- P.optionMaybe qualifiedName
154+ return (moduleName', declType, qName)
143155 where
144− stdImport = do
145− moduleName' <- moduleName
146− declType <- reserved "hiding" *> qualifyingList Hiding <|> qualifyingList Explicit
147− qName <- P.optionMaybe qualifiedName
148− return (moduleName', declType, qName, False)
149156 qualifiedName = reserved "as" *> moduleName
150− qualImport = do
151− reserved "qualified"
152− indented
153− moduleName' <- moduleName
154− declType <- qualifyingList Explicit
155− qName <- qualifiedName
156− return (moduleName', declType, Just qName, True)
157157 qualifyingList expectedType = do
158158 declType <- P.optionMaybe (expectedType <$> (indented *> parens (commaSep parseDeclarationRef)))
159159 return $ fromMaybe Implicit declType
@@ -162,15 +162,16 @@ parseDeclarationRef :: TokenParser DeclarationRef
162162parseDeclarationRef =
163163 withSourceSpan PositionedDeclarationRef
164164 $ (ValueRef <$> parseIdent)
165− <|> parseProperRef
165+ <|> (ValueOpRef <$> parens parseOperator)
166+ <|> parseTypeRef
166167 <|> (TypeClassRef <$> (reserved "class" *> properName))
167168 <|> (ModuleRef <$> (indented *> reserved "module" *> moduleName))
168− <|> (TypeOpRef <$> (indented *> reserved "type" *> parens (Op <$> symbol)))
169+ <|> (TypeOpRef <$> (indented *> reserved "type" *> parens parseOperator))
169170 where
170− parseProperRef = do
171− name <- properName
171+ parseTypeRef = do
172+ name <- typeName
172173 dctors <- P.optionMaybe $ parens (symbol' ".." *> pure Nothing <|> Just <$> commaSep properName)
173− return $ maybe (ProperRef (runProperName name)) (TypeRef name) dctors
174+ return $ TypeRef name (fromMaybe (Just []) dctors)
174175
175176parseTypeClassDeclaration :: TokenParser Declaration
176177parseTypeClassDeclaration = do
@@ -188,7 +189,9 @@ parseTypeClassDeclaration = do
188189 return $ TypeClassDeclaration className idents implies members
189190
190191parseConstraint :: TokenParser Constraint
191−parseConstraint = (,) <$> parseQualified properName <*> P.many (noWildcards parseTypeAtom)
192+parseConstraint = Constraint <$> parseQualified properName
193+ <*> P.many (noWildcards parseTypeAtom)
194+ <*> pure Nothing
192195
193196parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)
194197parseInstanceDeclaration = do
@@ -231,7 +234,6 @@ parseDeclaration = positioned (P.choice
231234 , parseValueDeclaration
232235 , parseExternDeclaration
233236 , parseFixityDeclaration
234− , parseImportDeclaration
235237 , parseTypeClassDeclaration
236238 , parseTypeInstanceDeclaration
237239 , parseDerivingInstanceDeclaration
@@ -255,48 +257,56 @@ parseModule = do
255257 name <- moduleName
256258 exports <- P.optionMaybe $ parens $ commaSep1 parseDeclarationRef
257259 reserved "where"
258− decls <- mark (P.many (same *> parseDeclaration))
260+ decls <- mark $ do
261+ -- TODO: extract a module header structure here, and provide a
262+ -- parseModuleHeader function. This should allow us to speed up rebuilds
263+ -- by only parsing as far as the module header. See PR #2054.
264+ imports <- P.many (same *> parseImportDeclaration)
265+ decls <- P.many (same *> parseDeclaration)
266+ return (imports ++ decls)
267+ _ <- P.eof
259268 end <- P.getPosition
260− let ss = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)
269+ let ss = SourceSpan (P.sourceName start) (C.toSourcePos start) (C.toSourcePos end)
261270 return $ Module ss comments name decls exports
262271
263272-- | Parse a collection of modules in parallel
264−parseModulesFromFiles :: forall m k. (MonadError MultipleErrors m) =>
265− (k -> FilePath) -> [(k, String)] -> m [(k, Module)]
266−parseModulesFromFiles toFilePath input = do
267− modules <- flip parU id $ map wrapError $ inParallel $ flip map input $ \(k, content) -> do
268− let filename = toFilePath k
269− ts <- lex filename content
270− ms <- runTokenParser filename parseModules ts
271− return (k, ms)
272− return $ collect modules
273+parseModulesFromFiles
274+ :: forall m k
275+ . MonadError MultipleErrors m
276+ => (k -> FilePath)
277+ -> [(k, String)]
278+ -> m [(k, Module)]
279+parseModulesFromFiles toFilePath input =
280+ flip parU wrapError . inParallel . flip map input $ parseModuleFromFile toFilePath
273281 where
274− collect :: [(k, [v])] -> [(k, v)]
275− collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
276282 wrapError :: Either P.ParseError a -> m a
277283 wrapError = either (throwError . MultipleErrors . pure . toPositionedError) return
278284 -- It is enough to force each parse result to WHNF, since success or failure can't be
279285 -- determined until the end of the file, so this effectively distributes parsing of each file
280286 -- to a different spark.
281− inParallel :: [Either P.ParseError (k, [Module])] -> [Either P.ParseError (k, [Module])]
287+ inParallel :: [Either P.ParseError (k, a)] -> [Either P.ParseError (k, a)]
282288 inParallel = withStrategy (parList rseq)
283289
290+
291+-- | Parses a single module with FilePath for eventual parsing errors
292+parseModuleFromFile
293+ :: (k -> FilePath)
294+ -> (k, String)
295+ -> Either P.ParseError (k, Module)
296+parseModuleFromFile toFilePath (k, content) = do
297+ let filename = toFilePath k
298+ ts <- lex filename content
299+ m <- runTokenParser filename parseModule ts
300+ pure (k, m)
301+
302+-- | Converts a @ParseError@ into a @PositionedError@
284303toPositionedError :: P.ParseError -> ErrorMessage
285304toPositionedError perr = ErrorMessage [ PositionedError (SourceSpan name start end) ] (ErrorParsingModule perr)
286305 where
287− name = (P.sourceName . P.errorPos) perr
288− start = (toSourcePos . P.errorPos) perr
306+ name = (P.sourceName . P.errorPos) perr
307+ start = (C.toSourcePos . P.errorPos) perr
289308 end = start
290309
291−toSourcePos :: P.SourcePos -> SourcePos
292−toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)
293−
294−-- |
295−-- Parse a collection of modules
296−--
297−parseModules :: TokenParser [Module]
298−parseModules = mark (P.many (same *> parseModule)) <* P.eof
299−
300310booleanLiteral :: TokenParser Bool
301311booleanLiteral = (reserved "true" >> return True) P.<|> (reserved "false" >> return False)
302312
@@ -331,8 +341,7 @@ parseIdentifierAndValue =
331341parseAbs :: TokenParser Expr
332342parseAbs = do
333343 symbol' "\\"
334− -- TODO: remove this 'try' after operator aliases are finished (0.9)
335− args <- P.many1 (C.indented *> (Abs <$> (Left <$> P.try C.parseIdent <|> Right <$> parseBinderNoParens)))
344+ args <- P.many1 (C.indented *> (Abs <$> (Left <$> C.parseIdent <|> Right <$> parseBinderNoParens)))
336345 C.indented *> rarrow
337346 value <- parseValue
338347 return $ toFunction args value
@@ -351,7 +360,7 @@ parseCase = Case <$> P.between (reserved "case") (C.indented *> reserved "of") (
351360 <*> (C.indented *> C.mark (P.many1 (C.same *> C.mark parseCaseAlternative)))
352361
353362parseCaseAlternative :: TokenParser CaseAlternative
354−parseCaseAlternative = CaseAlternative <$> (commaSep1 parseBinder)
363+parseCaseAlternative = CaseAlternative <$> commaSep1 parseBinder
355364 <*> (Left <$> (C.indented *>
356365 P.many1 ((,) <$> parseGuard
357366 <*> (indented *> rarrow *> parseValue)
@@ -382,7 +391,7 @@ parseValueAtom = P.choice
382391 , Literal <$> parseStringLiteral
383392 , Literal <$> parseBooleanLiteral
384393 , Literal <$> parseArrayLiteral parseValue
385− , Literal <$> P.try (parseObjectLiteral parseIdentifierAndValue)
394+ , Literal <$> parseObjectLiteral parseIdentifierAndValue
386395 , parseAbs
387396 , P.try parseConstructor
388397 , P.try parseVar
@@ -391,7 +400,7 @@ parseValueAtom = P.choice
391400 , parseDo
392401 , parseLet
393402 , P.try $ Parens <$> parens parseValue
394− , parseOperatorSection
403+ , Op <$> parseQualified (parens parseOperator)
395404 , parseHole
396405 ]
397406
@@ -399,14 +408,9 @@ parseValueAtom = P.choice
399408-- Parse an expression in backticks or an operator
400409--
401410parseInfixExpr :: TokenParser Expr
402−parseInfixExpr = P.between tick tick parseValue
403− <|> Var <$> parseQualified (Op <$> symbol)
404−
405−parseOperatorSection :: TokenParser Expr
406−parseOperatorSection = parens $ left <|> right
407− where
408− right = OperatorSection <$> parseInfixExpr <* indented <*> (Right <$> indexersAndAccessors)
409− left = flip OperatorSection <$> (Left <$> indexersAndAccessors) <* indented <*> parseInfixExpr
411+parseInfixExpr
412+ = P.between tick tick parseValue
413+ <|> Op <$> parseQualified parseOperator
410414
411415parseHole :: TokenParser Expr
412416parseHole = Hole <$> holeLit
@@ -496,10 +500,8 @@ parseArrayBinder = LiteralBinder <$> parseArrayLiteral (C.indented *> parseBinde
496500
497501parseVarOrNamedBinder :: TokenParser Binder
498502parseVarOrNamedBinder = do
499− -- TODO: once operator aliases are finalized in 0.9, this 'try' won't be needed
500− -- any more since identifiers in binders won't be 'Op's.
501− name <- P.try C.parseIdent
502− let parseNamedBinder = NamedBinder name <$> (at *> C.indented *> parseBinder)
503+ name <- C.parseIdent
504+ let parseNamedBinder = NamedBinder name <$> (at *> C.indented *> parseBinderAtom)
503505 parseNamedBinder <|> return (VarBinder name)
504506
505507parseNullBinder :: TokenParser Binder
@@ -507,12 +509,12 @@ parseNullBinder = underscore *> return NullBinder
507509
508510parseIdentifierAndBinder :: TokenParser (String, Binder)
509511parseIdentifierAndBinder =
510− do name <- lname
511− b <- P.option (VarBinder (Ident name)) rest
512− return (name, b)
513− <|> (,) <$> stringLiteral <*> rest
512+ do name <- lname
513+ b <- P.option (VarBinder (Ident name)) rest
514+ return (name, b)
515+ <|> (,) <$> stringLiteral <*> rest
514516 where
515− rest = C.indented *> (equals <|> colon) *> C.indented *> parseBinder
517+ rest = C.indented *> colon *> C.indented *> parseBinder
516518
517519-- |
518520-- Parse a binder
@@ -531,25 +533,27 @@ parseBinder =
531533 return (BinaryNoParensBinder op)) P.AssocRight
532534 ]
533535 ]
536+
534537 -- TODO: parsePolyType when adding support for polymorphic types
535538 postfixTable = [ \b -> flip TypedBinder b <$> (indented *> doubleColon *> parseType)
536539 ]
537− parseBinderAtom :: TokenParser Binder
538− parseBinderAtom = P.choice
539− [ parseNullBinder
540− , LiteralBinder <$> parseCharLiteral
541− , LiteralBinder <$> parseStringLiteral
542− , LiteralBinder <$> parseBooleanLiteral
543− , parseNumberLiteral
544− , parseVarOrNamedBinder
545− , parseConstructorBinder
546− , parseObjectBinder
547− , parseArrayBinder
548− , ParensInBinder <$> parens parseBinder
549− ] P.<?> "binder"
550540
551541 parseOpBinder :: TokenParser Binder
552− parseOpBinder = OpBinder <$> parseQualified (Op <$> symbol)
542+ parseOpBinder = OpBinder <$> parseQualified parseOperator
543+
544+parseBinderAtom :: TokenParser Binder
545+parseBinderAtom = P.choice
546+ [ parseNullBinder
547+ , LiteralBinder <$> parseCharLiteral
548+ , LiteralBinder <$> parseStringLiteral
549+ , LiteralBinder <$> parseBooleanLiteral
550+ , parseNumberLiteral
551+ , parseVarOrNamedBinder
552+ , parseConstructorBinder
553+ , parseObjectBinder
554+ , parseArrayBinder
555+ , ParensInBinder <$> parens parseBinder
556+ ] P.<?> "binder"
553557
554558-- |
555559-- Parse a binder as it would appear in a top level declaration
src/Language/PureScript/Parser/JS.hsdeleted−60
@@ -1,60 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Foreign
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−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15−{-# LANGUAGE FlexibleContexts #-}
16−
17−module Language.PureScript.Parser.JS
18− ( ForeignJS()
19− , parseForeignModulesFromFiles
20− ) where
21−
22−import Prelude ()
23−import Prelude.Compat hiding (lex)
24−
25−import Control.Monad (forM_, when, msum)
26−import Control.Monad.Error.Class (MonadError(..))
27−import Control.Monad.Writer.Class (MonadWriter(..))
28−import Data.Function (on)
29−import Data.List (sortBy, groupBy)
30−import Language.PureScript.Errors
31−import Language.PureScript.Names
32−import Language.PureScript.Parser.Common
33−import Language.PureScript.Parser.Lexer
34−import qualified Data.Map as M
35−import qualified Text.Parsec as PS
36−
37−type ForeignJS = String
38−
39−parseForeignModulesFromFiles :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
40− => [(FilePath, ForeignJS)]
41− -> m (M.Map ModuleName FilePath)
42−parseForeignModulesFromFiles files = do
43− foreigns <- parU files $ \(path, file) ->
44− case findModuleName (lines file) of
45− Just name -> return (name, path)
46− Nothing -> throwError (errorMessage $ ErrorParsingFFIModule path Nothing)
47− let grouped = groupBy ((==) `on` fst) $ sortBy (compare `on` fst) foreigns
48− forM_ grouped $ \grp ->
49− when (length grp > 1) $ do
50− let mn = fst (head grp)
51− paths = map snd grp
52− tell $ errorMessage $ MultipleFFIModules mn paths
53− return $ M.fromList foreigns
54−
55−findModuleName :: [String] -> Maybe ModuleName
56−findModuleName = msum . map parseComment
57− where
58− parseComment :: String -> Maybe ModuleName
59− parseComment s = either (const Nothing) Just $
60− lex "" s >>= runTokenParser "" (symbol' "//" *> reserved "module" *> moduleName <* PS.eof)
src/Language/PureScript/Parser/Kinds.hs+6−16
@@ -1,28 +1,14 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Parser.Kinds
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-- A parser for kinds
133--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.Parser.Kinds (parseKind) where
155
16−module Language.PureScript.Parser.Kinds (
17− parseKind
18−) where
19−
20−import Prelude ()
216import Prelude.Compat
227
238import Language.PureScript.Kinds
249import Language.PureScript.Parser.Common
2510import Language.PureScript.Parser.Lexer
11+
2612import qualified Text.Parsec as P
2713import qualified Text.Parsec.Expr as P
2814
@@ -32,10 +18,14 @@ parseStar = const Star <$> symbol' "*"
3218parseBang :: TokenParser Kind
3319parseBang = const Bang <$> symbol' "!"
3420
21+parseSymbol :: TokenParser Kind
22+parseSymbol = const Symbol <$> uname' "Symbol"
23+
3524parseTypeAtom :: TokenParser Kind
3625parseTypeAtom = indented *> P.choice
3726 [ parseStar
3827 , parseBang
28+ , parseSymbol
3929 , parens parseKind
4030 ]
4131-- |
src/Language/PureScript/Parser/Lexer.hs+41−35
@@ -1,20 +1,6 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Parser.Lexer
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-- The first step in the parsing process - turns source code into a list of lexemes
133--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE TupleSections #-}
17−
184module Language.PureScript.Parser.Lexer
195 ( PositionedToken(..)
206 , Token()
@@ -55,6 +41,7 @@ module Language.PureScript.Parser.Lexer
5541 , commaSep1
5642 , lname
5743 , qualifier
44+ , tyname
5845 , uname
5946 , uname'
6047 , mname
@@ -75,15 +62,14 @@ module Language.PureScript.Parser.Lexer
7562
7663import Prelude hiding (lex)
7764
78−import Data.Char (isSpace, isAscii, isSymbol, isAlphaNum)
79−
65+import Control.Applicative
8066import Control.Monad (void, guard)
81−import Data.Functor.Identity
8267
83−import Control.Applicative
68+import Data.Char (isSpace, isAscii, isSymbol, isAlphaNum)
69+import Data.Functor.Identity
8470
85−import Language.PureScript.Parser.State
8671import Language.PureScript.Comments
72+import Language.PureScript.Parser.State
8773
8874import qualified Text.Parsec as P
8975import qualified Text.Parsec.Token as PT
@@ -152,7 +138,12 @@ prettyPrintToken (Number n) = either show show n
152138prettyPrintToken (HoleLit name) = "?" ++ name
153139
154140data PositionedToken = PositionedToken
155− { ptSourcePos :: P.SourcePos
141+ { -- | Start position of this token
142+ ptSourcePos :: P.SourcePos
143+ -- | End position of this token (not including whitespace)
144+ , ptEndPos :: P.SourcePos
145+ -- | End position of the previous token
146+ , ptPrevEndPos :: Maybe P.SourcePos
156147 , ptToken :: Token
157148 , ptComments :: [Comment]
158149 } deriving (Eq)
@@ -162,7 +153,13 @@ instance Show PositionedToken where
162153 show = prettyPrintToken . ptToken
163154
164155lex :: FilePath -> String -> Either P.ParseError [PositionedToken]
165−lex = P.parse parseTokens
156+lex f s = updatePositions <$> P.parse parseTokens f s
157+
158+updatePositions :: [PositionedToken] -> [PositionedToken]
159+updatePositions [] = []
160+updatePositions (x:xs) = x : zipWith update (x:xs) xs
161+ where
162+ update PositionedToken { ptEndPos = pos } pt = pt { ptPrevEndPos = Just pos }
166163
167164parseTokens :: P.Parsec String u [PositionedToken]
168165parseTokens = whitespace *> P.many parsePositionedToken <* P.skipMany parseComment <* P.eof
@@ -184,7 +181,9 @@ parsePositionedToken = P.try $ do
184181 comments <- P.many parseComment
185182 pos <- P.getPosition
186183 tok <- parseToken
187− return $ PositionedToken pos tok comments
184+ pos' <- P.getPosition
185+ whitespace
186+ return $ PositionedToken pos pos' Nothing tok comments
188187
189188parseToken :: P.Parsec String u Token
190189parseToken = P.choice
@@ -215,20 +214,21 @@ parseToken = P.choice
215214 , P.try $ P.char '_' *> P.notFollowedBy identLetter *> pure Underscore
216215 , HoleLit <$> P.try (P.char '?' *> P.many1 identLetter)
217216 , LName <$> parseLName
218− , do uName <- parseUName
219− (guard (validModuleName uName) >> Qualifier uName <$ P.char '.') <|> pure (UName uName)
217+ , parseUName >>= \uName ->
218+ (guard (validModuleName uName) >> Qualifier uName <$ P.char '.')
219+ <|> pure (UName uName)
220220 , Symbol <$> parseSymbol
221221 , CharLiteral <$> parseCharLiteral
222222 , StringLiteral <$> parseStringLiteral
223223 , Number <$> parseNumber
224− ] <* whitespace
224+ ]
225225
226226 where
227227 parseLName :: P.Parsec String u String
228228 parseLName = (:) <$> identStart <*> P.many identLetter
229229
230230 parseUName :: P.Parsec String u String
231− parseUName = (:) <$> P.upper <*> P.many uidentLetter
231+ parseUName = (:) <$> P.upper <*> P.many identLetter
232232
233233 parseSymbol :: P.Parsec String u String
234234 parseSymbol = P.many1 symbolChar
@@ -239,9 +239,6 @@ parseToken = P.choice
239239 identLetter :: P.Parsec String u Char
240240 identLetter = P.alphaNum <|> P.oneOf "_'"
241241
242− uidentLetter :: P.Parsec String u Char
243− uidentLetter = P.alphaNum <|> P.char '_'
244−
245242 symbolChar :: P.Parsec String u Char
246243 symbolChar = P.satisfy isSymbolChar
247244
@@ -432,6 +429,18 @@ reserved s = token go P.<?> show s
432429
433430uname :: TokenParser String
434431uname = token go P.<?> "proper name"
432+ where
433+ go (UName s) | validUName s = Just s
434+ go _ = Nothing
435+
436+uname' :: String -> TokenParser ()
437+uname' s = token go P.<?> "proper name"
438+ where
439+ go (UName s') | s == s' = Just ()
440+ go _ = Nothing
441+
442+tyname :: TokenParser String
443+tyname = token go P.<?> "type name"
435444 where
436445 go (UName s) = Just s
437446 go _ = Nothing
@@ -442,12 +451,6 @@ mname = token go P.<?> "module name"
442451 go (UName s) | validModuleName s = Just s
443452 go _ = Nothing
444453
445−uname' :: String -> TokenParser ()
446−uname' s = token go P.<?> show s
447− where
448− go (UName s') | s == s' = Just ()
449− go _ = Nothing
450−
451454symbol :: TokenParser String
452455symbol = token go P.<?> "symbol"
453456 where
@@ -498,6 +501,9 @@ identifier = token go P.<?> "identifier"
498501validModuleName :: String -> Bool
499502validModuleName s = '_' `notElem` s
500503
504+validUName :: String -> Bool
505+validUName s = '\'' `notElem` s
506+
501507-- |
502508-- A list of purescript reserved identifiers
503509--
src/Language/PureScript/Parser/State.hs+2−14
@@ -1,20 +1,10 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Parser.State
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-- State for the parser monad
133--
14−-----------------------------------------------------------------------------
15−
164module Language.PureScript.Parser.State where
175
6+import Prelude.Compat
7+
188import qualified Text.Parsec as P
199
2010-- |
@@ -26,5 +16,3 @@ data ParseState = ParseState {
2616 --
2717 indentationLevel :: P.Column
2818 } deriving Show
29−
30−
src/Language/PureScript/Parser/Types.hs+25−15
@@ -1,19 +1,21 @@
1−module Language.PureScript.Parser.Types (
2− parseType,
3− parsePolyType,
4− noWildcards,
5− parseTypeAtom
6−) where
1+module Language.PureScript.Parser.Types
2+ ( parseType
3+ , parsePolyType
4+ , noWildcards
5+ , parseTypeAtom
6+ ) where
7+
8+import Prelude.Compat
79
810import Control.Applicative
911import Control.Monad (when, unless)
1012
11−import Language.PureScript.Names
12−import Language.PureScript.Types
13+import Language.PureScript.AST.SourcePos
14+import Language.PureScript.Environment
1315import Language.PureScript.Parser.Common
1416import Language.PureScript.Parser.Kinds
1517import Language.PureScript.Parser.Lexer
16−import Language.PureScript.Environment
18+import Language.PureScript.Types
1719
1820import qualified Text.Parsec as P
1921import qualified Text.Parsec.Expr as P
@@ -22,10 +24,17 @@ parseFunction :: TokenParser Type
2224parseFunction = parens rarrow >> return tyFunction
2325
2426parseObject :: TokenParser Type
25−parseObject = braces $ TypeApp tyObject <$> parseRow
27+parseObject = braces $ TypeApp tyRecord <$> parseRow
28+
29+parseTypeLevelString :: TokenParser Type
30+parseTypeLevelString = TypeLevelString <$> stringLiteral
2631
2732parseTypeWildcard :: TokenParser Type
28−parseTypeWildcard = underscore >> return TypeWildcard
33+parseTypeWildcard = do
34+ start <- P.getPosition
35+ let end = P.incSourceColumn start 1
36+ underscore
37+ return $ TypeWildcard (SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end))
2938
3039parseTypeVariable :: TokenParser Type
3140parseTypeVariable = do
@@ -34,7 +43,7 @@ parseTypeVariable = do
3443 return $ TypeVar ident
3544
3645parseTypeConstructor :: TokenParser Type
37−parseTypeConstructor = TypeConstructor <$> parseQualified properName
46+parseTypeConstructor = TypeConstructor <$> parseQualified typeName
3847
3948parseForAll :: TokenParser Type
4049parseForAll = mkForAll <$> ((reserved "forall" <|> reserved "∀") *> P.many1 (indented *> identifier) <* indented <* dot)
@@ -47,6 +56,7 @@ parseTypeAtom :: TokenParser Type
4756parseTypeAtom = indented *> P.choice
4857 [ P.try parseConstrainedType
4958 , P.try parseFunction
59+ , parseTypeLevelString
5060 , parseObject
5161 , parseTypeWildcard
5262 , parseForAll
@@ -69,16 +79,16 @@ parseConstrainedType = do
6979 className <- parseQualified properName
7080 indented
7181 ty <- P.many parseTypeAtom
72− return (className, ty)
82+ return (Constraint className ty Nothing)
7383
7484
7585parseAnyType :: TokenParser Type
7686parseAnyType = P.buildExpressionParser operators (buildPostfixParser postfixTable parseTypeAtom) P.<?> "type"
7787 where
78− operators = [ [ P.Infix (P.try (parseQualified (Op <$> symbol)) >>= \ident ->
88+ operators = [ [ P.Infix (return TypeApp) P.AssocLeft ]
89+ , [ P.Infix (P.try (parseQualified parseOperator) >>= \ident ->
7990 return (BinaryNoParensType (TypeOp ident))) P.AssocRight
8091 ]
81− , [ P.Infix (return TypeApp) P.AssocLeft ]
8292 , [ P.Infix (rarrow >> return function) P.AssocRight ]
8393 ]
8494 postfixTable = [ \t -> KindedType t <$> (indented *> doubleColon *> parseKind)
src/Language/PureScript/Pretty.hs+2−14
@@ -1,13 +1,3 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Pretty
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-- A collection of pretty printers for core data types:
133--
@@ -19,11 +9,9 @@
199--
2010-- [@Language.PureScript.Pretty.JS@] Pretty printer for values, used for code generation
2111--
22−-----------------------------------------------------------------------------
23−
2412module Language.PureScript.Pretty (module P) where
2513
14+import Language.PureScript.Pretty.JS as P
2615import Language.PureScript.Pretty.Kinds as P
27−import Language.PureScript.Pretty.Values as P
2816import Language.PureScript.Pretty.Types as P
29−import Language.PureScript.Pretty.JS as P
17+import Language.PureScript.Pretty.Values as P
src/Language/PureScript/Pretty/Common.hs+8−16
@@ -1,30 +1,18 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Pretty.Common
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+
113-- |
124-- Common pretty-printing utility functions
135--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17−
186module Language.PureScript.Pretty.Common where
197
20−import Prelude ()
218import Prelude.Compat
229
2310import Control.Monad.State (StateT, modify, get)
11+
2412import Data.List (elemIndices, intersperse)
2513
26−import Language.PureScript.Parser.Lexer (reservedPsNames, isUnquotedKey)
2714import Language.PureScript.AST (SourcePos(..), SourceSpan(..))
15+import Language.PureScript.Parser.Lexer (reservedPsNames, isUnquotedKey)
2816
2917import Text.PrettyPrint.Boxes
3018
@@ -165,3 +153,7 @@ before b1 b2 | rows b1 > 1 = b1 // b2
165153
166154beforeWithSpace :: Box -> Box -> Box
167155beforeWithSpace b1 = before (b1 <> text " ")
156+
157+-- | Place a Box on the bottom right of another
158+endWith :: Box -> Box -> Box
159+endWith l r = l <> vcat top [emptyBox (rows l - 1) (cols r), r]
src/Language/PureScript/Pretty/JS.hs+10−25
@@ -1,45 +1,30 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Pretty.JS
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-- Pretty printer for the Javascript AST
133--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.Pretty.JS
5+ ( prettyPrintJS
6+ , prettyPrintJSWithSourceMaps
7+ ) where
158
16−module Language.PureScript.Pretty.JS (
17− prettyPrintJS, prettyPrintJSWithSourceMaps
18−) where
19−
20−import Prelude ()
219import Prelude.Compat
2210
23−import Data.Maybe (fromMaybe)
24−
2511import Control.Arrow ((<+>))
2612import Control.Monad.State hiding (sequence)
2713import Control.PatternArrows
2814import qualified Control.Arrow as A
2915
30−import Language.PureScript.Crash
16+import Data.Maybe (fromMaybe)
17+import Data.Monoid
18+
19+import Language.PureScript.AST (SourceSpan(..))
3120import Language.PureScript.CodeGen.JS.AST
3221import Language.PureScript.CodeGen.JS.Common
33−import Language.PureScript.Pretty.Common
3422import Language.PureScript.Comments
35−
36−
37−import Language.PureScript.AST (SourceSpan(..))
23+import Language.PureScript.Crash
24+import Language.PureScript.Pretty.Common
3825
3926import Numeric
4027
41−import Data.Monoid
42−
4328literals :: (Emit gen) => Pattern PrinterState JS gen
4429literals = mkPattern' match'
4530 where
src/Language/PureScript/Pretty/Kinds.hs+11−18
@@ -1,26 +1,16 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Pretty.Kinds
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-- Pretty printer for kinds
133--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.Pretty.Kinds
5+ ( prettyPrintKind
6+ ) where
157
16−module Language.PureScript.Pretty.Kinds (
17− prettyPrintKind
18−) where
19−
20−import Data.Maybe (fromMaybe)
8+import Prelude.Compat
219
2210import Control.Arrow (ArrowPlus(..))
23−import Control.PatternArrows
11+import Control.PatternArrows as PA
12+
13+import Data.Maybe (fromMaybe)
2414
2515import Language.PureScript.Crash
2616import Language.PureScript.Kinds
@@ -31,6 +21,7 @@ typeLiterals = mkPattern match
3121 where
3222 match Star = Just "*"
3323 match Bang = Just "!"
24+ match Symbol = Just "Symbol"
3425 match (KUnknown u) = Just $ 'u' : show u
3526 match _ = Nothing
3627
@@ -48,7 +39,9 @@ funKind = mkPattern match
4839
4940-- | Generate a pretty-printed string representing a Kind
5041prettyPrintKind :: Kind -> String
51−prettyPrintKind = fromMaybe (internalError "Incomplete pattern") . pattern matchKind ()
42+prettyPrintKind
43+ = fromMaybe (internalError "Incomplete pattern")
44+ . PA.pattern matchKind ()
5245 where
5346 matchKind :: Pattern () Kind String
5447 matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
src/Language/PureScript/Pretty/Types.hs+22−13
@@ -10,40 +10,43 @@ module Language.PureScript.Pretty.Types
1010 , prettyPrintRow
1111 ) where
1212
13−import Data.Maybe (fromMaybe)
13+import Prelude.Compat
1414
1515import Control.Arrow ((<+>))
16−import Control.PatternArrows
16+import Control.PatternArrows as PA
17+
18+import Data.Maybe (fromMaybe)
1719
1820import Language.PureScript.Crash
19−import Language.PureScript.Types
20−import Language.PureScript.Names
21+import Language.PureScript.Environment
2122import Language.PureScript.Kinds
23+import Language.PureScript.Names
2224import Language.PureScript.Pretty.Common
2325import Language.PureScript.Pretty.Kinds
24−import Language.PureScript.Environment
26+import Language.PureScript.Types
2527
2628import Text.PrettyPrint.Boxes hiding ((<+>))
2729
2830typeLiterals :: Pattern () Type Box
2931typeLiterals = mkPattern match
3032 where
31− match TypeWildcard = Just $ text "_"
33+ match TypeWildcard{} = Just $ text "_"
3234 match (TypeVar var) = Just $ text var
35+ match (TypeLevelString s) = Just . text $ show s
3336 match (PrettyPrintObject row) = Just $ prettyPrintRowWith '{' '}' row
3437 match (TypeConstructor ctor) = Just $ text $ runProperName $ disqualify ctor
35− match (TUnknown u) = Just $ text $ '_' : show u
38+ match (TUnknown u) = Just $ text $ 't' : show u
3639 match (Skolem name s _ _) = Just $ text $ name ++ show s
3740 match REmpty = Just $ text "()"
3841 match row@RCons{} = Just $ prettyPrintRowWith '(' ')' row
3942 match (BinaryNoParensType op l r) =
4043 Just $ typeAsBox l <> text " " <> typeAsBox op <> text " " <> typeAsBox r
41− match (TypeOp op) = Just $ text $ showQualified runIdent op
44+ match (TypeOp op) = Just $ text $ showQualified runOpName op
4245 match _ = Nothing
4346
4447constraintsAsBox :: [Constraint] -> Box -> Box
45−constraintsAsBox [(pn, tys)] ty = text "(" <> constraintAsBox pn tys <> text ") => " <> ty
46−constraintsAsBox xs ty = vcat left (zipWith (\i (pn, tys) -> text (if i == 0 then "( " else ", ") <> constraintAsBox pn tys) [0 :: Int ..] xs) `before` (text ") => " <> ty)
48+constraintsAsBox [(Constraint pn tys _)] ty = text "(" <> constraintAsBox pn tys <> text ") => " <> ty
49+constraintsAsBox xs ty = vcat left (zipWith (\i (Constraint pn tys _) -> text (if i == 0 then "( " else ", ") <> constraintAsBox pn tys) [0 :: Int ..] xs) `before` (text ") => " <> ty)
4750
4851constraintAsBox :: Qualified (ProperName a) -> [Type] -> Box
4952constraintAsBox pn tys = hsep 1 left (text (runProperName (disqualify pn)) : map typeAtomAsBox tys)
@@ -97,7 +100,7 @@ insertPlaceholders :: Type -> Type
97100insertPlaceholders = everywhereOnTypesTopDown convertForAlls . everywhereOnTypes convert
98101 where
99102 convert (TypeApp (TypeApp f arg) ret) | f == tyFunction = PrettyPrintFunction arg ret
100− convert (TypeApp o r) | o == tyObject = PrettyPrintObject r
103+ convert (TypeApp o r) | o == tyRecord = PrettyPrintObject r
101104 convert other = other
102105 convertForAlls (ForAll ident ty _) = go [ident] ty
103106 where
@@ -147,14 +150,20 @@ forall_ = mkPattern match
147150 match _ = Nothing
148151
149152typeAtomAsBox :: Type -> Box
150−typeAtomAsBox = fromMaybe (internalError "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
153+typeAtomAsBox
154+ = fromMaybe (internalError "Incomplete pattern")
155+ . PA.pattern matchTypeAtom ()
156+ . insertPlaceholders
151157
152158-- | Generate a pretty-printed string representing a Type, as it should appear inside parentheses
153159prettyPrintTypeAtom :: Type -> String
154160prettyPrintTypeAtom = render . typeAtomAsBox
155161
156162typeAsBox :: Type -> Box
157−typeAsBox = fromMaybe (internalError "Incomplete pattern") . pattern matchType () . insertPlaceholders
163+typeAsBox
164+ = fromMaybe (internalError "Incomplete pattern")
165+ . PA.pattern matchType ()
166+ . insertPlaceholders
158167
159168-- | Generate a pretty-printed string representing a Type
160169prettyPrintType :: Type -> String
src/Language/PureScript/Pretty/Values.hs+13−12
@@ -1,19 +1,22 @@
11-- |
22-- Pretty printer for values
33--
4−module Language.PureScript.Pretty.Values (
5− prettyPrintValue,
6− prettyPrintBinder,
7− prettyPrintBinderAtom
8−) where
4+module Language.PureScript.Pretty.Values
5+ ( prettyPrintValue
6+ , prettyPrintBinder
7+ , prettyPrintBinderAtom
8+ ) where
9+
10+import Prelude.Compat
911
1012import Control.Arrow (second)
1113
12−import Language.PureScript.Crash
1314import Language.PureScript.AST
15+import Language.PureScript.Crash
1416import Language.PureScript.Names
1517import Language.PureScript.Pretty.Common
1618import Language.PureScript.Pretty.Types (typeAsBox, typeAtomAsBox)
19+import Language.PureScript.Types (Constraint(..))
1720
1821import Text.PrettyPrint.Boxes
1922
@@ -57,7 +60,7 @@ prettyPrintValue d (Let ds val) =
5760 (text "in " <> prettyPrintValue (d - 1) val)
5861prettyPrintValue d (Do els) =
5962 text "do " <> vcat left (map (prettyPrintDoNotationElement (d - 1)) els)
60−prettyPrintValue _ (TypeClassDictionary (name, tys) _) = foldl1 beforeWithSpace $ text ("#dict " ++ runProperName (disqualify name)) : map typeAtomAsBox tys
63+prettyPrintValue _ (TypeClassDictionary (Constraint name tys _) _) = foldl1 beforeWithSpace $ text ("#dict " ++ runProperName (disqualify name)) : map typeAtomAsBox tys
6164prettyPrintValue _ (SuperClassDictionary name _) = text $ "#dict " ++ runProperName (disqualify name)
6265prettyPrintValue _ (TypeClassDictionaryAccessor className ident) =
6366 text "#dict-accessor " <> text (runProperName (disqualify className)) <> text "." <> text (showIdent ident) <> text ">"
@@ -68,7 +71,7 @@ prettyPrintValue _ (Hole name) = text "?" <> text name
6871prettyPrintValue d expr@AnonymousArgument{} = prettyPrintValueAtom d expr
6972prettyPrintValue d expr@Constructor{} = prettyPrintValueAtom d expr
7073prettyPrintValue d expr@Var{} = prettyPrintValueAtom d expr
71−prettyPrintValue d expr@OperatorSection{} = prettyPrintValueAtom d expr
74+prettyPrintValue d expr@Op{} = prettyPrintValueAtom d expr
7275prettyPrintValue d expr@BinaryNoParens{} = prettyPrintValueAtom d expr
7376prettyPrintValue d expr@Parens{} = prettyPrintValueAtom d expr
7477prettyPrintValue d expr@UnaryMinus{} = prettyPrintValueAtom d expr
@@ -80,12 +83,10 @@ prettyPrintValueAtom d (Literal l) = prettyPrintLiteralValue d l
8083prettyPrintValueAtom _ AnonymousArgument = text "_"
8184prettyPrintValueAtom _ (Constructor name) = text $ runProperName (disqualify name)
8285prettyPrintValueAtom _ (Var ident) = text $ showIdent (disqualify ident)
83−prettyPrintValueAtom d (OperatorSection op (Right val)) = ((text "(" <> prettyPrintValue (d - 1) op) `beforeWithSpace` prettyPrintValue (d - 1) val) `before` text ")"
84−prettyPrintValueAtom d (OperatorSection op (Left val)) = ((text "(" <> prettyPrintValue (d - 1) val) `beforeWithSpace` prettyPrintValue (d - 1) op) `before` text ")"
8586prettyPrintValueAtom d (BinaryNoParens op lhs rhs) =
8687 prettyPrintValue (d - 1) lhs `beforeWithSpace` printOp op `beforeWithSpace` prettyPrintValue (d - 1) rhs
8788 where
88− printOp (Var (Qualified _ (Op opName))) = text opName
89+ printOp (Op (Qualified _ name)) = text (runOpName name)
8990 printOp expr = text "`" <> prettyPrintValue (d - 1) expr <> text "`"
9091prettyPrintValueAtom d (TypedValue _ val _) = prettyPrintValueAtom d val
9192prettyPrintValueAtom d (PositionedValue _ _ val) = prettyPrintValueAtom d val
@@ -154,7 +155,7 @@ prettyPrintBinderAtom b@ConstructorBinder{} = parens (prettyPrintBinder b)
154155prettyPrintBinderAtom (NamedBinder ident binder) = showIdent ident ++ "@" ++ prettyPrintBinder binder
155156prettyPrintBinderAtom (PositionedBinder _ _ binder) = prettyPrintBinderAtom binder
156157prettyPrintBinderAtom (TypedBinder _ binder) = prettyPrintBinderAtom binder
157−prettyPrintBinderAtom (OpBinder op) = showIdent (disqualify op)
158+prettyPrintBinderAtom (OpBinder op) = runOpName (disqualify op)
158159prettyPrintBinderAtom (BinaryNoParensBinder op b1 b2) =
159160 prettyPrintBinderAtom b1 ++ " " ++ prettyPrintBinderAtom op ++ " " ++ prettyPrintBinderAtom b2
160161prettyPrintBinderAtom (ParensInBinder b) = parens (prettyPrintBinder b)
src/Language/PureScript/Publish.hs+26−25
@@ -1,7 +1,5 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE TupleSections #-}
41{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+{-# LANGUAGE OverloadedStrings #-}
53
64module Language.PureScript.Publish
75 ( preparePackage
@@ -23,47 +21,46 @@ module Language.PureScript.Publish
2321 , getResolvedDependencies
2422 ) where
2523
26−import Prelude ()
2724import Prelude.Compat hiding (userError)
2825
29−import Data.Maybe
26+import Control.Arrow ((***))
27+import Control.Category ((>>>))
28+import Control.Exception (catch, try)
29+import Control.Monad.Error.Class (MonadError(..))
30+import Control.Monad.Trans.Except
31+import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
32+import Control.Monad.Writer.Strict
33+
34+import Data.Aeson.BetterErrors
3035import Data.Char (isSpace)
36+import Data.Foldable (traverse_)
37+import Data.Function (on)
3138import Data.List (stripPrefix, isSuffixOf, (\\), nubBy)
32−import Data.List.Split (splitOn)
3339import Data.List.NonEmpty (NonEmpty(..))
40+import Data.List.Split (splitOn)
41+import Data.Maybe
3442import Data.Version
35−import Data.Function (on)
36−import Data.Foldable (traverse_)
37−import Safe (headMay)
38−import Data.Aeson.BetterErrors
43+import qualified Data.SPDX as SPDX
3944import qualified Data.Text as T
4045import qualified Data.Text.Lazy as TL
4146import qualified Data.Text.Lazy.Encoding as TL
42−import qualified Data.SPDX as SPDX
4347
44−import Control.Category ((>>>))
45−import Control.Arrow ((***))
46−import Control.Exception (catch, try)
47−import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
48−import Control.Monad.Trans.Except
49−import Control.Monad.Error.Class (MonadError(..))
50−import Control.Monad.Writer.Strict
48+import Safe (headMay)
5149
5250import System.Directory (doesFileExist, findExecutable)
53−import System.Process (readProcess)
5451import System.Exit (exitFailure)
5552import System.FilePath (pathSeparator)
53+import System.Process (readProcess)
5654import qualified System.FilePath.Glob as Glob
5755import qualified System.Info
5856
59−import Web.Bower.PackageMeta (PackageMeta(..), BowerError(..), PackageName,
60− runPackageName, parsePackageName, Repository(..))
57+import Web.Bower.PackageMeta (PackageMeta(..), BowerError(..), PackageName, runPackageName, parsePackageName, Repository(..))
6158import qualified Web.Bower.PackageMeta as Bower
6259
60+import Language.PureScript.Publish.ErrorsWarnings
61+import Language.PureScript.Publish.Utils
6362import qualified Language.PureScript as P (version)
6463import qualified Language.PureScript.Docs as D
65−import Language.PureScript.Publish.Utils
66−import Language.PureScript.Publish.ErrorsWarnings
6764
6865data PublishOptions = PublishOptions
6966 { -- | How to obtain the version tag and version that the data being
@@ -216,8 +213,12 @@ getBowerRepositoryInfo = either (userError . BadRepositoryField) return . tryExt
216213
217214checkLicense :: PackageMeta -> PrepareM ()
218215checkLicense pkgMeta =
219− unless (any isValidSPDX (bowerLicense pkgMeta))
220− (userError NoLicenseSpecified)
216+ case bowerLicense pkgMeta of
217+ [] ->
218+ userError NoLicenseSpecified
219+ ls ->
220+ unless (any isValidSPDX ls)
221+ (userError InvalidLicense)
221222
222223-- |
223224-- Check if a string is a valid SPDX license expression.
src/Language/PureScript/Publish/BoxesHelpers.hs+3
@@ -4,7 +4,10 @@ module Language.PureScript.Publish.BoxesHelpers
44 , module Language.PureScript.Publish.BoxesHelpers
55 ) where
66
7+import Prelude.Compat
8+
79import System.IO (hPutStr, stderr)
10+
811import qualified Text.PrettyPrint.Boxes as Boxes
912
1013width :: Int
src/Language/PureScript/Publish/ErrorsWarnings.hs+31−27
@@ -1,5 +1,4 @@
11{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE RecordWildCards #-}
32
43module Language.PureScript.Publish.ErrorsWarnings
54 ( PackageError(..)
@@ -16,26 +15,24 @@ module Language.PureScript.Publish.ErrorsWarnings
1615 , renderWarnings
1716 ) where
1817
19−import Prelude ()
2018import Prelude.Compat
2119
20+import Control.Exception (IOException)
21+
2222import Data.Aeson.BetterErrors
23−import Data.Version
24−import Data.Maybe
25−import Data.Monoid
2623import Data.List (intersperse, intercalate)
2724import Data.List.NonEmpty (NonEmpty(..))
25+import Data.Maybe
26+import Data.Monoid
27+import Data.Version
2828import qualified Data.List.NonEmpty as NonEmpty
29−
3029import qualified Data.Text as T
3130
32−import Control.Exception (IOException)
33−import Web.Bower.PackageMeta (BowerError, PackageName, runPackageName, showBowerError)
34−import qualified Web.Bower.PackageMeta as Bower
35−
31+import Language.PureScript.Publish.BoxesHelpers
3632import qualified Language.PureScript as P
3733
38−import Language.PureScript.Publish.BoxesHelpers
34+import Web.Bower.PackageMeta (BowerError, PackageName, runPackageName, showBowerError)
35+import qualified Web.Bower.PackageMeta as Bower
3936
4037-- | An error which meant that it was not possible to retrieve metadata for a
4138-- package.
@@ -55,13 +52,13 @@ data PackageWarning
5552-- | An error that should be fixed by the user.
5653data UserError
5754 = BowerJSONNotFound
58− | LicenseNotFound
5955 | BowerExecutableNotFound [String] -- list of executable names tried
6056 | CouldntDecodeBowerJSON (ParseError BowerError)
6157 | TagMustBeCheckedOut
6258 | AmbiguousVersions [Version] -- Invariant: should contain at least two elements
6359 | BadRepositoryField RepositoryFieldError
6460 | NoLicenseSpecified
61+ | InvalidLicense
6562 | MissingDependencies (NonEmpty PackageName)
6663 | CompileError P.MultipleErrors
6764 | DirtyWorkingTree
@@ -129,12 +126,6 @@ displayUserError e = case e of
129126 "The bower.json file was not found. Please create one, or run " ++
130127 "`pulp init`."
131128 )
132− LicenseNotFound ->
133− para (concat
134− ["No LICENSE file was found. Please create one. ",
135− "Distributing code without a license means that nobody ",
136− "will be able to (legally) use it."
137− ])
138129 BowerExecutableNotFound names ->
139130 para (concat
140131 [ "The Bower executable was not found (tried: ", format names, "). Please"
@@ -189,14 +180,7 @@ displayUserError e = case e of
189180 , "following would be acceptable:"
190181 ])
191182 , spacer
192− ] ++
193− map (indented . para)
194− [ "* \"MIT\""
195− , "* \"BSD-2-Clause\""
196− , "* \"GPL-2.0+\""
197− , "* \"(GPL-3.0 OR MIT)\""
198− ]
199− ++
183+ ] ++ spdxExamples ++
200184 [ spacer
201185 , para (concat
202186 [ "Note that distributing code without a license means that nobody "
@@ -209,6 +193,16 @@ displayUserError e = case e of
209193 , "necessary."
210194 ])
211195 ]
196+ InvalidLicense ->
197+ vcat $
198+ [ para (concat
199+ [ "The license specified in bower.json is not a valid SPDX license "
200+ , "expression. Please use the SPDX license expression format. For "
201+ , "example, any of the following would be acceptable:"
202+ ])
203+ , spacer
204+ ] ++
205+ spdxExamples
212206 MissingDependencies pkgs ->
213207 let singular = NonEmpty.length pkgs == 1
214208 pl a b = if singular then b else a
@@ -231,7 +225,7 @@ displayUserError e = case e of
231225 CompileError err ->
232226 vcat
233227 [ para "Compile error:"
234− , indented (vcat (P.prettyPrintMultipleErrorsBox False err))
228+ , indented (vcat (P.prettyPrintMultipleErrorsBox P.defaultPPEOptions err))
235229 ]
236230 DirtyWorkingTree ->
237231 para (
@@ -239,6 +233,16 @@ displayUserError e = case e of
239233 "your changes first."
240234 )
241235
236+spdxExamples :: [Box]
237+spdxExamples =
238+ map (indented . para)
239+ [ "* \"MIT\""
240+ , "* \"Apache-2.0\""
241+ , "* \"BSD-2-Clause\""
242+ , "* \"GPL-2.0+\""
243+ , "* \"(GPL-3.0 OR MIT)\""
244+ ]
245+
242246displayRepositoryError :: RepositoryFieldError -> Box
243247displayRepositoryError err = case err of
244248 RepositoryFieldMissing ->
src/Language/PureScript/Publish/Utils.hs+41−38
@@ -1,38 +1,41 @@
1−
2−module Language.PureScript.Publish.Utils where
3−
4−import Data.List
5−import Data.Either (partitionEithers)
6−import System.Directory
7−import System.Exit (exitFailure)
8−import System.IO (hPutStrLn, stderr)
9−import System.FilePath (pathSeparator)
10−import qualified System.FilePath.Glob as Glob
11−
12−-- | Glob relative to the current directory, and produce relative pathnames.
13−globRelative :: Glob.Pattern -> IO [FilePath]
14−globRelative pat = do
15− currentDir <- getCurrentDirectory
16− filesAbsolute <- Glob.globDir1 pat currentDir
17− let prefix = currentDir ++ [pathSeparator]
18− let (fails, paths) = partitionEithers . map (stripPrefix' prefix) $ filesAbsolute
19− if null fails
20− then return paths
21− else do
22− let p = hPutStrLn stderr
23− p "Internal error in Language.PureScript.Publish.Utils.globRelative"
24− p "Unmatched files:"
25− mapM_ p fails
26− exitFailure
27−
28− where
29− stripPrefix' prefix dir =
30− maybe (Left dir) Right $ stripPrefix prefix dir
31−
32−-- | Glob pattern for PureScript source files.
33−purescriptSourceFiles :: Glob.Pattern
34−purescriptSourceFiles = Glob.compile "src/**/*.purs"
35−
36−-- | Glob pattern for PureScript dependency files.
37−purescriptDepsFiles :: Glob.Pattern
38−purescriptDepsFiles = Glob.compile "bower_components/*/src/**/*.purs"
1+
2+module Language.PureScript.Publish.Utils where
3+
4+import Prelude.Compat
5+
6+import Data.Either (partitionEithers)
7+import Data.List
8+
9+import System.Directory
10+import System.Exit (exitFailure)
11+import System.FilePath (pathSeparator)
12+import System.IO (hPutStrLn, stderr)
13+import qualified System.FilePath.Glob as Glob
14+
15+-- | Glob relative to the current directory, and produce relative pathnames.
16+globRelative :: Glob.Pattern -> IO [FilePath]
17+globRelative pat = do
18+ currentDir <- getCurrentDirectory
19+ filesAbsolute <- Glob.globDir1 pat currentDir
20+ let prefix = currentDir ++ [pathSeparator]
21+ let (fails, paths) = partitionEithers . map (stripPrefix' prefix) $ filesAbsolute
22+ if null fails
23+ then return paths
24+ else do
25+ let p = hPutStrLn stderr
26+ p "Internal error in Language.PureScript.Publish.Utils.globRelative"
27+ p "Unmatched files:"
28+ mapM_ p fails
29+ exitFailure
30+
31+ where
32+ stripPrefix' prefix dir =
33+ maybe (Left dir) Right $ stripPrefix prefix dir
34+
35+-- | Glob pattern for PureScript source files.
36+purescriptSourceFiles :: Glob.Pattern
37+purescriptSourceFiles = Glob.compile "src/**/*.purs"
38+
39+-- | Glob pattern for PureScript dependency files.
40+purescriptDepsFiles :: Glob.Pattern
41+purescriptDepsFiles = Glob.compile "bower_components/*/src/**/*.purs"
src/Language/PureScript/Renamer.hs−6
@@ -1,26 +1,20 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41-- |
52-- Renaming pass that prevents shadowing of local identifiers.
63--
74module Language.PureScript.Renamer (renameInModules) where
85
9−import Prelude ()
106import Prelude.Compat
117
128import Control.Monad.State
139
1410import Data.List (find)
1511import Data.Maybe (fromJust, fromMaybe)
16−
1712import qualified Data.Map as M
1813import qualified Data.Set as S
1914
2015import Language.PureScript.CoreFn
2116import Language.PureScript.Names
2217import Language.PureScript.Traversals
23−
2418import qualified Language.PureScript.Constants as C
2519
2620-- |
src/Language/PureScript/Sugar.hs+16−27
@@ -1,35 +1,20 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Sugar
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-- Desugaring passes
133--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE FlexibleContexts #-}
17−
184module Language.PureScript.Sugar (desugar, module S) where
195
20−import Prelude ()
21−import Prelude.Compat
22−
23−import Control.Monad
246import Control.Category ((>>>))
7+import Control.Monad
258import Control.Monad.Error.Class (MonadError())
26−import Control.Monad.Writer.Class (MonadWriter())
279import Control.Monad.Supply.Class
10+import Control.Monad.Writer.Class (MonadWriter())
11+
12+import Data.List (map)
13+import Data.Traversable (traverse)
2814
2915import Language.PureScript.AST
3016import Language.PureScript.Errors
3117import Language.PureScript.Externs
32−
3318import Language.PureScript.Sugar.BindingGroups as S
3419import Language.PureScript.Sugar.CaseDeclarations as S
3520import Language.PureScript.Sugar.DoNotation as S
@@ -49,7 +34,7 @@ import Language.PureScript.Sugar.TypeDeclarations as S
4934--
5035-- * Desugar operator sections
5136--
52−-- * Desugar do-notation using the @Prelude.Monad@ type class
37+-- * Desugar do-notation
5338--
5439-- * Desugar top-level case declarations into explicit case expressions
5540--
@@ -63,16 +48,20 @@ import Language.PureScript.Sugar.TypeDeclarations as S
6348--
6449-- * Group mutually recursive value and data declarations into binding groups.
6550--
66−desugar :: (MonadSupply m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [ExternsFile] -> [Module] -> m [Module]
51+desugar
52+ :: (MonadSupply m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
53+ => [ExternsFile]
54+ -> [Module]
55+ -> m [Module]
6756desugar externs =
68− map removeSignedLiterals
57+ map desugarSignedLiterals
6958 >>> traverse desugarObjectConstructors
70− >=> traverse desugarOperatorSections
7159 >=> traverse desugarDoModule
72− >=> desugarCasesModule
73− >=> desugarTypeDeclarationsModule
60+ >=> traverse desugarCasesModule
61+ >=> traverse desugarTypeDeclarationsModule
7462 >=> desugarImports externs
7563 >=> rebracket externs
64+ >=> traverse checkFixityExports
7665 >=> traverse deriveInstances
7766 >=> desugarTypeClasses externs
78− >=> createBindingGroupsModule
67+ >=> traverse createBindingGroupsModule
src/Language/PureScript/Sugar/BindingGroups.hs+19−25
@@ -1,7 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE LambdaCase #-}
4−
51-- |
62-- This module implements the desugaring pass which creates binding groups from sets of
73-- mutually-recursive value declarations and mutually-recursive type declarations.
@@ -13,7 +9,6 @@ module Language.PureScript.Sugar.BindingGroups
139 , collapseBindingGroupsModule
1410 ) where
1511
16−import Prelude ()
1712import Prelude.Compat
1813
1914import Control.Monad ((<=<))
@@ -36,11 +31,10 @@ import Language.PureScript.Types
3631--
3732createBindingGroupsModule
3833 :: (MonadError MultipleErrors m)
39− => [Module]
40− -> m [Module]
41−createBindingGroupsModule =
42− mapM $ \(Module ss coms name ds exps) ->
43− Module ss coms name <$> createBindingGroups name ds <*> pure exps
34+ => Module
35+ -> m Module
36+createBindingGroupsModule (Module ss coms name ds exps) =
37+ Module ss coms name <$> createBindingGroups name ds <*> pure exps
4438
4539-- |
4640-- Collapse all binding groups in a module to individual declarations
@@ -72,11 +66,11 @@ createBindingGroups moduleName = mapM f <=< handleDecls
7266 handleDecls ds = do
7367 let values = filter isValueDecl ds
7468 dataDecls = filter isDataDecl ds
75− allProperNames = map getTypeName dataDecls
76− dataVerts = map (\d -> (d, getTypeName d, usedTypeNames moduleName d `intersect` allProperNames)) dataDecls
69+ allProperNames = map declTypeName dataDecls
70+ dataVerts = map (\d -> (d, declTypeName d, usedTypeNames moduleName d `intersect` allProperNames)) dataDecls
7771 dataBindingGroupDecls <- parU (stronglyConnComp dataVerts) toDataBindingGroup
78− let allIdents = map getIdent values
79− valueVerts = map (\d -> (d, getIdent d, usedIdents moduleName d `intersect` allIdents)) values
72+ let allIdents = map declIdent values
73+ valueVerts = map (\d -> (d, declIdent d, usedIdents moduleName d `intersect` allIdents)) values
8074 bindingGroupDecls <- parU (stronglyConnComp valueVerts) (toBindingGroup moduleName)
8175 return $ filter isImportDecl ds ++
8276 filter isExternDataDecl ds ++
@@ -147,23 +141,23 @@ usedTypeNames moduleName =
147141 usedNames :: Type -> [ProperName 'TypeName]
148142 usedNames (ConstrainedType constraints _) =
149143 flip mapMaybe constraints $ \case
150− (Qualified (Just moduleName') name, _)
144+ (Constraint (Qualified (Just moduleName') name) _ _)
151145 | moduleName == moduleName' -> Just (coerceProperName name)
152146 _ -> Nothing
153147 usedNames (TypeConstructor (Qualified (Just moduleName') name))
154148 | moduleName == moduleName' = [name]
155149 usedNames _ = []
156150
157−getIdent :: Declaration -> Ident
158−getIdent (ValueDeclaration ident _ _ _) = ident
159−getIdent (PositionedDeclaration _ _ d) = getIdent d
160−getIdent _ = internalError "Expected ValueDeclaration"
151+declIdent :: Declaration -> Ident
152+declIdent (ValueDeclaration ident _ _ _) = ident
153+declIdent (PositionedDeclaration _ _ d) = declIdent d
154+declIdent _ = internalError "Expected ValueDeclaration"
161155
162−getTypeName :: Declaration -> ProperName 'TypeName
163−getTypeName (DataDeclaration _ pn _ _) = pn
164−getTypeName (TypeSynonymDeclaration pn _ _) = pn
165−getTypeName (PositionedDeclaration _ _ d) = getTypeName d
166−getTypeName _ = internalError "Expected DataDeclaration"
156+declTypeName :: Declaration -> ProperName 'TypeName
157+declTypeName (DataDeclaration _ pn _ _) = pn
158+declTypeName (TypeSynonymDeclaration pn _ _) = pn
159+declTypeName (PositionedDeclaration _ _ d) = declTypeName d
160+declTypeName _ = internalError "Expected DataDeclaration"
167161
168162-- |
169163-- Convert a group of mutually-recursive dependencies into a BindingGroupDeclaration (or simple ValueDeclaration).
@@ -192,7 +186,7 @@ toBindingGroup moduleName (CyclicSCC ds') =
192186 idents = map (\(_, i, _) -> i) valueVerts
193187
194188 valueVerts :: [(Declaration, Ident, [Ident])]
195− valueVerts = map (\d -> (d, getIdent d, usedImmediateIdents moduleName d `intersect` idents)) ds'
189+ valueVerts = map (\d -> (d, declIdent d, usedImmediateIdents moduleName d `intersect` idents)) ds'
196190
197191 toBinding :: SCC Declaration -> m (Ident, NameKind, Expr)
198192 toBinding (AcyclicSCC d) = return $ fromValueDecl d
src/Language/PureScript/Sugar/CaseDeclarations.hs+17−20
@@ -1,45 +1,42 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41-- |
52-- This module implements the desugaring pass which replaces top-level binders with
63-- case expressions.
74--
8−module Language.PureScript.Sugar.CaseDeclarations (
9− desugarCases,
10− desugarCasesModule
11−) where
5+module Language.PureScript.Sugar.CaseDeclarations
6+ ( desugarCases
7+ , desugarCasesModule
8+ ) where
129
13−import Prelude ()
1410import Prelude.Compat
1511
16−import Language.PureScript.Crash
17−import Data.Maybe (catMaybes, mapMaybe)
12+import Data.Either (isLeft)
1813import Data.List (nub, groupBy, foldl1')
14+import Data.Maybe (catMaybes, mapMaybe)
1915
20−import Control.Monad ((<=<), forM, replicateM, join, unless)
16+import Control.Monad ((<=<), replicateM, join, unless)
2117import Control.Monad.Error.Class (MonadError(..))
2218import Control.Monad.Supply.Class
2319
24−import Language.PureScript.Names
2520import Language.PureScript.AST
21+import Language.PureScript.Crash
2622import Language.PureScript.Environment
2723import Language.PureScript.Errors
24+import Language.PureScript.Names
2825import Language.PureScript.Traversals
2926import Language.PureScript.TypeChecker.Monad (guardWith)
3027
31−-- Data.Either.isLeft (base 4.7)
32−isLeft :: Either a b -> Bool
33−isLeft (Left _) = True
34−isLeft (Right _) = False
35−
3628-- |
3729-- Replace all top-level binders in a module with case expressions.
3830--
39−desugarCasesModule :: (MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]
40−desugarCasesModule ms = forM ms $ \(Module ss coms name ds exps) ->
31+desugarCasesModule
32+ :: (MonadSupply m, MonadError MultipleErrors m)
33+ => Module
34+ -> m Module
35+desugarCasesModule (Module ss coms name ds exps) =
4136 rethrow (addHint (ErrorInModule name)) $
42− Module ss coms name <$> (desugarCases <=< desugarAbs <=< validateCases $ ds) <*> pure exps
37+ Module ss coms name
38+ <$> (desugarCases <=< desugarAbs <=< validateCases $ ds)
39+ <*> pure exps
4340
4441-- |
4542-- Validates that case head and binder lengths match.
src/Language/PureScript/Sugar/DoNotation.hs+14−16
@@ -1,34 +1,32 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41-- |
52-- This module implements the desugaring pass which replaces do-notation statements with
6−-- appropriate calls to bind from the Prelude.Monad type class.
3+-- appropriate calls to bind.
74--
8−module Language.PureScript.Sugar.DoNotation (
9− desugarDoModule
10−) where
5+module Language.PureScript.Sugar.DoNotation (desugarDoModule) where
116
12−import Prelude ()
137import Prelude.Compat
148
15−import Language.PureScript.Crash
16−import Language.PureScript.Names
9+import Control.Monad.Error.Class (MonadError(..))
10+import Control.Monad.Supply.Class
11+
12+
1713import Language.PureScript.AST
14+import Language.PureScript.Crash
1815import Language.PureScript.Errors
19−
16+import Language.PureScript.Names
2017import qualified Language.PureScript.Constants as C
2118
22−import Control.Monad.Error.Class (MonadError(..))
23−import Control.Monad.Supply.Class
24−
2519-- |
26−-- Replace all @DoNotationBind@ and @DoNotationValue@ constructors with applications of the Prelude.bind function,
27−-- and all @DoNotationLet@ constructors with let expressions.
20+-- Replace all @DoNotationBind@ and @DoNotationValue@ constructors with
21+-- applications of the bind function in scope, and all @DoNotationLet@
22+-- constructors with let expressions.
2823--
2924desugarDoModule :: forall m. (MonadSupply m, MonadError MultipleErrors m) => Module -> m Module
3025desugarDoModule (Module ss coms mn ds exts) = Module ss coms mn <$> parU ds desugarDo <*> pure exts
3126
27+-- |
28+-- Desugar a single do statement
29+--
3230desugarDo :: forall m. (MonadSupply m, MonadError MultipleErrors m) => Declaration -> m Declaration
3331desugarDo (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> rethrowWithPosition pos (desugarDo d)
3432desugarDo d =
src/Language/PureScript/Sugar/Names.hs+102−182
@@ -1,8 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−{-# LANGUAGE TupleSections #-}
5−
61module Language.PureScript.Sugar.Names
72 ( desugarImports
83 , desugarImportsWithEnv
@@ -13,38 +8,41 @@ module Language.PureScript.Sugar.Names
138 , Exports(..)
149 ) where
1510
16−import Prelude ()
1711import Prelude.Compat
1812
19−import Data.List (find, nub)
20−import Data.Maybe (fromMaybe, mapMaybe)
21−
22−import Control.Arrow (first)
13+import Control.Arrow (first, second)
2314import Control.Monad
2415import Control.Monad.Error.Class (MonadError(..))
25−import Control.Monad.Writer (MonadWriter(..), censor)
2616import Control.Monad.State.Lazy
17+import Control.Monad.Writer (MonadWriter(..), censor)
2718
19+import Data.List (nub)
20+import Data.Maybe (fromMaybe, mapMaybe)
2821import qualified Data.Map as M
2922import qualified Data.Set as S
3023
31−import Language.PureScript.Crash
3224import Language.PureScript.AST
33−import Language.PureScript.Names
34−import Language.PureScript.Types
25+import Language.PureScript.Crash
3526import Language.PureScript.Errors
36−import Language.PureScript.Traversals
3727import Language.PureScript.Externs
28+import Language.PureScript.Linter.Imports
29+import Language.PureScript.Names
3830import Language.PureScript.Sugar.Names.Env
39−import Language.PureScript.Sugar.Names.Imports
4031import Language.PureScript.Sugar.Names.Exports
41−import Language.PureScript.Linter.Imports
32+import Language.PureScript.Sugar.Names.Imports
33+import Language.PureScript.Traversals
34+import Language.PureScript.Types
4235
4336-- |
4437-- Replaces all local names with qualified names within a list of modules. The
4538-- modules should be topologically sorted beforehand.
4639--
47−desugarImports :: forall m. (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [ExternsFile] -> [Module] -> m [Module]
40+desugarImports
41+ :: forall m
42+ . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
43+ => [ExternsFile]
44+ -> [Module]
45+ -> m [Module]
4846desugarImports externs modules =
4947 fmap snd (desugarImportsWithEnv externs modules)
5048
@@ -56,9 +54,8 @@ desugarImportsWithEnv
5654 -> m (Env, [Module])
5755desugarImportsWithEnv externs modules = do
5856 env <- silence $ foldM externsEnv primEnv externs
59− modules' <- traverse updateExportRefs modules
60− (modules'', env') <- first reverse <$> foldM updateEnv ([], env) modules'
61− (env',) <$> traverse (renameInModule' env') modules''
57+ (modules', env') <- first reverse <$> foldM updateEnv ([], env) modules
58+ (env',) <$> traverse (renameInModule' env') modules'
6259 where
6360 silence :: m a -> m a
6461 silence = censor (const mempty)
@@ -68,41 +65,35 @@ desugarImportsWithEnv externs modules = do
6865 externsEnv env ExternsFile{..} = do
6966 let members = Exports{..}
7067 ss = internalModuleSourceSpan "<Externs>"
71− env' = M.insert efModuleName (ss, nullImports, members) env
68+ env' = M.insert efModuleName (ss, primImports, members) env
7269 fromEFImport (ExternsImport mn mt qmn) = (mn, [(Nothing, Just mt, qmn)])
73− imps <- foldM (resolveModuleImport env') nullImports (map fromEFImport efImports)
74− exps <- resolveExports env' efModuleName imps members efExports
70+ imps <- foldM (resolveModuleImport env') primImports (map fromEFImport efImports)
71+ exps <- resolveExports env' ss efModuleName imps members efExports
7572 return $ M.insert efModuleName (ss, imps, exps) env
7673 where
7774
78− exportedTypes :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
79− exportedTypes = mapMaybe toExportedType efExports
75+ exportedTypes :: M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
76+ exportedTypes = M.fromList $ mapMaybe toExportedType efExports
8077 where
81− toExportedType (TypeRef tyCon dctors) = Just ((tyCon, fromMaybe (mapMaybe forTyCon efDeclarations) dctors), efModuleName)
78+ toExportedType (TypeRef tyCon dctors) = Just (tyCon, (fromMaybe (mapMaybe forTyCon efDeclarations) dctors, efModuleName))
8279 where
8380 forTyCon :: ExternsDeclaration -> Maybe (ProperName 'ConstructorName)
8481 forTyCon (EDDataConstructor pn _ tNm _ _) | tNm == tyCon = Just pn
8582 forTyCon _ = Nothing
8683 toExportedType (PositionedDeclarationRef _ _ r) = toExportedType r
8784 toExportedType _ = Nothing
88− exportedTypeOps :: [(Ident, ModuleName)]
89− exportedTypeOps = mapMaybe toExportedTypeOp efExports
90− where
91− toExportedTypeOp (TypeOpRef ident) = Just (ident, efModuleName)
92− toExportedTypeOp (PositionedDeclarationRef _ _ r) = toExportedTypeOp r
93− toExportedTypeOp _ = Nothing
94− exportedTypeClasses :: [(ProperName 'ClassName, ModuleName)]
95− exportedTypeClasses = mapMaybe toExportedTypeClass efExports
96− where
97− toExportedTypeClass (TypeClassRef className) = Just (className, efModuleName)
98− toExportedTypeClass (PositionedDeclarationRef _ _ r) = toExportedTypeClass r
99− toExportedTypeClass _ = Nothing
100− exportedValues :: [(Ident, ModuleName)]
101− exportedValues = mapMaybe toExportedValue efExports
102− where
103− toExportedValue (ValueRef ident) = Just (ident, efModuleName)
104− toExportedValue (PositionedDeclarationRef _ _ r) = toExportedValue r
105− toExportedValue _ = Nothing
85+
86+ exportedTypeOps :: M.Map (OpName 'TypeOpName) ModuleName
87+ exportedTypeOps = M.fromList $ (, efModuleName) <$> mapMaybe getTypeOpRef efExports
88+
89+ exportedTypeClasses :: M.Map (ProperName 'ClassName) ModuleName
90+ exportedTypeClasses = M.fromList $ (, efModuleName) <$> mapMaybe getTypeClassRef efExports
91+
92+ exportedValues :: M.Map Ident ModuleName
93+ exportedValues = M.fromList $ (, efModuleName) <$> mapMaybe getValueRef efExports
94+
95+ exportedValueOps :: M.Map (OpName 'ValueOpName) ModuleName
96+ exportedValueOps = M.fromList $ (, efModuleName) <$> mapMaybe getValueOpRef efExports
10697
10798 updateEnv :: ([Module], Env) -> Module -> m ([Module], Env)
10899 updateEnv (ms, env) m@(Module ss _ mn _ refs) =
@@ -110,17 +101,17 @@ desugarImportsWithEnv externs modules = do
110101 Just m' -> throwError . errorMessage $ RedefinedModule mn [envModuleSourceSpan m', ss]
111102 Nothing -> do
112103 members <- findExportable m
113− let env' = M.insert mn (ss, nullImports, members) env
104+ let env' = M.insert mn (ss, primImports, members) env
114105 (m', imps) <- resolveImports env' m
115− exps <- maybe (return members) (resolveExports env' mn imps members) refs
106+ exps <- maybe (return members) (resolveExports env' ss mn imps members) refs
116107 return (m' : ms, M.insert mn (ss, imps, exps) env)
117108
118109 renameInModule' :: Env -> Module -> m Module
119110 renameInModule' env m@(Module _ _ mn _ _) =
120111 warnAndRethrow (addHint (ErrorInModule mn)) $ do
121112 let (_, imps, exps) = fromMaybe (internalError "Module is missing in renameInModule'") $ M.lookup mn env
122− (m', used) <- flip runStateT M.empty $ renameInModule env imps (elaborateExports exps m)
123− lintImports m env used
113+ (m', used) <- flip runStateT M.empty $ renameInModule imps (elaborateExports exps m)
114+ lintImports m' env used
124115 return m'
125116
126117-- |
@@ -131,16 +122,23 @@ desugarImportsWithEnv externs modules = do
131122elaborateExports :: Exports -> Module -> Module
132123elaborateExports exps (Module ss coms mn decls refs) =
133124 Module ss coms mn decls $
134− Just $ map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) (my exportedTypes) ++
125+ Just $ map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) myTypes ++
135126 map TypeOpRef (my exportedTypeOps) ++
136127 map TypeClassRef (my exportedTypeClasses) ++
137128 map ValueRef (my exportedValues) ++
129+ map ValueOpRef (my exportedValueOps) ++
138130 maybe [] (filter isModuleRef) refs
139131 where
140132 -- Extracts a list of values from the exports and filters out any values that
141133 -- are re-exports from other modules.
142− my :: (Exports -> [(a, ModuleName)]) -> [a]
143− my f = fst `map` filter ((== mn) . snd) (f exps)
134+ my :: (Exports -> M.Map a ModuleName) -> [a]
135+ my = map fst <$> filt (== mn)
136+
137+ myTypes :: [(ProperName 'TypeName, [ProperName 'ConstructorName])]
138+ myTypes = second fst <$> filt ((== mn) . snd) exportedTypes
139+
140+ filt :: (b -> Bool) -> (Exports -> M.Map a b) -> [(a, b)]
141+ filt predicate f = M.toList $ predicate `M.filter` f exps
144142
145143-- |
146144-- Replaces all local names with qualified names within a module and checks that all existing
@@ -149,11 +147,10 @@ elaborateExports exps (Module ss coms mn decls refs) =
149147renameInModule
150148 :: forall m
151149 . (MonadError MultipleErrors m, MonadWriter MultipleErrors m, MonadState UsedImports m)
152− => Env
153− -> Imports
150+ => Imports
154151 -> Module
155152 -> m Module
156−renameInModule env imports (Module ss coms mn decls exps) =
153+renameInModule imports (Module ss coms mn decls exps) =
157154 Module ss coms mn <$> parU decls go <*> pure exps
158155 where
159156
@@ -177,16 +174,12 @@ renameInModule env imports (Module ss coms mn decls exps) =
177174 (,) (pos, bound) <$> (TypeDeclaration name <$> updateTypesEverywhere pos ty)
178175 updateDecl (pos, bound) (ExternDeclaration name ty) =
179176 (,) (pos, name : bound) <$> (ExternDeclaration name <$> updateTypesEverywhere pos ty)
180− updateDecl (pos, bound) (FixityDeclaration fx name alias) =
181− (,) (pos, bound) <$> (FixityDeclaration fx name <$> traverse updateAlias alias)
182− where
183− updateAlias :: Qualified FixityAlias -> m (Qualified FixityAlias)
184− updateAlias (Qualified mn' (AliasValue ident)) =
185− fmap AliasValue <$> updateValueName (Qualified mn' ident) pos
186− updateAlias (Qualified mn' (AliasConstructor ctor)) =
187− fmap AliasConstructor <$> updateDataConstructorName (Qualified mn' ctor) pos
188− updateAlias (Qualified mn' (AliasType ty)) =
189− fmap AliasType <$> updateTypeName (Qualified mn' ty) pos
177+ updateDecl (pos, bound) (TypeFixityDeclaration fixity alias op) =
178+ (,) (pos, bound) <$> (TypeFixityDeclaration fixity <$> updateTypeName alias pos <*> pure op)
179+ updateDecl (pos, bound) (ValueFixityDeclaration fixity (Qualified mn' (Left alias)) op) =
180+ (,) (pos, bound) <$> (ValueFixityDeclaration fixity . fmap Left <$> updateValueName (Qualified mn' alias) pos <*> pure op)
181+ updateDecl (pos, bound) (ValueFixityDeclaration fixity (Qualified mn' (Right alias)) op) =
182+ (,) (pos, bound) <$> (ValueFixityDeclaration fixity . fmap Right <$> updateDataConstructorName (Qualified mn' alias) pos <*> pure op)
190183 updateDecl s d = return (s, d)
191184
192185 updateValue
@@ -207,6 +200,8 @@ renameInModule env imports (Module ss coms mn decls exps) =
207200 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
208201 updateValue (pos, bound) (Var name'@(Qualified (Just _) _)) =
209202 (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
203+ updateValue (pos, bound) (Op op) =
204+ (,) (pos, bound) <$> (Op <$> updateValueOpName op pos)
210205 updateValue s@(pos, _) (Constructor name) =
211206 (,) s <$> (Constructor <$> updateDataConstructorName name pos)
212207 updateValue s@(pos, _) (TypedValue check val ty) =
@@ -221,12 +216,11 @@ renameInModule env imports (Module ss coms mn decls exps) =
221216 return ((Just pos, bound), v)
222217 updateBinder s@(pos, _) (ConstructorBinder name b) =
223218 (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
224− updateBinder s@(pos, _) (OpBinder name) =
225− (,) s <$> (OpBinder <$> updateValueName name pos)
226− updateBinder s (TypedBinder t b) = do
227− (s'@ (span', _), b') <- updateBinder s b
228− t' <- updateTypesEverywhere span' t
229− return (s', TypedBinder t' b')
219+ updateBinder s@(pos, _) (OpBinder op) =
220+ (,) s <$> (OpBinder <$> updateValueOpName op pos)
221+ updateBinder s@(pos, _) (TypedBinder t b) = do
222+ t' <- updateTypesEverywhere pos t
223+ return (s, TypedBinder t' b)
230224 updateBinder s v =
231225 return (s, v)
232226
@@ -248,103 +242,63 @@ renameInModule env imports (Module ss coms mn decls exps) =
248242 updateType :: Type -> m Type
249243 updateType (TypeOp name) = TypeOp <$> updateTypeOpName name pos
250244 updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
251− updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
245+ updateType (ConstrainedType cs t) = ConstrainedType <$> traverse updateInConstraint cs <*> pure t
252246 updateType t = return t
247+ updateInConstraint :: Constraint -> m Constraint
248+ updateInConstraint (Constraint name ts info) =
249+ Constraint <$> updateClassName name pos <*> pure ts <*> pure info
253250
254251 updateConstraints :: Maybe SourceSpan -> [Constraint] -> m [Constraint]
255− updateConstraints pos = traverse (\(name, ts) -> (,) <$> updateClassName name pos <*> traverse (updateTypesEverywhere pos) ts)
252+ updateConstraints pos = traverse $ \(Constraint name ts info) ->
253+ Constraint
254+ <$> updateClassName name pos
255+ <*> traverse (updateTypesEverywhere pos) ts
256+ <*> pure info
256257
257258 updateTypeName
258259 :: Qualified (ProperName 'TypeName)
259260 -> Maybe SourceSpan
260261 -> m (Qualified (ProperName 'TypeName))
261− updateTypeName =
262− update UnknownType
263− (importedTypes imports)
264− (resolveType . exportedTypes)
265− TyName
266− (("type " ++) . runProperName)
262+ updateTypeName = update (importedTypes imports) TyName
267263
268264 updateTypeOpName
269− :: Qualified Ident
265+ :: Qualified (OpName 'TypeOpName)
270266 -> Maybe SourceSpan
271− -> m (Qualified Ident)
272− updateTypeOpName =
273− update
274− UnknownTypeOp
275− (importedTypeOps imports)
276− (resolve . exportedTypeOps)
277− TyOpName
278− (("type operator" ++) . runIdent)
267+ -> m (Qualified (OpName 'TypeOpName))
268+ updateTypeOpName = update (importedTypeOps imports) TyOpName
279269
280270 updateDataConstructorName
281271 :: Qualified (ProperName 'ConstructorName)
282272 -> Maybe SourceSpan
283273 -> m (Qualified (ProperName 'ConstructorName))
284− updateDataConstructorName =
285− update
286− (flip UnknownDataConstructor Nothing)
287− (importedDataConstructors imports)
288− (resolveDctor . exportedTypes)
289− DctorName
290− (("data constructor " ++) . runProperName)
274+ updateDataConstructorName = update (importedDataConstructors imports) DctorName
291275
292276 updateClassName
293277 :: Qualified (ProperName 'ClassName)
294278 -> Maybe SourceSpan
295279 -> m (Qualified (ProperName 'ClassName))
296− updateClassName =
297− update
298− UnknownTypeClass
299− (importedTypeClasses imports)
300− (resolve . exportedTypeClasses)
301− TyClassName
302− (("class " ++) . runProperName)
280+ updateClassName = update (importedTypeClasses imports) TyClassName
303281
304282 updateValueName :: Qualified Ident -> Maybe SourceSpan -> m (Qualified Ident)
305− updateValueName =
306− update
307− UnknownValue
308− (importedValues imports)
309− (resolve . exportedValues)
310− IdentName
311− (("value " ++) . runIdent)
312−
313− -- Used when performing an update to qualify values and classes with their
314− -- module of original definition.
315− resolve :: (Eq a) => [(a, ModuleName)] -> a -> Maybe (Qualified a)
316− resolve as name = mkQualified name <$> name `lookup` as
317−
318− -- Used when performing an update to qualify types with their module of
319− -- original definition.
320− resolveType
321− :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
322− -> ProperName 'TypeName
323− -> Maybe (Qualified (ProperName 'TypeName))
324− resolveType tys name = mkQualified name . snd <$> find ((== name) . fst . fst) tys
325−
326− -- Used when performing an update to qualify data constructors with their
327− -- module of original definition.
328− resolveDctor
329− :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
330− -> ProperName 'ConstructorName
331− -> Maybe (Qualified (ProperName 'ConstructorName))
332− resolveDctor tys name = mkQualified name . snd <$> find (elem name . snd . fst) tys
283+ updateValueName = update (importedValues imports) IdentName
284+
285+ updateValueOpName
286+ :: Qualified (OpName 'ValueOpName)
287+ -> Maybe SourceSpan
288+ -> m (Qualified (OpName 'ValueOpName))
289+ updateValueOpName = update (importedValueOps imports) ValOpName
333290
334291 -- Update names so unqualified references become qualified, and locally
335292 -- qualified references are replaced with their canoncial qualified names
336293 -- (e.g. M.Map -> Data.Map.Map).
337294 update
338295 :: (Ord a, Show a)
339− => (Qualified a -> SimpleErrorMessage)
340− -> M.Map (Qualified a) [ImportRecord a]
341− -> (Exports -> a -> Maybe (Qualified a))
342− -> (Qualified a -> Name)
343− -> (a -> String)
296+ => M.Map (Qualified a) [ImportRecord a]
297+ -> (a -> Name)
344298 -> Qualified a
345299 -> Maybe SourceSpan
346300 -> m (Qualified a)
347− update unknown imps getE toName render qname@(Qualified mn' name) pos = positioned $
301+ update imps toName qname@(Qualified mn' name) pos = positioned $
348302 case (M.lookup qname imps, mn') of
349303
350304 -- We found the name in our imports, so we return the name for it,
@@ -353,61 +307,27 @@ renameInModule env imports (Module ss coms mn decls exps) =
353307 -- re-exports. If there are multiple options for the name to resolve to
354308 -- in scope, we throw an error.
355309 (Just options, _) -> do
356− (mnNew, mnOrig) <- checkImportConflicts mn render options
357− modify $ \result -> M.insert mnNew (maybe [toName qname] (toName qname :) (mnNew `M.lookup` result)) result
310+ (mnNew, mnOrig) <- checkImportConflicts mn toName options
311+ modify $ \result ->
312+ M.insert
313+ mnNew
314+ (maybe [fmap toName qname] (fmap toName qname :) (mnNew `M.lookup` result))
315+ result
358316 return $ Qualified (Just mnOrig) name
359317
360318 -- If the name wasn't found in our imports but was qualified then we need
361319 -- to check whether it's a failed import from a "pseudo" module (created
362320 -- by qualified importing). If that's not the case, then we just need to
363321 -- check it refers to a symbol in another module.
364− (Nothing, Just mn'') -> do
365− case M.lookup mn'' env of
366− Nothing
367− | mn'' `S.member` importedVirtualModules imports -> throwUnknown
368− | otherwise -> throwError . errorMessage $ UnknownModule mn''
369− Just env' -> maybe throwUnknown return (getE (envModuleExports env') name)
322+ (Nothing, Just mn'') ->
323+ if mn'' `S.member` importedQualModules imports || mn'' `S.member` importedModules imports
324+ then throwUnknown
325+ else throwError . errorMessage . UnknownName . Qualified Nothing $ ModName mn''
370326
371327 -- If neither of the above cases are true then it's an undefined or
372328 -- unimported symbol.
373329 _ -> throwUnknown
374330
375331 where
376− positioned err = case pos of
377− Nothing -> err
378− Just pos' -> rethrowWithPosition pos' err
379− throwUnknown = throwError . errorMessage $ unknown qname
380−
381−-- |
382−-- Replaces `ProperRef` export values with a `TypeRef` or `TypeClassRef`
383−-- depending on what is availble within the module. Warns when a `ProperRef`
384−-- desugars into a `TypeClassRef`.
385−--
386−updateExportRefs
387− :: forall m
388− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
389− => Module
390− -> m Module
391−updateExportRefs (Module ss coms mn decls exps) =
392− Module ss coms mn decls <$> traverse (traverse updateRef) exps
393− where
394−
395− updateRef :: DeclarationRef -> m DeclarationRef
396− updateRef (ProperRef name)
397− | ProperName name `elem` classNames = do
398− tell . errorMessage . DeprecatedClassExport $ ProperName name
399− return . TypeClassRef $ ProperName name
400− -- Fall through case here - assume it's a type if it's not a class.
401− -- If it's a reference to something that doesn't actually exist it will
402− -- be picked up elsewhere
403− | otherwise = return $ TypeRef (ProperName name) (Just [])
404− updateRef (PositionedDeclarationRef pos com ref) =
405− warnWithPosition pos $ PositionedDeclarationRef pos com <$> updateRef ref
406− updateRef other = return other
407−
408− classNames :: [ProperName 'ClassName]
409− classNames = mapMaybe go decls
410− where
411− go (PositionedDeclaration _ _ d) = go d
412− go (TypeClassDeclaration name _ _ _) = Just name
413− go _ = Nothing
332+ positioned err = maybe err (`rethrowWithPosition` err) pos
333+ throwUnknown = throwError . errorMessage . UnknownName . fmap toName $ qname
src/Language/PureScript/Sugar/Names/Common.hsnew file+68
@@ -0,0 +1,68 @@
1+module Language.PureScript.Sugar.Names.Common (warnDuplicateRefs) where
2+
3+import Prelude.Compat
4+
5+import Control.Monad.Writer (MonadWriter(..))
6+
7+import Data.Foldable (for_)
8+import Data.Function (on)
9+import Data.List (nub, nubBy, (\\))
10+import Data.Maybe (mapMaybe)
11+
12+import Language.PureScript.AST
13+import Language.PureScript.Errors
14+import Language.PureScript.Names
15+
16+-- |
17+-- Warns about duplicate values in a list of declaration refs.
18+--
19+warnDuplicateRefs
20+ :: MonadWriter MultipleErrors m
21+ => SourceSpan
22+ -> (Name -> SimpleErrorMessage)
23+ -> [DeclarationRef]
24+ -> m ()
25+warnDuplicateRefs pos toError refs = do
26+ let withoutCtors = deleteCtors `map` refs
27+ dupeRefs = mapMaybe (refToName pos) $ withoutCtors \\ nubBy ((==) `on` withoutPosInfo) withoutCtors
28+ dupeCtors = concat $ mapMaybe (extractCtors pos) refs
29+
30+ for_ (dupeRefs ++ dupeCtors) $ \(pos', name) ->
31+ warnWithPosition pos' . tell . errorMessage $ toError name
32+
33+ where
34+
35+ -- Returns a DeclarationRef unwrapped from any PositionedDeclarationRef
36+ -- constructor(s) it may be wrapped within. Used so position info is ignored
37+ -- when making the comparison for duplicates.
38+ withoutPosInfo :: DeclarationRef -> DeclarationRef
39+ withoutPosInfo (PositionedDeclarationRef _ _ ref) = withoutPosInfo ref
40+ withoutPosInfo other = other
41+
42+ -- Deletes the constructor information from TypeRefs so that only the
43+ -- referenced type is used in the duplicate check - constructors are handled
44+ -- separately
45+ deleteCtors :: DeclarationRef -> DeclarationRef
46+ deleteCtors (PositionedDeclarationRef ss com ref) =
47+ PositionedDeclarationRef ss com (deleteCtors ref)
48+ deleteCtors (TypeRef pn _) = TypeRef pn Nothing
49+ deleteCtors other = other
50+
51+ -- Extracts the names of duplicate constructor references from TypeRefs.
52+ extractCtors :: SourceSpan -> DeclarationRef -> Maybe [(SourceSpan, Name)]
53+ extractCtors _ (PositionedDeclarationRef pos' _ ref) = extractCtors pos' ref
54+ extractCtors pos' (TypeRef _ (Just dctors)) =
55+ let dupes = dctors \\ nub dctors
56+ in if null dupes then Nothing else Just $ ((pos',) . DctorName) <$> dupes
57+ extractCtors _ _ = Nothing
58+
59+ -- Converts a DeclarationRef into a name for an error message.
60+ refToName :: SourceSpan -> DeclarationRef -> Maybe (SourceSpan, Name)
61+ refToName pos' (TypeRef name _) = Just (pos', TyName name)
62+ refToName pos' (TypeOpRef op) = Just (pos', TyOpName op)
63+ refToName pos' (ValueRef name) = Just (pos', IdentName name)
64+ refToName pos' (ValueOpRef op) = Just (pos', ValOpName op)
65+ refToName pos' (TypeClassRef name) = Just (pos', TyClassName name)
66+ refToName pos' (ModuleRef name) = Just (pos', ModName name)
67+ refToName _ (PositionedDeclarationRef pos' _ ref) = refToName pos' ref
68+ refToName _ _ = Nothing
src/Language/PureScript/Sugar/Names/Env.hs+204−83
@@ -1,11 +1,8 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41module Language.PureScript.Sugar.Names.Env
52 ( ImportRecord(..)
63 , ImportProvenance(..)
74 , Imports(..)
8− , nullImports
5+ , primImports
96 , Exports(..)
107 , nullExports
118 , Env
@@ -13,29 +10,33 @@ module Language.PureScript.Sugar.Names.Env
1310 , envModuleSourceSpan
1411 , envModuleImports
1512 , envModuleExports
13+ , ExportMode(..)
1614 , exportType
1715 , exportTypeOp
1816 , exportTypeClass
1917 , exportValue
18+ , exportValueOp
2019 , getExports
2120 , checkImportConflicts
2221 ) where
2322
24−import Data.Function (on)
25−import Data.List (groupBy, sortBy, nub, delete)
26−import Data.Maybe (fromJust)
27−import qualified Data.Map as M
28−import qualified Data.Set as S
23+import Prelude.Compat
2924
3025import Control.Monad
3126import Control.Monad.Error.Class (MonadError(..))
3227import Control.Monad.Writer.Class (MonadWriter(..))
3328
29+import Data.Function (on)
30+import Data.Foldable (find)
31+import Data.List (groupBy, sortBy, delete)
32+import Data.Maybe (fromJust, mapMaybe)
33+import qualified Data.Map as M
34+import qualified Data.Set as S
35+
3436import Language.PureScript.AST
35−import Language.PureScript.Crash
36−import Language.PureScript.Names
3737import Language.PureScript.Environment
3838import Language.PureScript.Errors
39+import Language.PureScript.Names
3940
4041-- |
4142-- The details for an import: the name of the thing that is being imported
@@ -59,8 +60,11 @@ data ImportProvenance
5960 = FromImplicit
6061 | FromExplicit
6162 | Local
63+ | Prim
6264 deriving (Eq, Ord, Show, Read)
6365
66+type ImportMap a = M.Map (Qualified a) [ImportRecord a]
67+
6468-- |
6569-- The imported declarations for a module, including the module's own members.
6670--
@@ -69,39 +73,60 @@ data Imports = Imports
6973 -- |
7074 -- Local names for types within a module mapped to to their qualified names
7175 --
72− importedTypes :: M.Map (Qualified (ProperName 'TypeName)) [ImportRecord (ProperName 'TypeName)]
76+ importedTypes :: ImportMap (ProperName 'TypeName)
7377 -- |
7478 -- Local names for type operators within a module mapped to to their qualified names
7579 --
76− , importedTypeOps :: M.Map (Qualified Ident) [ImportRecord Ident]
80+ , importedTypeOps :: ImportMap (OpName 'TypeOpName)
7781 -- |
7882 -- Local names for data constructors within a module mapped to to their qualified names
7983 --
80− , importedDataConstructors :: M.Map (Qualified (ProperName 'ConstructorName)) [ImportRecord (ProperName 'ConstructorName)]
84+ , importedDataConstructors :: ImportMap (ProperName 'ConstructorName)
8185 -- |
8286 -- Local names for classes within a module mapped to to their qualified names
8387 --
84− , importedTypeClasses :: M.Map (Qualified (ProperName 'ClassName)) [ImportRecord (ProperName 'ClassName)]
88+ , importedTypeClasses :: ImportMap (ProperName 'ClassName)
8589 -- |
8690 -- Local names for values within a module mapped to to their qualified names
8791 --
88− , importedValues :: M.Map (Qualified Ident) [ImportRecord Ident]
92+ , importedValues :: ImportMap Ident
93+ -- |
94+ -- Local names for value operators within a module mapped to to their qualified names
95+ --
96+ , importedValueOps :: ImportMap (OpName 'ValueOpName)
8997 -- |
90− -- The modules that have been imported into the current scope.
98+ -- The name of modules that have been imported into the current scope that
99+ -- can be re-exported. If a module is imported with `as` qualification, the
100+ -- `as` name appears here, otherwise the original name.
91101 --
92102 , importedModules :: S.Set ModuleName
93103 -- |
94− -- The names of "virtual" modules that come into existence when "import as"
95− -- is used.
104+ -- The "as" names of modules that have been imported qualified.
96105 --
97− , importedVirtualModules :: S.Set ModuleName
106+ , importedQualModules :: S.Set ModuleName
98107 } deriving (Show, Read)
99108
109+nullImports :: Imports
110+nullImports = Imports M.empty M.empty M.empty M.empty M.empty M.empty S.empty S.empty
111+
100112-- |
101−-- An empty 'Imports' value.
113+-- An 'Imports' value with imports for the `Prim` module.
102114--
103−nullImports :: Imports
104−nullImports = Imports M.empty M.empty M.empty M.empty M.empty S.empty S.empty
115+primImports :: Imports
116+primImports =
117+ nullImports
118+ { importedTypes = M.fromList $ mkEntries `concatMap` M.keys primTypes
119+ , importedTypeClasses = M.fromList $ mkEntries `concatMap` M.keys primClasses
120+ }
121+ where
122+ mkEntries :: Qualified a -> [(Qualified a, [ImportRecord a])]
123+ mkEntries fullName@(Qualified _ name) =
124+ [ (fullName, [ImportRecord fullName primModuleName Prim])
125+ , (Qualified Nothing name, [ImportRecord fullName primModuleName Prim])
126+ ]
127+
128+primModuleName :: ModuleName
129+primModuleName = ModuleName [ProperName "Prim"]
105130
106131-- |
107132-- The exported declarations from a module.
@@ -109,32 +134,34 @@ nullImports = Imports M.empty M.empty M.empty M.empty M.empty S.empty S.empty
109134data Exports = Exports
110135 {
111136 -- |
112− -- The types exported from each module along with the module they originally
113− -- came from.
137+ -- The exported types along with the module they originally came from.
114138 --
115− exportedTypes :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
139+ exportedTypes :: M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
116140 -- |
117− -- The type operators exported from each module along with the module they
118− -- originally came from.
141+ -- The exported type operators along with the module they originally came
142+ -- from.
119143 --
120− , exportedTypeOps :: [(Ident, ModuleName)]
144+ , exportedTypeOps :: M.Map (OpName 'TypeOpName) ModuleName
121145 -- |
122− -- The classes exported from each module along with the module they originally
123− -- came from.
146+ -- The exported classes along with the module they originally came from.
124147 --
125− , exportedTypeClasses :: [(ProperName 'ClassName, ModuleName)]
148+ , exportedTypeClasses :: M.Map (ProperName 'ClassName) ModuleName
126149 -- |
127− -- The values exported from each module along with the module they originally
128− -- came from.
150+ -- The exported values along with the module they originally came from.
129151 --
130− , exportedValues :: [(Ident, ModuleName)]
152+ , exportedValues :: M.Map Ident ModuleName
153+ -- |
154+ -- The exported value operators along with the module they originally came
155+ -- from.
156+ --
157+ , exportedValueOps :: M.Map (OpName 'ValueOpName) ModuleName
131158 } deriving (Show, Read)
132159
133160-- |
134161-- An empty 'Exports' value.
135162--
136163nullExports :: Exports
137−nullExports = Exports [] [] [] []
164+nullExports = Exports M.empty M.empty M.empty M.empty M.empty
138165
139166-- |
140167-- The imports and exports for a collection of modules. The 'SourceSpan' is used
@@ -165,82 +192,182 @@ envModuleExports (_, _, exps) = exps
165192-- The exported types from the @Prim@ module
166193--
167194primExports :: Exports
168−primExports = Exports (mkTypeEntry `map` M.keys primTypes) [] (mkClassEntry `map` M.keys primClasses) []
195+primExports =
196+ nullExports
197+ { exportedTypes = M.fromList $ mkTypeEntry `map` M.keys primTypes
198+ , exportedTypeClasses = M.fromList $ mkClassEntry `map` M.keys primClasses
199+ }
169200 where
170− mkTypeEntry (Qualified mn name) = ((name, []), fromJust mn)
201+ mkTypeEntry (Qualified mn name) = (name, ([], fromJust mn))
171202 mkClassEntry (Qualified mn name) = (name, fromJust mn)
172203
173204-- | Environment which only contains the Prim module.
174205primEnv :: Env
175206primEnv = M.singleton
176− (ModuleName [ProperName "Prim"])
207+ primModuleName
177208 (internalModuleSourceSpan "<Prim>", nullImports, primExports)
178209
210+-- |
211+-- When updating the `Exports` the behaviour is slightly different depending
212+-- on whether we are exporting values defined within the module or elaborating
213+-- re-exported values. This type is used to indicate which behaviour should be
214+-- used.
215+--
216+data ExportMode = Internal | ReExport
217+ deriving (Eq, Show)
218+
179219-- |
180220-- Safely adds a type and its data constructors to some exports, returning an
181221-- error if a conflict occurs.
182222--
183−exportType :: (MonadError MultipleErrors m) => Exports -> ProperName 'TypeName -> [ProperName 'ConstructorName] -> ModuleName -> m Exports
184−exportType exps name dctors mn = do
185− let exTypes' = exportedTypes exps
186− let exTypes = filter ((/= mn) . snd) exTypes'
187− let exDctors = (snd . fst) `concatMap` exTypes
223+exportType
224+ :: MonadError MultipleErrors m
225+ => ExportMode
226+ -> Exports
227+ -> ProperName 'TypeName
228+ -> [ProperName 'ConstructorName]
229+ -> ModuleName
230+ -> m Exports
231+exportType exportMode exps name dctors mn = do
232+ let exTypes = exportedTypes exps
188233 let exClasses = exportedTypeClasses exps
189− when (any ((== name) . fst . fst) exTypes) $ throwConflictError ConflictingTypeDecls name
190− when (any ((== coerceProperName name) . fst) exClasses) $ throwConflictError TypeConflictsWithClass name
191− forM_ dctors $ \dctor -> do
192− when (dctor `elem` exDctors) $ throwConflictError ConflictingCtorDecls dctor
193− when (any ((== coerceProperName dctor) . fst) exClasses) $ throwConflictError CtorConflictsWithClass dctor
194− return $ exps { exportedTypes = nub $ ((name, dctors), mn) : exTypes' }
234+ case exportMode of
235+ Internal -> do
236+ when (name `M.member` exTypes) $
237+ throwDeclConflict (TyName name) (TyName name)
238+ when (coerceProperName name `M.member` exClasses) $
239+ throwDeclConflict (TyName name) (TyClassName (coerceProperName name))
240+ forM_ dctors $ \dctor -> do
241+ when ((elem dctor . fst) `any` exTypes) $
242+ throwDeclConflict (DctorName dctor) (DctorName dctor)
243+ when (coerceProperName dctor `M.member` exClasses) $
244+ throwDeclConflict (DctorName dctor) (TyClassName (coerceProperName dctor))
245+ ReExport -> do
246+ forM_ (name `M.lookup` exTypes) $ \(_, mn') ->
247+ when (mn /= mn') $
248+ throwExportConflict mn mn' (TyName name)
249+ forM_ dctors $ \dctor ->
250+ forM_ ((elem dctor . fst) `find` exTypes) $ \(_, mn') ->
251+ when (mn /= mn') $
252+ throwExportConflict mn mn' (DctorName dctor)
253+ return $ exps { exportedTypes = M.alter updateOrInsert name exTypes }
254+ where
255+ updateOrInsert Nothing = Just (dctors, mn)
256+ updateOrInsert (Just (dctors', _)) = Just (dctors ++ dctors', mn)
195257
196258-- |
197259-- Safely adds a type operator to some exports, returning an error if a
198260-- conflict occurs.
199261--
200−exportTypeOp :: (MonadError MultipleErrors m) => Exports -> Ident -> ModuleName -> m Exports
201−exportTypeOp exps name mn = do
202− typeOps <- addExport DuplicateTypeOpExport name mn (exportedTypeOps exps)
262+exportTypeOp
263+ :: MonadError MultipleErrors m
264+ => Exports
265+ -> OpName 'TypeOpName
266+ -> ModuleName
267+ -> m Exports
268+exportTypeOp exps op mn = do
269+ typeOps <- addExport TyOpName op mn (exportedTypeOps exps)
203270 return $ exps { exportedTypeOps = typeOps }
204271
205272-- |
206273-- Safely adds a class to some exports, returning an error if a conflict occurs.
207274--
208−exportTypeClass :: (MonadError MultipleErrors m) => Exports -> ProperName 'ClassName -> ModuleName -> m Exports
209−exportTypeClass exps name mn = do
275+exportTypeClass
276+ :: MonadError MultipleErrors m
277+ => ExportMode
278+ -> Exports
279+ -> ProperName 'ClassName
280+ -> ModuleName
281+ -> m Exports
282+exportTypeClass exportMode exps name mn = do
210283 let exTypes = exportedTypes exps
211− let exDctors = (snd . fst) `concatMap` exTypes
212− when (any ((== coerceProperName name) . fst . fst) exTypes) $ throwConflictError ClassConflictsWithType name
213− when (coerceProperName name `elem` exDctors) $ throwConflictError ClassConflictsWithCtor name
214− classes <- addExport DuplicateClassExport name mn (exportedTypeClasses exps)
284+ when (exportMode == Internal) $ do
285+ when (coerceProperName name `M.member` exTypes) $
286+ throwDeclConflict (TyClassName name) (TyName (coerceProperName name))
287+ when ((elem (coerceProperName name) . fst) `any` exTypes) $
288+ throwDeclConflict (TyClassName name) (DctorName (coerceProperName name))
289+ classes <- addExport TyClassName name mn (exportedTypeClasses exps)
215290 return $ exps { exportedTypeClasses = classes }
216291
217292-- |
218293-- Safely adds a value to some exports, returning an error if a conflict occurs.
219294--
220−exportValue :: (MonadError MultipleErrors m) => Exports -> Ident -> ModuleName -> m Exports
295+exportValue
296+ :: MonadError MultipleErrors m
297+ => Exports
298+ -> Ident
299+ -> ModuleName
300+ -> m Exports
221301exportValue exps name mn = do
222− values <- addExport DuplicateValueExport name mn (exportedValues exps)
302+ values <- addExport IdentName name mn (exportedValues exps)
223303 return $ exps { exportedValues = values }
224304
225305-- |
226−-- Adds an entry to a list of exports unless it is already present, in which case an error is
227−-- returned.
306+-- Safely adds a value operator to some exports, returning an error if a
307+-- conflict occurs.
228308--
229−addExport :: (MonadError MultipleErrors m, Eq a) => (a -> SimpleErrorMessage) -> a -> ModuleName -> [(a, ModuleName)] -> m [(a, ModuleName)]
230−addExport what name mn exports =
231− if any (\(name', mn') -> name == name' && mn /= mn') exports
232− then throwConflictError what name
233− else return $ nub $ (name, mn) : exports
309+exportValueOp
310+ :: MonadError MultipleErrors m
311+ => Exports
312+ -> OpName 'ValueOpName
313+ -> ModuleName
314+ -> m Exports
315+exportValueOp exps op mn = do
316+ valueOps <- addExport ValOpName op mn (exportedValueOps exps)
317+ return $ exps { exportedValueOps = valueOps }
318+
319+-- |
320+-- Adds an entry to a list of exports unless it is already present, in which
321+-- case an error is returned.
322+--
323+addExport
324+ :: (MonadError MultipleErrors m, Ord a)
325+ => (a -> Name)
326+ -> a
327+ -> ModuleName
328+ -> M.Map a ModuleName
329+ -> m (M.Map a ModuleName)
330+addExport toName name mn exports =
331+ case M.lookup name exports of
332+ Just mn'
333+ | mn == mn' -> return exports
334+ | otherwise -> throwExportConflict mn mn' (toName name)
335+ Nothing ->
336+ return $ M.insert name mn exports
234337
235338-- |
236339-- Raises an error for when there is more than one definition for something.
237340--
238−throwConflictError :: (MonadError MultipleErrors m) => (a -> SimpleErrorMessage) -> a -> m b
239−throwConflictError conflict = throwError . errorMessage . conflict
341+throwDeclConflict
342+ :: MonadError MultipleErrors m
343+ => Name
344+ -> Name
345+ -> m a
346+throwDeclConflict new existing =
347+ throwError . errorMessage $ DeclConflict new existing
240348
241−-- Gets the exports for a module, or an error message if the module doesn't exist
242−getExports :: (MonadError MultipleErrors m) => Env -> ModuleName -> m Exports
243−getExports env mn = maybe (throwError . errorMessage $ UnknownModule mn) (return . envModuleExports) $ M.lookup mn env
349+-- |
350+-- Raises an error for when there are conflicting names in the exports.
351+--
352+throwExportConflict
353+ :: MonadError MultipleErrors m
354+ => ModuleName
355+ -> ModuleName
356+ -> Name
357+ -> m a
358+throwExportConflict new existing name =
359+ throwError . errorMessage $
360+ ExportConflict (Qualified (Just new) name) (Qualified (Just existing) name)
361+
362+-- |
363+-- Gets the exports for a module, or raise an error if the module doesn't exist.
364+--
365+getExports :: MonadError MultipleErrors m => Env -> ModuleName -> m Exports
366+getExports env mn =
367+ maybe
368+ (throwError . errorMessage . UnknownName . Qualified Nothing $ ModName mn)
369+ (return . envModuleExports)
370+ $ M.lookup mn env
244371
245372-- |
246373-- When reading a value from the imports, check that there are no conflicts in
@@ -250,16 +377,16 @@ checkImportConflicts
250377 :: forall m a
251378 . (Show a, MonadError MultipleErrors m, MonadWriter MultipleErrors m, Ord a)
252379 => ModuleName
253− -> (a -> String)
380+ -> (a -> Name)
254381 -> [ImportRecord a]
255382 -> m (ModuleName, ModuleName)
256−checkImportConflicts currentModule render xs =
383+checkImportConflicts currentModule toName xs =
257384 let
258385 byOrig = sortBy (compare `on` importSourceModule) xs
259386 groups = groupBy ((==) `on` importSourceModule) byOrig
260387 nonImplicit = filter ((/= FromImplicit) . importProvenance) xs
261− name = render' (importName . head $ xs)
262− conflictModules = map (getQual . importName . head) groups
388+ name = toName . disqualify . importName $ head xs
389+ conflictModules = mapMaybe (getQual . importName . head) groups
263390 in
264391 if length groups > 1
265392 then case nonImplicit of
@@ -271,9 +398,3 @@ checkImportConflicts currentModule render xs =
271398 else
272399 let ImportRecord (Qualified (Just mnNew) _) mnOrig _ = head byOrig
273400 in return (mnNew, mnOrig)
274− where
275− getQual :: Qualified a -> ModuleName
276− getQual (Qualified (Just mn) _) = mn
277− getQual _ = internalError "unexpected unqualified name in checkImportConflicts"
278− render' :: Qualified a -> String
279− render' (Qualified _ a) = render a
src/Language/PureScript/Sugar/Names/Exports.hs+156−154
@@ -1,32 +1,26 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE RankNTypes #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−{-# LANGUAGE TupleSections #-}
5−{-# LANGUAGE LambdaCase #-}
6−
71module Language.PureScript.Sugar.Names.Exports
82 ( findExportable
93 , resolveExports
104 ) where
115
12−import Prelude ()
136import Prelude.Compat
147
15−import Data.List (find, intersect)
16−import Data.Maybe (fromMaybe, mapMaybe)
17−import Data.Foldable (traverse_)
18−
198import Control.Monad
209import Control.Monad.Writer.Class (MonadWriter(..))
2110import Control.Monad.Error.Class (MonadError(..))
2211
12+import Data.Function (on)
13+import Data.Foldable (traverse_)
14+import Data.List (intersect, groupBy, sortBy)
15+import Data.Maybe (fromMaybe, mapMaybe)
2316import qualified Data.Map as M
2417
25−import Language.PureScript.Crash
2618import Language.PureScript.AST
27−import Language.PureScript.Names
19+import Language.PureScript.Crash
2820import Language.PureScript.Errors
29−import Language.PureScript.Sugar.Names.Env
21+import Language.PureScript.Names
22+import Language.PureScript.Sugar.Names.Env
23+import Language.PureScript.Sugar.Names.Common (warnDuplicateRefs)
3024
3125-- |
3226-- Finds all exportable members of a module, disregarding any explicit exports.
@@ -37,82 +31,87 @@ findExportable (Module _ _ mn ds _) =
3731 where
3832 updateExports :: Exports -> Declaration -> m Exports
3933 updateExports exps (TypeClassDeclaration tcn _ _ ds') = do
40− exps' <- exportTypeClass exps tcn mn
34+ exps' <- exportTypeClass Internal exps tcn mn
4135 foldM go exps' ds'
4236 where
4337 go exps'' (TypeDeclaration name _) = exportValue exps'' name mn
4438 go exps'' (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ go exps'' d
4539 go _ _ = internalError "Invalid declaration in TypeClassDeclaration"
46− updateExports exps (DataDeclaration _ tn _ dcs) = exportType exps tn (map fst dcs) mn
47− updateExports exps (TypeSynonymDeclaration tn _ _) = exportType exps tn [] mn
48− updateExports exps (ExternDataDeclaration tn _) = exportType exps tn [] mn
49− updateExports exps (ValueDeclaration name _ _ _) = exportValue exps name mn
50− updateExports exps (FixityDeclaration _ name (Just (Qualified _ (AliasType _)))) = exportTypeOp exps (Op name) mn
51− updateExports exps (FixityDeclaration _ name (Just _)) = exportValue exps (Op name) mn
52− updateExports exps (ExternDeclaration name _) = exportValue exps name mn
53− updateExports exps (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ updateExports exps d
40+ updateExports exps (DataDeclaration _ tn _ dcs) =
41+ exportType Internal exps tn (map fst dcs) mn
42+ updateExports exps (TypeSynonymDeclaration tn _ _) =
43+ exportType Internal exps tn [] mn
44+ updateExports exps (ExternDataDeclaration tn _) =
45+ exportType Internal exps tn [] mn
46+ updateExports exps (ValueDeclaration name _ _ _) =
47+ exportValue exps name mn
48+ updateExports exps (ValueFixityDeclaration _ _ op) =
49+ exportValueOp exps op mn
50+ updateExports exps (TypeFixityDeclaration _ _ op) =
51+ exportTypeOp exps op mn
52+ updateExports exps (ExternDeclaration name _) =
53+ exportValue exps name mn
54+ updateExports exps (PositionedDeclaration pos _ d) =
55+ rethrowWithPosition pos $ updateExports exps d
5456 updateExports exps _ = return exps
5557
5658-- |
5759-- Resolves the exports for a module, filtering out members that have not been
5860-- exported and elaborating re-exports of other modules.
5961--
60−resolveExports :: forall m. (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Env -> ModuleName -> Imports -> Exports -> [DeclarationRef] -> m Exports
61−resolveExports env mn imps exps refs =
62− rethrow (addHint (ErrorInModule mn)) $ do
62+resolveExports
63+ :: forall m
64+ . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
65+ => Env
66+ -> SourceSpan
67+ -> ModuleName
68+ -> Imports
69+ -> Exports
70+ -> [DeclarationRef]
71+ -> m Exports
72+resolveExports env ss mn imps exps refs =
73+ warnAndRethrow (addHint (ErrorInModule mn)) $ do
6374 filtered <- filterModule mn exps refs
64− let (dupeRefs, dupeDctors) = findDuplicateRefs refs
65− warnDupeRefs dupeRefs
66− warnDupeDctors dupeDctors
67− foldM elaborateModuleExports filtered refs
68−
75+ exps' <- foldM elaborateModuleExports filtered refs
76+ warnDuplicateRefs ss DuplicateExportRef refs
77+ return exps'
78+
6979 where
7080
71− warnDupeRefs :: [DeclarationRef] -> m ()
72− warnDupeRefs = traverse_ $ \case
73− TypeRef name _ -> warnDupe $ "type " ++ runProperName name
74− TypeOpRef name -> warnDupe $ "type operator " ++ runIdent name
75− ValueRef name -> warnDupe $ "value " ++ runIdent name
76− TypeClassRef name -> warnDupe $ "class " ++ runProperName name
77− ModuleRef name -> warnDupe $ "module " ++ runModuleName name
78− _ -> return ()
79−
80− warnDupeDctors :: [ProperName 'ConstructorName] -> m ()
81− warnDupeDctors = traverse_ (warnDupe . ("data constructor " ++) . runProperName)
82−
83− warnDupe :: String -> m ()
84− warnDupe ref = tell . errorMessage $ DuplicateExportRef ref
85−
8681 -- Takes the current module's imports, the accumulated list of exports, and a
8782 -- `DeclarationRef` for an explicit export. When the ref refers to another
8883 -- module, export anything from the imports that matches for that module.
8984 elaborateModuleExports :: Exports -> DeclarationRef -> m Exports
9085 elaborateModuleExports result (PositionedDeclarationRef pos _ r) =
91− rethrowWithPosition pos $ elaborateModuleExports result r
86+ warnAndRethrowWithPosition pos $ elaborateModuleExports result r
9287 elaborateModuleExports result (ModuleRef name) | name == mn = do
93− let types' = exportedTypes result ++ exportedTypes exps
94− let typeOps' = exportedTypeOps result ++ exportedTypeOps exps
95− let classes' = exportedTypeClasses result ++ exportedTypeClasses exps
96− let values' = exportedValues result ++ exportedValues exps
88+ let types' = exportedTypes result `M.union` exportedTypes exps
89+ let typeOps' = exportedTypeOps result `M.union` exportedTypeOps exps
90+ let classes' = exportedTypeClasses result `M.union` exportedTypeClasses exps
91+ let values' = exportedValues result `M.union` exportedValues exps
92+ let valueOps' = exportedValueOps result `M.union` exportedValueOps exps
9793 return result
9894 { exportedTypes = types'
9995 , exportedTypeOps = typeOps'
10096 , exportedTypeClasses = classes'
10197 , exportedValues = values'
98+ , exportedValueOps = valueOps'
10299 }
103100 elaborateModuleExports result (ModuleRef name) = do
104101 let isPseudo = isPseudoModule name
105− when (not isPseudo && not (isImportedModule name)) $
106− throwError . errorMessage . UnknownExportModule $ name
107− reTypes <- extract isPseudo name (("type " ++) . runProperName) (importedTypes imps)
108− reTypeOps <- extract isPseudo name (("type operator " ++) . runIdent) (importedTypeOps imps)
109− reDctors <- extract isPseudo name (("data constructor " ++) . runProperName) (importedDataConstructors imps)
110− reClasses <- extract isPseudo name (("class " ++) . runProperName) (importedTypeClasses imps)
111− reValues <- extract isPseudo name (("value " ++) . runIdent) (importedValues imps)
112− result' <- foldM (\exps' ((tctor, dctors), mn') -> exportType exps' tctor dctors mn') result (resolveTypeExports reTypes reDctors)
113− result'' <- foldM (uncurry . exportTypeOp) result' (map resolveTypeOp reTypeOps)
114− result''' <- foldM (uncurry . exportTypeClass) result'' (map resolveClass reClasses)
115− foldM (uncurry . exportValue) result''' (map resolveValue reValues)
102+ when (not isPseudo && not (isImportedModule name))
103+ . throwError . errorMessage . UnknownExport $ ModName name
104+ reTypes <- extract isPseudo name TyName (importedTypes imps)
105+ reTypeOps <- extract isPseudo name TyOpName (importedTypeOps imps)
106+ reDctors <- extract isPseudo name DctorName (importedDataConstructors imps)
107+ reClasses <- extract isPseudo name TyClassName (importedTypeClasses imps)
108+ reValues <- extract isPseudo name IdentName (importedValues imps)
109+ reValueOps <- extract isPseudo name ValOpName (importedValueOps imps)
110+ foldM (\exps' ((tctor, dctors), mn') -> exportType ReExport exps' tctor dctors mn') result (resolveTypeExports reTypes reDctors)
111+ >>= flip (foldM (uncurry . exportTypeOp)) (map resolveTypeOp reTypeOps)
112+ >>= flip (foldM (uncurry . exportTypeClass ReExport)) (map resolveClass reClasses)
113+ >>= flip (foldM (uncurry . exportValue)) (map resolveValue reValues)
114+ >>= flip (foldM (uncurry . exportValueOp)) (map resolveValueOp reValueOps)
116115 elaborateModuleExports result _ = return result
117116
118117 -- Extracts a list of values for a module based on a lookup table. If the
@@ -121,14 +120,14 @@ resolveExports env mn imps exps refs =
121120 :: (Show a, Ord a)
122121 => Bool
123122 -> ModuleName
124− -> (a -> String)
123+ -> (a -> Name)
125124 -> M.Map (Qualified a) [ImportRecord a]
126125 -> m [Qualified a]
127− extract useQual name render = fmap (map (importName . head . snd)) . go . M.toList
126+ extract useQual name toName = fmap (map (importName . head . snd)) . go . M.toList
128127 where
129128 go = filterM $ \(name', options) -> do
130129 let isMatch = if useQual then isQualifiedWith name name' else any (checkUnqual name') options
131− when (isMatch && length options > 1) $ void $ checkImportConflicts mn render options
130+ when (isMatch && length options > 1) $ void $ checkImportConflicts mn toName options
132131 return isMatch
133132 checkUnqual name' ir = isUnqualified name' && isQualifiedWith name (importName ir)
134133
@@ -147,6 +146,7 @@ resolveExports env mn imps exps refs =
147146 || any (isQualifiedWith mn') (f (importedDataConstructors imps))
148147 || any (isQualifiedWith mn') (f (importedTypeClasses imps))
149148 || any (isQualifiedWith mn') (f (importedValues imps))
149+ || any (isQualifiedWith mn') (f (importedValueOps imps))
150150
151151 -- Check whether a module name refers to a module that has been imported
152152 -- without qualification into an import scope.
@@ -164,35 +164,54 @@ resolveExports env mn imps exps refs =
164164 go
165165 :: Qualified (ProperName 'TypeName)
166166 -> ((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)
167− go (Qualified (Just mn'') name) = fromMaybe (internalError "Missing value in resolveTypeExports") $ do
168− exps' <- envModuleExports <$> mn'' `M.lookup` env
169− ((_, dctors'), mnOrig) <- find (\((name', _), _) -> name == name') (exportedTypes exps')
170− let relevantDctors = mapMaybe (\(Qualified mn''' dctor) -> if mn''' == Just mn'' then Just dctor else Nothing) dctors
171− return ((name, relevantDctors `intersect` dctors'), mnOrig)
167+ go (Qualified (Just mn'') name) =
168+ fromMaybe (internalError "Missing value in resolveTypeExports") $ do
169+ exps' <- envModuleExports <$> mn'' `M.lookup` env
170+ (dctors', mnOrig) <- name `M.lookup` exportedTypes exps'
171+ let relevantDctors = mapMaybe (disqualifyFor (Just mn'')) dctors
172+ return ((name, relevantDctors `intersect` dctors'), mnOrig)
172173 go (Qualified Nothing _) = internalError "Unqualified value in resolveTypeExports"
173174
174175 -- Looks up an imported type operator and re-qualifies it with the original
175176 -- module it came from.
176− resolveTypeOp :: Qualified Ident -> (Ident, ModuleName)
177− resolveTypeOp ident = splitQual $ fromMaybe (internalError "Missing value in resolveValue") $
178− resolve exportedTypeOps ident
177+ resolveTypeOp :: Qualified (OpName 'TypeOpName) -> (OpName 'TypeOpName, ModuleName)
178+ resolveTypeOp op
179+ = splitQual
180+ . fromMaybe (internalError "Missing value in resolveValue")
181+ $ resolve exportedTypeOps op
179182
180183 -- Looks up an imported class and re-qualifies it with the original module it
181184 -- came from.
182185 resolveClass :: Qualified (ProperName 'ClassName) -> (ProperName 'ClassName, ModuleName)
183− resolveClass className = splitQual $ fromMaybe (internalError "Missing value in resolveClass") $
184− resolve exportedTypeClasses className
186+ resolveClass className
187+ = splitQual
188+ . fromMaybe (internalError "Missing value in resolveClass")
189+ $ resolve exportedTypeClasses className
185190
186191 -- Looks up an imported value and re-qualifies it with the original module it
187192 -- came from.
188193 resolveValue :: Qualified Ident -> (Ident, ModuleName)
189− resolveValue ident = splitQual $ fromMaybe (internalError "Missing value in resolveValue") $
190− resolve exportedValues ident
194+ resolveValue ident
195+ = splitQual
196+ . fromMaybe (internalError "Missing value in resolveValue")
197+ $ resolve exportedValues ident
198+
199+ -- Looks up an imported operator and re-qualifies it with the original
200+ -- module it came from.
201+ resolveValueOp :: Qualified (OpName 'ValueOpName) -> (OpName 'ValueOpName, ModuleName)
202+ resolveValueOp op
203+ = splitQual
204+ . fromMaybe (internalError "Missing value in resolveValueOp")
205+ $ resolve exportedValueOps op
191206
192− resolve :: (Eq a) => (Exports -> [(a, ModuleName)]) -> Qualified a -> Maybe (Qualified a)
207+ resolve
208+ :: Ord a
209+ => (Exports -> M.Map a ModuleName)
210+ -> Qualified a
211+ -> Maybe (Qualified a)
193212 resolve f (Qualified (Just mn'') a) = do
194213 exps' <- envModuleExports <$> mn'' `M.lookup` env
195− mn''' <- snd <$> find ((== a) . fst) (f exps')
214+ mn''' <- a `M.lookup` f exps'
196215 return $ Qualified (Just mn''') a
197216 resolve _ _ = internalError "Unqualified value in resolve"
198217
@@ -208,97 +227,80 @@ resolveExports env mn imps exps refs =
208227--
209228filterModule
210229 :: forall m
211− . (MonadError MultipleErrors m)
230+ . MonadError MultipleErrors m
212231 => ModuleName
213232 -> Exports
214233 -> [DeclarationRef]
215234 -> m Exports
216235filterModule mn exps refs = do
217− types <- foldM (filterTypes $ exportedTypes exps) [] refs
218− typeOps <- foldM (filterTypeOps $ exportedTypeOps exps) [] refs
219− values <- foldM (filterValues $ exportedValues exps) [] refs
220− classes <- foldM (filterClasses $ exportedTypeClasses exps) [] refs
221− return $ exps
236+ types <- foldM filterTypes M.empty (combineTypeRefs refs)
237+ typeOps <- foldM (filterExport TyOpName getTypeOpRef exportedTypeOps) M.empty refs
238+ classes <- foldM (filterExport TyClassName getTypeClassRef exportedTypeClasses) M.empty refs
239+ values <- foldM (filterExport IdentName getValueRef exportedValues) M.empty refs
240+ valueOps <- foldM (filterExport ValOpName getValueOpRef exportedValueOps) M.empty refs
241+ return Exports
222242 { exportedTypes = types
223243 , exportedTypeOps = typeOps
224244 , exportedTypeClasses = classes
225245 , exportedValues = values
246+ , exportedValueOps = valueOps
226247 }
227248
228249 where
229250
230− -- Takes a list of all the exportable types with their data constructors, the
231− -- accumulated list of filtered exports, and a `DeclarationRef` for an
232− -- explicit export. When the ref refers to a type in the list of exportable
233− -- values, the type and specified data constructors are included in the
234− -- result.
251+ -- Takes the list of exported refs, filters out any non-TypeRefs, then
252+ -- combines any duplicate type exports to ensure that all constructors
253+ -- listed for the type are covered. Without this, only the data constructor
254+ -- listing for the last ref would be used.
255+ combineTypeRefs :: [DeclarationRef] -> [DeclarationRef]
256+ combineTypeRefs
257+ = fmap (uncurry TypeRef)
258+ . map (foldr1 $ \(tc, dcs1) (_, dcs2) -> (tc, liftM2 (++) dcs1 dcs2))
259+ . groupBy ((==) `on` fst)
260+ . sortBy (compare `on` fst)
261+ . mapMaybe getTypeRef
262+
235263 filterTypes
236− :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
237− -> [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
264+ :: M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
238265 -> DeclarationRef
239− -> m [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
240− filterTypes exps' result (PositionedDeclarationRef pos _ r) =
241− rethrowWithPosition pos $ filterTypes exps' result r
242− filterTypes exps' result (TypeRef name expDcons) =
243− case (\((name', _), mn') -> name == name' && mn == mn') `find` exps' of
244− Nothing -> throwError . errorMessage . UnknownExportType $ name
245− Just ((_, dcons), _) -> do
266+ -> m (M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName))
267+ filterTypes result (PositionedDeclarationRef pos _ r) =
268+ rethrowWithPosition pos $ filterTypes result r
269+ filterTypes result (TypeRef name expDcons) =
270+ case name `M.lookup` exportedTypes exps of
271+ Nothing -> throwError . errorMessage . UnknownExport $ TyName name
272+ Just (dcons, _) -> do
246273 let expDcons' = fromMaybe dcons expDcons
247274 traverse_ (checkDcon name dcons) expDcons'
248− return $ ((name, expDcons'), mn) : result
249− filterTypes _ result _ = return result
250−
251− -- Ensures a data constructor is exportable for a given type. Takes a type
252− -- name, a list of exportable data constructors for the type, and the name of
253− -- the data constructor to check.
254− checkDcon
255− :: ProperName 'TypeName
256− -> [ProperName 'ConstructorName]
257− -> ProperName 'ConstructorName
258− -> m ()
259− checkDcon tcon exps' name =
260− unless (name `elem` exps') $
261− throwError . errorMessage $ UnknownExportDataConstructor tcon name
262−
263− -- Takes a list of all the exportable type operators, the accumulated list of
264− -- filtered exports, and a `DeclarationRef` for an explicit export. When the
265− -- ref refers to a value in the list of exportable values, the value is
266− -- included in the result.
267− filterTypeOps :: [(Ident, ModuleName)] -> [(Ident, ModuleName)] -> DeclarationRef -> m [(Ident, ModuleName)]
268− filterTypeOps exps' result (PositionedDeclarationRef pos _ r) =
269− rethrowWithPosition pos $ filterTypeOps exps' result r
270− filterTypeOps exps' result (TypeOpRef name) =
271− if (name, mn) `elem` exps'
272− then return $ (name, mn) : result
273− else throwError . errorMessage . UnknownExportTypeOp $ name
274− filterTypeOps _ result _ = return result
275+ return $ M.insert name (expDcons', mn) result
276+ where
277+ -- Ensures a data constructor is exportable for a given type. Takes a type
278+ -- name, a list of exportable data constructors for the type, and the name of
279+ -- the data constructor to check.
280+ checkDcon
281+ :: ProperName 'TypeName
282+ -> [ProperName 'ConstructorName]
283+ -> ProperName 'ConstructorName
284+ -> m ()
285+ checkDcon tcon dcons dcon =
286+ unless (dcon `elem` dcons) $
287+ throwError . errorMessage $ UnknownExportDataConstructor tcon dcon
288+ filterTypes result _ = return result
275289
276− -- Takes a list of all the exportable classes, the accumulated list of
277− -- filtered exports, and a `DeclarationRef` for an explicit export. When the
278− -- ref refers to a class in the list of exportable classes, the class is
279− -- included in the result.
280− filterClasses
281− :: [(ProperName 'ClassName, ModuleName)]
282− -> [(ProperName 'ClassName, ModuleName)]
290+ filterExport
291+ :: Ord a
292+ => (a -> Name)
293+ -> (DeclarationRef -> Maybe a)
294+ -> (Exports -> M.Map a ModuleName)
295+ -> M.Map a ModuleName
283296 -> DeclarationRef
284− -> m [(ProperName 'ClassName, ModuleName)]
285− filterClasses exps' result (PositionedDeclarationRef pos _ r) =
286− rethrowWithPosition pos $ filterClasses exps' result r
287− filterClasses exps' result (TypeClassRef name) =
288− if (name, mn) `elem` exps'
289− then return $ (name, mn) : result
290− else throwError . errorMessage . UnknownExportTypeClass $ name
291− filterClasses _ result _ = return result
292−
293− -- Takes a list of all the exportable values, the accumulated list of filtered
294− -- exports, and a `DeclarationRef` for an explicit export. When the ref refers
295− -- to a value in the list of exportable values, the value is included in the
296− -- result.
297− filterValues :: [(Ident, ModuleName)] -> [(Ident, ModuleName)] -> DeclarationRef -> m [(Ident, ModuleName)]
298− filterValues exps' result (PositionedDeclarationRef pos _ r) =
299− rethrowWithPosition pos $ filterValues exps' result r
300− filterValues exps' result (ValueRef name) =
301− if (name, mn) `elem` exps'
302− then return $ (name, mn) : result
303− else throwError . errorMessage . UnknownExportValue $ name
304− filterValues _ result _ = return result
297+ -> m (M.Map a ModuleName)
298+ filterExport toName get fromExps result (PositionedDeclarationRef pos _ r) =
299+ rethrowWithPosition pos $ filterExport toName get fromExps result r
300+ filterExport toName get fromExps result ref
301+ | Just name <- get ref =
302+ case name `M.lookup` fromExps exps of
303+ -- TODO: I'm not sure if we actually need to check mn == mn' here -gb
304+ Just mn' | mn == mn' -> return $ M.insert name mn result
305+ _ -> throwError . errorMessage . UnknownExport $ toName name
306+ filterExport _ _ _ result _ = return result
src/Language/PureScript/Sugar/Names/Imports.hs+89−179
@@ -1,166 +1,64 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE TupleSections #-}
4−{-# LANGUAGE LambdaCase #-}
5−
61module Language.PureScript.Sugar.Names.Imports
7− ( resolveImports
2+ ( ImportDef
3+ , resolveImports
84 , resolveModuleImport
95 , findImports
106 ) where
117
12−import Prelude ()
138import Prelude.Compat
149
15−import Data.Foldable (traverse_, for_)
16−import Data.Function (on)
17−import Data.List (find, sortBy, groupBy, (\\))
18−import Data.Maybe (fromMaybe, isNothing, fromJust)
19−import Data.Traversable (for)
20−
21−import Control.Arrow (first)
2210import Control.Monad
2311import Control.Monad.Error.Class (MonadError(..))
24−import Control.Monad.Writer (MonadWriter(..))
2512
13+import Data.Foldable (for_, traverse_)
14+import Data.Maybe (fromMaybe)
2615import qualified Data.Map as M
2716import qualified Data.Set as S
2817
29−import Language.PureScript.Crash
3018import Language.PureScript.AST
31−import Language.PureScript.Names
19+import Language.PureScript.Crash
3220import Language.PureScript.Errors
21+import Language.PureScript.Names
3322import Language.PureScript.Sugar.Names.Env
3423
24+type ImportDef = (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)
25+
3526-- |
3627-- Finds the imports within a module, mapping the imported module name to an optional set of
3728-- explicitly imported declarations.
3829--
3930findImports
40− :: forall m
41− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
42− => [Declaration]
43− -> m (M.Map ModuleName [(Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)])
44−findImports = foldM (go Nothing) M.empty
31+ :: [Declaration]
32+ -> M.Map ModuleName [ImportDef]
33+findImports = foldl (go Nothing) M.empty
4534 where
46− go pos result (ImportDeclaration mn typ qual isOldSyntax) = do
47− when isOldSyntax . tell . errorMessage $ DeprecatedQualifiedSyntax mn (fromJust qual)
35+ go pos result (ImportDeclaration mn typ qual) =
4836 let imp = (pos, typ, qual)
49− return $ M.insert mn (maybe [imp] (imp :) (mn `M.lookup` result)) result
50− go _ result (PositionedDeclaration pos _ d) = warnAndRethrowWithPosition pos $ go (Just pos) result d
51− go _ result _ = return result
52−
53−type ImportDef = (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)
37+ in M.insert mn (maybe [imp] (imp :) (mn `M.lookup` result)) result
38+ go _ result (PositionedDeclaration pos _ d) = go (Just pos) result d
39+ go _ result _ = result
5440
5541-- |
5642-- Constructs a set of imports for a module.
5743--
5844resolveImports
5945 :: forall m
60− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
46+ . MonadError MultipleErrors m
6147 => Env
6248 -> Module
6349 -> m (Module, Imports)
6450resolveImports env (Module ss coms currentModule decls exps) =
65− warnAndRethrow (addHint (ErrorInModule currentModule)) $ do
66−
67− decls' <- traverse updateImportRef decls
68− imports <- findImports decls'
69−
70− for_ (M.toList imports) $ \(mn, imps) -> do
71−
72− warned <- foldM (checkDuplicateImports mn) [] (selfCartesianSubset imps)
73−
74− let unwarned = imps \\ warned
75− duplicates
76− = join
77− . map tail
78− . filter ((> 1) . length)
79− . groupBy ((==) `on` defQual)
80− . sortBy (compare `on` defQual)
81− $ unwarned
82−
83− warned' <-
84− for duplicates $ \i@(pos, _, _) -> do
85− warn pos $ DuplicateSelectiveImport mn
86− return i
87−
88− for_ (imps \\ (warned ++ warned')) $ \(pos, typ, _) ->
89− let (dupeRefs, dupeDctors) = findDuplicateRefs $ case typ of
90− Explicit refs -> refs
91− Hiding refs -> refs
92− _ -> []
93− in warnDupeRefs pos dupeRefs >> warnDupeDctors pos dupeDctors
94−
95− return ()
96−
97− let imports' = M.map (map (\(ss', dt, mmn) -> (ss', Just dt, mmn))) imports
51+ rethrow (addHint (ErrorInModule currentModule)) $ do
52+ let imports = findImports decls
53+ imports' = M.map (map (\(ss', dt, mmn) -> (ss', Just dt, mmn))) imports
9854 scope = M.insert currentModule [(Nothing, Nothing, Nothing)] imports'
99− resolved <- foldM (resolveModuleImport env) nullImports (M.toList scope)
100−
101− return (Module ss coms currentModule decls' exps, resolved)
102−
103− where
104− defQual :: ImportDef -> Maybe ModuleName
105− defQual (_, _, q) = q
106−
107− selfCartesianSubset :: [a] -> [(a, a)]
108− selfCartesianSubset (x : xs) = [(x, y) | y <- xs] ++ selfCartesianSubset xs
109− selfCartesianSubset [] = []
110−
111− checkDuplicateImports :: ModuleName -> [ImportDef] -> (ImportDef, ImportDef) -> m [ImportDef]
112− checkDuplicateImports mn xs ((_, t1, q1), (pos, t2, q2)) =
113− if (t1 == t2 && q1 == q2)
114− then do
115− warn pos $ DuplicateImport mn t2 q2
116− return $ (pos, t2, q2) : xs
117− else return xs
118−
119− warnDupeRefs :: Maybe SourceSpan -> [DeclarationRef] -> m ()
120− warnDupeRefs pos = traverse_ $ \case
121− TypeRef name _ -> warnDupe pos $ "type " ++ runProperName name
122− TypeOpRef name -> warnDupe pos $ "type operator " ++ runIdent name
123− ValueRef name -> warnDupe pos $ "value " ++ runIdent name
124− TypeClassRef name -> warnDupe pos $ "class " ++ runProperName name
125− ModuleRef name -> warnDupe pos $ "module " ++ runModuleName name
126− _ -> return ()
127−
128− warnDupeDctors :: Maybe SourceSpan -> [ProperName 'ConstructorName] -> m ()
129− warnDupeDctors pos = traverse_ (warnDupe pos . ("data constructor " ++) . runProperName)
130−
131− warnDupe :: Maybe SourceSpan -> String -> m ()
132− warnDupe pos ref = warn pos $ DuplicateImportRef ref
133−
134− warn :: Maybe SourceSpan -> SimpleErrorMessage -> m ()
135− warn pos msg = maybe id warnWithPosition pos $ tell . errorMessage $ msg
136−
137− updateImportRef :: Declaration -> m Declaration
138− updateImportRef (PositionedDeclaration pos com d) =
139− warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> updateImportRef d
140− updateImportRef (ImportDeclaration mn typ qual isOldSyntax) = do
141− modExports <- getExports env mn
142− typ' <- case typ of
143− Implicit -> return Implicit
144− Explicit refs -> Explicit <$> updateProperRef mn modExports `traverse` refs
145− Hiding refs -> Hiding <$> updateProperRef mn modExports `traverse` refs
146− return $ ImportDeclaration mn typ' qual isOldSyntax
147− updateImportRef other = return other
148−
149− updateProperRef :: ModuleName -> Exports -> DeclarationRef -> m DeclarationRef
150− updateProperRef importModule modExports (ProperRef name) =
151− if ProperName name `elem` (fst `map` exportedTypeClasses modExports)
152− then do
153− tell . errorMessage $ DeprecatedClassImport importModule (ProperName name)
154− return . TypeClassRef $ ProperName name
155− else return $ TypeRef (ProperName name) (Just [])
156− updateProperRef importModule modExports (PositionedDeclarationRef pos com ref) =
157− PositionedDeclarationRef pos com <$> updateProperRef importModule modExports ref
158− updateProperRef _ _ other = return other
55+ (Module ss coms currentModule decls exps,) <$>
56+ foldM (resolveModuleImport env) primImports (M.toList scope)
15957
16058-- | Constructs a set of imports for a single module import.
16159resolveModuleImport
16260 :: forall m
163− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
61+ . MonadError MultipleErrors m
16462 => Env
16563 -> Imports
16664 -> (ModuleName, [(Maybe SourceSpan, Maybe ImportDeclarationType, Maybe ModuleName)])
@@ -171,10 +69,15 @@ resolveModuleImport env ie (mn, imps) = foldM go ie imps
17169 -> (Maybe SourceSpan, Maybe ImportDeclarationType, Maybe ModuleName)
17270 -> m Imports
17371 go ie' (pos, typ, impQual) = do
174− modExports <- positioned $ maybe (throwError . errorMessage $ UnknownModule mn) (return . envModuleExports) $ mn `M.lookup` env
175− let virtualModules = importedVirtualModules ie'
176− ie'' = ie' { importedModules = S.insert mn (importedModules ie')
177− , importedVirtualModules = maybe virtualModules (`S.insert` virtualModules) impQual
72+ modExports <-
73+ positioned $ maybe
74+ (throwError . errorMessage . UnknownName . Qualified Nothing $ ModName mn)
75+ (return . envModuleExports)
76+ (mn `M.lookup` env)
77+ let impModules = importedModules ie'
78+ qualModules = importedQualModules ie'
79+ ie'' = ie' { importedModules = maybe (S.insert mn impModules) (const impModules) impQual
80+ , importedQualModules = maybe qualModules (`S.insert` qualModules) impQual
17881 }
17982 positioned $ resolveImport mn modExports ie'' impQual typ
18083 where
@@ -187,7 +90,7 @@ resolveModuleImport env ie (mn, imps) = foldM go ie imps
18790--
18891resolveImport
18992 :: forall m
190− . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)
93+ . MonadError MultipleErrors m
19194 => ModuleName
19295 -> Exports
19396 -> Imports
@@ -198,19 +101,14 @@ resolveImport importModule exps imps impQual = resolveByType
198101 where
199102
200103 resolveByType :: Maybe ImportDeclarationType -> m Imports
201− resolveByType Nothing = importAll (importRef Local)
202− resolveByType (Just Implicit) = importAll (importRef FromImplicit)
203− resolveByType (Just (Explicit refs)) = checkRefs False refs >> foldM (importRef FromExplicit) imps refs
204− resolveByType (Just (Hiding refs)) = do
205− imps' <- checkRefs True refs >> importAll (importNonHidden refs)
206− let isEmptyImport
207− = M.null (importedTypes imps')
208− && M.null (importedTypeOps imps')
209− && M.null (importedDataConstructors imps')
210− && M.null (importedTypeClasses imps')
211− && M.null (importedValues imps')
212− when isEmptyImport $ tell . errorMessage $ RedundantEmptyHidingImport importModule
213− return imps'
104+ resolveByType Nothing =
105+ importAll (importRef Local)
106+ resolveByType (Just Implicit) =
107+ importAll (importRef FromImplicit)
108+ resolveByType (Just (Explicit refs)) =
109+ checkRefs False refs >> foldM (importRef FromExplicit) imps refs
110+ resolveByType (Just (Hiding refs)) =
111+ checkRefs True refs >> importAll (importNonHidden refs)
214112
215113 -- Check that a 'DeclarationRef' refers to an importable symbol
216114 checkRefs :: Bool -> [DeclarationRef] -> m ()
@@ -219,28 +117,32 @@ resolveImport importModule exps imps impQual = resolveByType
219117 check (PositionedDeclarationRef pos _ r) =
220118 rethrowWithPosition pos $ check r
221119 check (ValueRef name) =
222− checkImportExists UnknownImportValue (fst `map` exportedValues exps) name
120+ checkImportExists IdentName (exportedValues exps) name
121+ check (ValueOpRef op) =
122+ checkImportExists ValOpName (exportedValueOps exps) op
223123 check (TypeRef name dctors) = do
224− checkImportExists UnknownImportType ((fst . fst) `map` exportedTypes exps) name
225− let allDctors = fst `map` allExportedDataConstructors name
226− maybe (return ()) (traverse_ $ checkDctorExists name allDctors) dctors
124+ checkImportExists TyName (exportedTypes exps) name
125+ let (allDctors, _) = allExportedDataConstructors name
126+ for_ dctors $ traverse_ (checkDctorExists name allDctors)
227127 check (TypeOpRef name) =
228− checkImportExists UnknownImportTypeOp (fst `map` exportedTypeOps exps) name
128+ checkImportExists TyOpName (exportedTypeOps exps) name
229129 check (TypeClassRef name) =
230− checkImportExists UnknownImportTypeClass (fst `map` exportedTypeClasses exps) name
130+ checkImportExists TyClassName (exportedTypeClasses exps) name
231131 check (ModuleRef name) | isHiding =
232132 throwError . errorMessage $ ImportHidingModule name
233133 check r = internalError $ "Invalid argument to checkRefs: " ++ show r
234134
235135 -- Check that an explicitly imported item exists in the module it is being imported from
236136 checkImportExists
237− :: Eq a
238− => (ModuleName -> a -> SimpleErrorMessage)
239− -> [a]
137+ :: Ord a
138+ => (a -> Name)
139+ -> M.Map a b
240140 -> a
241141 -> m ()
242− checkImportExists unknown exports item =
243− when (item `notElem` exports) $ throwError . errorMessage $ unknown importModule item
142+ checkImportExists toName exports item
143+ = when (item `M.notMember` exports)
144+ . throwError . errorMessage
145+ $ UnknownImport importModule (toName item)
244146
245147 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
246148 -- from
@@ -249,7 +151,10 @@ resolveImport importModule exps imps impQual = resolveByType
249151 -> [ProperName 'ConstructorName]
250152 -> ProperName 'ConstructorName
251153 -> m ()
252− checkDctorExists tcon = checkImportExists (flip UnknownImportDataConstructor tcon)
154+ checkDctorExists tcon exports dctor
155+ = when (dctor `notElem` exports)
156+ . throwError . errorMessage
157+ $ UnknownImportDataConstructor importModule tcon dctor
253158
254159 importNonHidden :: [DeclarationRef] -> Imports -> DeclarationRef -> m Imports
255160 importNonHidden hidden m ref | isHidden ref = return m
@@ -270,54 +175,59 @@ resolveImport importModule exps imps impQual = resolveByType
270175
271176 -- Import all symbols
272177 importAll :: (Imports -> DeclarationRef -> m Imports) -> m Imports
273− importAll importer = do
274− imp' <- foldM (\m ((name, dctors), _) -> importer m (TypeRef name (Just dctors))) imps (exportedTypes exps)
275− imp'' <- foldM (\m (name, _) -> importer m (TypeOpRef name)) imp' (exportedTypeOps exps)
276− imp''' <- foldM (\m (name, _) -> importer m (ValueRef name)) imp'' (exportedValues exps)
277− foldM (\m (name, _) -> importer m (TypeClassRef name)) imp''' (exportedTypeClasses exps)
178+ importAll importer =
179+ foldM (\m (name, (dctors, _)) -> importer m (TypeRef name (Just dctors))) imps (M.toList (exportedTypes exps))
180+ >>= flip (foldM (\m (name, _) -> importer m (TypeOpRef name))) (M.toList (exportedTypeOps exps))
181+ >>= flip (foldM (\m (name, _) -> importer m (ValueRef name))) (M.toList (exportedValues exps))
182+ >>= flip (foldM (\m (name, _) -> importer m (ValueOpRef name))) (M.toList (exportedValueOps exps))
183+ >>= flip (foldM (\m (name, _) -> importer m (TypeClassRef name))) (M.toList (exportedTypeClasses exps))
278184
279185 importRef :: ImportProvenance -> Imports -> DeclarationRef -> m Imports
280186 importRef prov imp (PositionedDeclarationRef pos _ r) =
281− warnAndRethrowWithPosition pos $ importRef prov imp r
187+ rethrowWithPosition pos $ importRef prov imp r
282188 importRef prov imp (ValueRef name) = do
283− let values' = updateImports (importedValues imp) (exportedValues exps) name prov
189+ let values' = updateImports (importedValues imp) (exportedValues exps) id name prov
284190 return $ imp { importedValues = values' }
191+ importRef prov imp (ValueOpRef name) = do
192+ let valueOps' = updateImports (importedValueOps imp) (exportedValueOps exps) id name prov
193+ return $ imp { importedValueOps = valueOps' }
285194 importRef prov imp (TypeRef name dctors) = do
286− let types' = updateImports (importedTypes imp) (first fst `map` exportedTypes exps) name prov
287− let exportedDctors :: [(ProperName 'ConstructorName, ModuleName)]
288− exportedDctors = allExportedDataConstructors name
289− dctorNames :: [ProperName 'ConstructorName]
290− dctorNames = fst `map` exportedDctors
291− maybe (return ()) (traverse_ $ checkDctorExists name dctorNames) dctors
292− when (null dctorNames && isNothing dctors) . tell . errorMessage $ MisleadingEmptyTypeImport importModule name
293− let dctors' = foldl (\m d -> updateImports m exportedDctors d prov) (importedDataConstructors imp) (fromMaybe dctorNames dctors)
195+ let types' = updateImports (importedTypes imp) (exportedTypes exps) snd name prov
196+ let (dctorNames, mn) = allExportedDataConstructors name
197+ dctorLookup :: M.Map (ProperName 'ConstructorName) ModuleName
198+ dctorLookup = M.fromList $ map (, mn) dctorNames
199+ traverse_ (traverse_ $ checkDctorExists name dctorNames) dctors
200+ let dctors' = foldl (\m d -> updateImports m dctorLookup id d prov) (importedDataConstructors imp) (fromMaybe dctorNames dctors)
294201 return $ imp { importedTypes = types', importedDataConstructors = dctors' }
295202 importRef prov imp (TypeOpRef name) = do
296− let ops' = updateImports (importedTypeOps imp) (exportedTypeOps exps) name prov
203+ let ops' = updateImports (importedTypeOps imp) (exportedTypeOps exps) id name prov
297204 return $ imp { importedTypeOps = ops' }
298205 importRef prov imp (TypeClassRef name) = do
299− let typeClasses' = updateImports (importedTypeClasses imp) (exportedTypeClasses exps) name prov
206+ let typeClasses' = updateImports (importedTypeClasses imp) (exportedTypeClasses exps) id name prov
300207 return $ imp { importedTypeClasses = typeClasses' }
301− importRef _ _ _ = internalError "Invalid argument to importRef"
208+ importRef _ _ TypeInstanceRef{} = internalError "TypeInstanceRef in importRef"
209+ importRef _ _ ModuleRef{} = internalError "ModuleRef in importRef"
302210
303211 -- Find all exported data constructors for a given type
304− allExportedDataConstructors :: ProperName 'TypeName -> [(ProperName 'ConstructorName, ModuleName)]
212+ allExportedDataConstructors
213+ :: ProperName 'TypeName
214+ -> ([ProperName 'ConstructorName], ModuleName)
305215 allExportedDataConstructors name =
306− case find ((== name) . fst . fst) (exportedTypes exps) of
307− Nothing -> internalError "Invalid state in allExportedDataConstructors"
308− Just ((_, dctors), mn) -> map (, mn) dctors
216+ fromMaybe (internalError "Invalid state in allExportedDataConstructors")
217+ $ name `M.lookup` exportedTypes exps
309218
310219 -- Add something to an import resolution list
311220 updateImports
312221 :: (Ord a)
313222 => M.Map (Qualified a) [ImportRecord a]
314− -> [(a, ModuleName)]
223+ -> M.Map a b
224+ -> (b -> ModuleName)
315225 -> a
316226 -> ImportProvenance
317227 -> M.Map (Qualified a) [ImportRecord a]
318− updateImports imps' exps' name prov =
228+ updateImports imps' exps' expName name prov =
319229 let
320− mnOrig = fromMaybe (internalError "Invalid state in updateImports") (name `lookup` exps')
230+ mnOrig = maybe (internalError "Invalid state in updateImports") expName (name `M.lookup` exps')
321231 rec = ImportRecord (Qualified (Just importModule) name) mnOrig prov
322232 in
323233 M.alter
src/Language/PureScript/Sugar/ObjectWildcards.hs+7−10
@@ -1,12 +1,7 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE PatternGuards #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
1+module Language.PureScript.Sugar.ObjectWildcards
2+ ( desugarObjectConstructors
3+ ) where
44
5−module Language.PureScript.Sugar.ObjectWildcards (
6− desugarObjectConstructors
7−) where
8−
9−import Prelude ()
105import Prelude.Compat
116
127import Control.Monad (forM)
@@ -39,10 +34,12 @@ desugarObjectConstructors (Module ss coms mn ds exts) = Module ss coms mn <$> ma
3934 desugarExpr (Parens b)
4035 | b' <- stripPositionInfo b
4136 , BinaryNoParens op val u <- b'
42− , isAnonymousArgument u = return $ OperatorSection op (Left val)
37+ , isAnonymousArgument u = do arg <- freshIdent'
38+ return $ Abs (Left arg) $ App (App op val) (Var (Qualified Nothing arg))
4339 | b' <- stripPositionInfo b
4440 , BinaryNoParens op u val <- b'
45− , isAnonymousArgument u = return $ OperatorSection op (Right val)
41+ , isAnonymousArgument u = do arg <- freshIdent'
42+ return $ Abs (Left arg) $ App (App op (Var (Qualified Nothing arg))) val
4643 desugarExpr (Literal (ObjectLiteral ps)) = wrapLambda (Literal . ObjectLiteral) ps
4744 desugarExpr (ObjectUpdate u ps) | isAnonymousArgument u = do
4845 obj <- freshIdent'
src/Language/PureScript/Sugar/Operators.hs+211−128
@@ -1,8 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE RecordWildCards #-}
4−{-# LANGUAGE TupleSections #-}
5−
61-- |
72-- This module implements the desugaring pass which reapplies binary operators based
83-- on their fixity data and removes explicit parentheses.
@@ -11,12 +6,11 @@
116-- it is necessary to reorder them here.
127--
138module Language.PureScript.Sugar.Operators
14− ( rebracket
15− , removeSignedLiterals
16− , desugarOperatorSections
9+ ( desugarSignedLiterals
10+ , rebracket
11+ , checkFixityExports
1712 ) where
1813
19−import Prelude ()
2014import Prelude.Compat
2115
2216import Language.PureScript.AST
@@ -30,28 +24,43 @@ import Language.PureScript.Sugar.Operators.Types
3024import Language.PureScript.Traversals (defS, sndM)
3125import Language.PureScript.Types
3226
33−import Control.Monad ((<=<))
27+import Control.Monad (unless, (<=<))
3428import Control.Monad.Error.Class (MonadError(..))
35−import Control.Monad.Supply.Class
3629
30+import Data.Either (partitionEithers)
31+import Data.Foldable (for_, traverse_)
3732import Data.Function (on)
38−import Data.Functor.Identity
39−import Data.List (partition, groupBy, sortBy)
40−import Data.Maybe (mapMaybe)
33+import Data.Functor.Identity (Identity(..), runIdentity)
34+import Data.List (groupBy, sortBy)
35+import Data.Maybe (mapMaybe, listToMaybe)
36+import Data.Traversable (for)
4137import qualified Data.Map as M
4238
4339import qualified Language.PureScript.Constants as C
4440
45−-- TODO: in 0.9 operators names can have their own type rather than being in a sum with `Ident`, and `FixityAlias` no longer needs to be optional
41+-- |
42+-- Removes unary negation operators and replaces them with calls to `negate`.
43+--
44+desugarSignedLiterals :: Module -> Module
45+desugarSignedLiterals (Module ss coms mn ds exts) =
46+ Module ss coms mn (map f' ds) exts
47+ where
48+ (f', _, _) = everywhereOnValues id go id
49+ go (UnaryMinus val) = App (Var (Qualified Nothing (Ident C.negate))) val
50+ go other = other
4651
4752-- |
4853-- An operator associated with its declaration position, fixity, and the name
4954-- of the function or data constructor it is an alias for.
5055--
51−type FixityRecord = (Qualified Ident, SourceSpan, Fixity, Maybe (Qualified FixityAlias))
56+type FixityRecord op alias = (Qualified op, SourceSpan, Fixity, Qualified alias)
57+type ValueFixityRecord = FixityRecord (OpName 'ValueOpName) (Either Ident (ProperName 'ConstructorName))
58+type TypeFixityRecord = FixityRecord (OpName 'TypeOpName) (ProperName 'TypeName)
5259
5360-- |
54−-- Remove explicit parentheses and reorder binary operator applications
61+-- Remove explicit parentheses and reorder binary operator applications.
62+--
63+-- This pass requires name desugaring and export elaboration to have run first.
5564--
5665rebracket
5766 :: forall m
@@ -59,56 +68,57 @@ rebracket
5968 => [ExternsFile]
6069 -> [Module]
6170 -> m [Module]
62−rebracket externs ms = do
63− let (typeFixities, valueFixities) = partition isTypeFixity $
64− concatMap externsFixities externs ++ concatMap collectFixities ms
71+rebracket externs modules = do
72+ let (valueFixities, typeFixities) =
73+ partitionEithers
74+ $ concatMap externsFixities externs
75+ ++ concatMap collectFixities modules
6576
66− ensureNoDuplicates' $ valueFixities
67− ensureNoDuplicates' $ typeFixities
77+ ensureNoDuplicates' MultipleValueOpFixities valueFixities
78+ ensureNoDuplicates' MultipleTypeOpFixities typeFixities
6879
6980 let valueOpTable = customOperatorTable' valueFixities
70− typeOpTable = customOperatorTable' typeFixities
71− ms' <- traverse (rebracketModule valueOpTable typeOpTable) ms
81+ let valueAliased = M.fromList (map makeLookupEntry valueFixities)
82+ let typeOpTable = customOperatorTable' typeFixities
83+ let typeAliased = M.fromList (map makeLookupEntry typeFixities)
7284
73− let valueAliased = M.fromList (mapMaybe makeLookupEntry valueFixities)
74− typeAliased = M.fromList (mapMaybe makeLookupEntry typeFixities)
75− mapM (renameAliasedOperators valueAliased typeAliased) ms'
85+ for modules
86+ $ renameAliasedOperators valueAliased typeAliased
87+ <=< rebracketModule valueOpTable typeOpTable
7688
7789 where
7890
79− isTypeFixity :: FixityRecord -> Bool
80− -- Nothing case for FixityAlias can only ever be a value fixity, as it's not
81− -- possible to define types with operator names aside through aliasing.
82− -- TODO: This comment is redundant after 0.9.
83− isTypeFixity (_, _, _, Just (Qualified _ (AliasType _))) = True
84− isTypeFixity _ = False
85−
86− ensureNoDuplicates' :: [FixityRecord] -> m ()
87− ensureNoDuplicates' =
88− ensureNoDuplicates . map (\(i, pos, _, _) -> (i, pos))
91+ ensureNoDuplicates'
92+ :: Ord op
93+ => (op -> SimpleErrorMessage)
94+ -> [FixityRecord op alias]
95+ -> m ()
96+ ensureNoDuplicates' toError =
97+ ensureNoDuplicates toError . map (\(i, pos, _, _) -> (i, pos))
8998
90− customOperatorTable' :: [FixityRecord] -> [[(Qualified Ident, Associativity)]]
91− customOperatorTable' =
92− customOperatorTable . map (\(i, _, f, _) -> (i, f))
99+ customOperatorTable'
100+ :: [FixityRecord op alias]
101+ -> [[(Qualified op, Associativity)]]
102+ customOperatorTable' = customOperatorTable . map (\(i, _, f, _) -> (i, f))
93103
94− makeLookupEntry :: FixityRecord -> Maybe (Qualified Ident, Qualified FixityAlias)
95− makeLookupEntry (qname, _, _, alias) = (qname, ) <$> alias
104+ makeLookupEntry :: FixityRecord op alias -> (Qualified op, Qualified alias)
105+ makeLookupEntry (qname, _, _, alias) = (qname, alias)
96106
97107 renameAliasedOperators
98− :: M.Map (Qualified Ident) (Qualified FixityAlias)
99− -> M.Map (Qualified Ident) (Qualified FixityAlias)
108+ :: M.Map (Qualified (OpName 'ValueOpName)) (Qualified (Either Ident (ProperName 'ConstructorName)))
109+ -> M.Map (Qualified (OpName 'TypeOpName)) (Qualified (ProperName 'TypeName))
100110 -> Module
101111 -> m Module
102112 renameAliasedOperators valueAliased typeAliased (Module ss coms mn ds exts) =
103113 Module ss coms mn <$> mapM f' ds <*> pure exts
104114 where
105− (goDecl', goExpr') = updateTypes goType
115+ (goDecl', goExpr', goBinder') = updateTypes goType
106116 (f', _, _, _, _) =
107117 everywhereWithContextOnValuesM
108118 Nothing
109119 (\pos -> uncurry goDecl <=< goDecl' pos)
110120 (\pos -> uncurry goExpr <=< goExpr' pos)
111− goBinder
121+ (\pos -> uncurry goBinder <=< goBinder' pos)
112122 defS
113123 defS
114124
@@ -118,52 +128,51 @@ rebracket externs ms = do
118128
119129 goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
120130 goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
121− goExpr pos (Var name) = return (pos, case name `M.lookup` valueAliased of
122− Just (Qualified mn' (AliasValue alias)) -> Var (Qualified mn' alias)
123− Just (Qualified mn' (AliasConstructor alias)) -> Constructor (Qualified mn' alias)
124− _ -> Var name)
131+ goExpr pos (Op op) =
132+ (pos, ) <$> case op `M.lookup` valueAliased of
133+ Just (Qualified mn' (Left alias)) ->
134+ return $ Var (Qualified mn' alias)
135+ Just (Qualified mn' (Right alias)) ->
136+ return $ Constructor (Qualified mn' alias)
137+ Nothing ->
138+ maybe id rethrowWithPosition pos $
139+ throwError . errorMessage . UnknownName $ fmap ValOpName op
125140 goExpr pos other = return (pos, other)
126141
127142 goBinder :: Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)
128143 goBinder _ b@(PositionedBinder pos _ _) = return (Just pos, b)
129− goBinder pos (BinaryNoParensBinder (OpBinder name) lhs rhs) = case name `M.lookup` valueAliased of
130− Just (Qualified _ (AliasValue alias)) ->
131− maybe id rethrowWithPosition pos $
132− throwError . errorMessage $ InvalidOperatorInBinder (disqualify name) alias
133− Just (Qualified mn' (AliasConstructor alias)) ->
134− return (pos, ConstructorBinder (Qualified mn' alias) [lhs, rhs])
135− _ ->
136− maybe id rethrowWithPosition pos $
137− throwError . errorMessage $ UnknownValue name
138− goBinder _ (BinaryNoParensBinder {}) =
144+ goBinder pos (BinaryNoParensBinder (OpBinder op) lhs rhs) =
145+ case op `M.lookup` valueAliased of
146+ Just (Qualified mn' (Left alias)) ->
147+ maybe id rethrowWithPosition pos $
148+ throwError . errorMessage $
149+ InvalidOperatorInBinder op (Qualified mn' alias)
150+ Just (Qualified mn' (Right alias)) ->
151+ return (pos, ConstructorBinder (Qualified mn' alias) [lhs, rhs])
152+ Nothing ->
153+ maybe id rethrowWithPosition pos $
154+ throwError . errorMessage . UnknownName $ fmap ValOpName op
155+ goBinder _ BinaryNoParensBinder{} =
139156 internalError "BinaryNoParensBinder has no OpBinder"
140157 goBinder pos other = return (pos, other)
141158
142159 goType :: Maybe SourceSpan -> Type -> m Type
143− goType pos = everywhereOnTypesM go
160+ goType pos = maybe id rethrowWithPosition pos . everywhereOnTypesM go
144161 where
145162 go :: Type -> m Type
146− go (BinaryNoParensType (TypeOp name) lhs rhs) = case name `M.lookup` typeAliased of
147− Just (Qualified mn' (AliasType alias)) ->
148− return $ TypeApp (TypeApp (TypeConstructor (Qualified mn' alias)) lhs) rhs
149− _ ->
150− maybe id rethrowWithPosition pos $
151− throwError . errorMessage $ UnknownTypeOp name
163+ go (BinaryNoParensType (TypeOp op) lhs rhs) =
164+ case op `M.lookup` typeAliased of
165+ Just alias ->
166+ return $ TypeApp (TypeApp (TypeConstructor alias) lhs) rhs
167+ Nothing ->
168+ throwError . errorMessage $ UnknownName $ fmap TyOpName op
152169 go other = return other
153170
154−removeSignedLiterals :: Module -> Module
155−removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds) exts
156− where
157− (f', _, _) = everywhereOnValues id go id
158−
159− go (UnaryMinus val) = App (Var (Qualified Nothing (Ident C.negate))) val
160− go other = other
161−
162171rebracketModule
163172 :: forall m
164173 . (MonadError MultipleErrors m)
165− => [[(Qualified Ident, Associativity)]]
166− -> [[(Qualified Ident, Associativity)]]
174+ => [[(Qualified (OpName 'ValueOpName), Associativity)]]
175+ -> [[(Qualified (OpName 'TypeOpName), Associativity)]]
167176 -> Module
168177 -> m Module
169178rebracketModule valueOpTable typeOpTable (Module ss coms mn ds exts) =
@@ -173,9 +182,9 @@ rebracketModule valueOpTable typeOpTable (Module ss coms mn ds exts) =
173182 everywhereOnValuesTopDownM
174183 (decontextify goDecl)
175184 (goExpr <=< decontextify goExpr')
176− goBinder
185+ (goBinder <=< decontextify goBinder')
177186
178− (goDecl, goExpr') = updateTypes (\_ -> goType)
187+ (goDecl, goExpr', goBinder') = updateTypes (const goType)
179188
180189 goExpr :: Expr -> m Expr
181190 goExpr = return . matchExprOperators valueOpTable
@@ -196,9 +205,9 @@ removeParens = f
196205 everywhereOnValues
197206 (decontextify goDecl)
198207 (goExpr . decontextify goExpr')
199− goBinder
208+ (goBinder . decontextify goBinder')
200209
201− (goDecl, goExpr') = updateTypes (\_ -> return . goType)
210+ (goDecl, goExpr', goBinder') = updateTypes (\_ -> return . goType)
202211
203212 goExpr :: Expr -> Expr
204213 goExpr (Parens val) = val
@@ -218,40 +227,61 @@ removeParens = f
218227 -> a
219228 decontextify ctxf = snd . runIdentity . ctxf Nothing
220229
221−externsFixities
222− :: ExternsFile
223− -> [FixityRecord]
230+externsFixities :: ExternsFile -> [Either ValueFixityRecord TypeFixityRecord]
224231externsFixities ExternsFile{..} =
225− [ (Qualified (Just efModuleName) (Op op), internalModuleSourceSpan "", Fixity assoc prec, alias)
226− | ExternsFixity assoc prec op alias <- efFixities
227− ]
232+ map fromFixity efFixities ++ map fromTypeFixity efTypeFixities
233+ where
228234
229−collectFixities :: Module -> [FixityRecord]
235+ fromFixity
236+ :: ExternsFixity
237+ -> Either ValueFixityRecord TypeFixityRecord
238+ fromFixity (ExternsFixity assoc prec op name) =
239+ Left
240+ ( Qualified (Just efModuleName) op
241+ , internalModuleSourceSpan ""
242+ , Fixity assoc prec
243+ , name
244+ )
245+
246+ fromTypeFixity
247+ :: ExternsTypeFixity
248+ -> Either ValueFixityRecord TypeFixityRecord
249+ fromTypeFixity (ExternsTypeFixity assoc prec op name) =
250+ Right
251+ ( Qualified (Just efModuleName) op
252+ , internalModuleSourceSpan ""
253+ , Fixity assoc prec
254+ , name
255+ )
256+
257+collectFixities :: Module -> [Either ValueFixityRecord TypeFixityRecord]
230258collectFixities (Module _ _ moduleName ds _) = concatMap collect ds
231259 where
232− collect :: Declaration -> [FixityRecord]
233− collect (PositionedDeclaration pos _ (FixityDeclaration fixity name alias)) =
234− [(Qualified (Just moduleName) (Op name), pos, fixity, alias)]
260+ collect :: Declaration -> [Either ValueFixityRecord TypeFixityRecord]
261+ collect (PositionedDeclaration pos _ (ValueFixityDeclaration fixity name op)) =
262+ [Left (Qualified (Just moduleName) op, pos, fixity, name)]
263+ collect (PositionedDeclaration pos _ (TypeFixityDeclaration fixity name op)) =
264+ [Right (Qualified (Just moduleName) op, pos, fixity, name)]
235265 collect FixityDeclaration{} = internalError "Fixity without srcpos info"
236266 collect _ = []
237267
238268ensureNoDuplicates
239− :: MonadError MultipleErrors m
240− => [(Qualified Ident, SourceSpan)]
269+ :: (Ord a, MonadError MultipleErrors m)
270+ => (a -> SimpleErrorMessage)
271+ -> [(Qualified a, SourceSpan)]
241272 -> m ()
242−ensureNoDuplicates m = go $ sortBy (compare `on` fst) m
273+ensureNoDuplicates toError m = go $ sortBy (compare `on` fst) m
243274 where
244275 go [] = return ()
245276 go [_] = return ()
246− go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
277+ go ((x@(Qualified (Just mn) op), _) : (y, pos) : _) | x == y =
247278 rethrow (addHint (ErrorInModule mn)) $
248− rethrowWithPosition pos $
249− throwError . errorMessage $ MultipleFixities name
279+ rethrowWithPosition pos $ throwError . errorMessage $ toError op
250280 go (_ : rest) = go rest
251281
252282customOperatorTable
253− :: [(Qualified Ident, Fixity)]
254− -> [[(Qualified Ident, Associativity)]]
283+ :: [(Qualified op, Fixity)]
284+ -> [[(Qualified op, Associativity)]]
255285customOperatorTable fixities =
256286 let
257287 userOps = map (\(name, Fixity a p) -> (name, p, a)) fixities
@@ -260,36 +290,15 @@ customOperatorTable fixities =
260290 in
261291 map (map (\(name, _, a) -> (name, a))) groups
262292
263−desugarOperatorSections
264− :: forall m
265− . (MonadSupply m, MonadError MultipleErrors m)
266− => Module
267− -> m Module
268−desugarOperatorSections (Module ss coms mn ds exts) =
269− Module ss coms mn <$> traverse goDecl ds <*> pure exts
270− where
271−
272− goDecl :: Declaration -> m Declaration
273− (goDecl, _, _) = everywhereOnValuesM return goExpr return
274−
275− goExpr :: Expr -> m Expr
276− goExpr (OperatorSection op eVal) = do
277− arg <- freshIdent'
278− let var = Var (Qualified Nothing arg)
279− f2 a b = Abs (Left arg) $ App (App op a) b
280− return $ case eVal of
281− Left val -> f2 val var
282− Right val -> f2 var val
283− goExpr other = return other
284−
285293updateTypes
286294 :: forall m
287295 . Monad m
288296 => (Maybe SourceSpan -> Type -> m Type)
289− -> ( Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
290− , Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
297+ -> ( Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
298+ , Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
299+ , Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)
291300 )
292−updateTypes goType = (goDecl, goExpr)
301+updateTypes goType = (goDecl, goExpr, goBinder)
293302 where
294303
295304 goType' :: Maybe SourceSpan -> Type -> m Type
@@ -304,10 +313,10 @@ updateTypes goType = (goDecl, goExpr)
304313 ty' <- goType' pos ty
305314 return (pos, ExternDeclaration name ty')
306315 goDecl pos (TypeClassDeclaration name args implies decls) = do
307− implies' <- traverse (sndM (traverse (goType' pos))) implies
316+ implies' <- traverse (overConstraintArgs (traverse (goType' pos))) implies
308317 return (pos, TypeClassDeclaration name args implies' decls)
309318 goDecl pos (TypeInstanceDeclaration name cs className tys impls) = do
310− cs' <- traverse (sndM (traverse (goType' pos))) cs
319+ cs' <- traverse (overConstraintArgs (traverse (goType' pos))) cs
311320 tys' <- traverse (goType' pos) tys
312321 return (pos, TypeInstanceDeclaration name cs' className tys' impls)
313322 goDecl pos (TypeSynonymDeclaration name args ty) = do
@@ -320,9 +329,9 @@ updateTypes goType = (goDecl, goExpr)
320329
321330 goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
322331 goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
323− goExpr pos (TypeClassDictionary (name, tys) dicts) = do
332+ goExpr pos (TypeClassDictionary (Constraint name tys info) dicts) = do
324333 tys' <- traverse (goType' pos) tys
325− return (pos, TypeClassDictionary (name, tys') dicts)
334+ return (pos, TypeClassDictionary (Constraint name tys' info) dicts)
326335 goExpr pos (SuperClassDictionary cls tys) = do
327336 tys' <- traverse (goType' pos) tys
328337 return (pos, SuperClassDictionary cls tys')
@@ -330,3 +339,77 @@ updateTypes goType = (goDecl, goExpr)
330339 ty' <- goType' pos ty
331340 return (pos, TypedValue check v ty')
332341 goExpr pos other = return (pos, other)
342+
343+ goBinder :: Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)
344+ goBinder _ e@(PositionedBinder pos _ _) = return (Just pos, e)
345+ goBinder pos (TypedBinder ty b) = do
346+ ty' <- goType' pos ty
347+ return (pos, TypedBinder ty' b)
348+ goBinder pos other = return (pos, other)
349+
350+-- |
351+-- Checks all the fixity exports within a module to ensure that members aliased
352+-- by the operators are also exported from the module.
353+--
354+-- This pass requires name desugaring and export elaboration to have run first.
355+--
356+checkFixityExports
357+ :: forall m
358+ . MonadError MultipleErrors m
359+ => Module
360+ -> m Module
361+checkFixityExports (Module _ _ _ _ Nothing) =
362+ internalError "exports should have been elaborated before checkFixityExports"
363+checkFixityExports m@(Module ss _ mn ds (Just exps)) =
364+ rethrow (addHint (ErrorInModule mn))
365+ $ rethrowWithPosition ss (traverse_ checkRef exps)
366+ *> return m
367+ where
368+
369+ checkRef :: DeclarationRef -> m ()
370+ checkRef (PositionedDeclarationRef pos _ d) =
371+ rethrowWithPosition pos $ checkRef d
372+ checkRef dr@(ValueOpRef op) =
373+ for_ (getValueOpAlias op) $ \case
374+ Left ident ->
375+ unless (ValueRef ident `elem` exps)
376+ . throwError . errorMessage
377+ $ TransitiveExportError dr [ValueRef ident]
378+ Right ctor ->
379+ unless (anyTypeRef (maybe False (elem ctor) . snd))
380+ . throwError . errorMessage
381+ $ TransitiveDctorExportError dr ctor
382+ checkRef dr@(TypeOpRef op) =
383+ for_ (getTypeOpAlias op) $ \ty ->
384+ unless (anyTypeRef ((== ty) . fst))
385+ . throwError . errorMessage
386+ $ TransitiveExportError dr [TypeRef ty Nothing]
387+ checkRef _ = return ()
388+
389+ -- Finds the name associated with a type operator when that type is also
390+ -- defined in the current module.
391+ getTypeOpAlias :: OpName 'TypeOpName -> Maybe (ProperName 'TypeName)
392+ getTypeOpAlias op =
393+ listToMaybe (mapMaybe (either (const Nothing) go <=< getFixityDecl) ds)
394+ where
395+ go (TypeFixity _ (Qualified (Just mn') ident) op')
396+ | mn == mn' && op == op' = Just ident
397+ go _ = Nothing
398+
399+ -- Finds the value or data constructor associated with an operator when that
400+ -- declaration is also in the current module.
401+ getValueOpAlias
402+ :: OpName 'ValueOpName
403+ -> Maybe (Either Ident (ProperName 'ConstructorName))
404+ getValueOpAlias op =
405+ listToMaybe (mapMaybe (either go (const Nothing) <=< getFixityDecl) ds)
406+ where
407+ go (ValueFixity _ (Qualified (Just mn') ident) op')
408+ | mn == mn' && op == op' = Just ident
409+ go _ = Nothing
410+
411+ -- Tests the exported `TypeRef` entries with a predicate.
412+ anyTypeRef
413+ :: ((ProperName 'TypeName, Maybe [ProperName 'ConstructorName]) -> Bool)
414+ -> Bool
415+ anyTypeRef f = any (maybe False f . getTypeRef) exps
src/Language/PureScript/Sugar/Operators/Binders.hs+4−5
@@ -1,13 +1,12 @@
11module Language.PureScript.Sugar.Operators.Binders where
22
3−import Prelude ()
43import Prelude.Compat
54
65import Language.PureScript.AST
76import Language.PureScript.Names
87import Language.PureScript.Sugar.Operators.Common
98
10−matchBinderOperators :: [[(Qualified Ident, Associativity)]] -> Binder -> Binder
9+matchBinderOperators :: [[(Qualified (OpName 'ValueOpName), Associativity)]] -> Binder -> Binder
1110matchBinderOperators = matchOperators isBinOp extractOp fromOp reapply id
1211 where
1312
@@ -19,9 +18,9 @@ matchBinderOperators = matchOperators isBinOp extractOp fromOp reapply id
1918 extractOp (BinaryNoParensBinder op l r) = Just (op, l, r)
2019 extractOp _ = Nothing
2120
22− fromOp :: Binder -> Maybe (Qualified Ident)
23− fromOp (OpBinder q@(Qualified _ (Op _))) = Just q
21+ fromOp :: Binder -> Maybe (Qualified (OpName 'ValueOpName))
22+ fromOp (OpBinder q@(Qualified _ (OpName _))) = Just q
2423 fromOp _ = Nothing
2524
26− reapply :: Qualified Ident -> Binder -> Binder -> Binder
25+ reapply :: Qualified (OpName 'ValueOpName) -> Binder -> Binder -> Binder
2726 reapply = BinaryNoParensBinder . OpBinder
src/Language/PureScript/Sugar/Operators/Common.hs+11−16
@@ -1,10 +1,5 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE PatternGuards #-}
4−
51module Language.PureScript.Sugar.Operators.Common where
62
7−import Prelude ()
83import Prelude.Compat
94
105import Control.Monad.State
@@ -33,36 +28,36 @@ parseValue :: P.Parsec (Chain a) () a
3328parseValue = token (either Just (const Nothing)) P.<?> "expression"
3429
3530parseOp
36− :: (a -> (Maybe (Qualified Ident)))
37− -> P.Parsec (Chain a) () (Qualified Ident)
31+ :: (a -> (Maybe (Qualified (OpName nameType))))
32+ -> P.Parsec (Chain a) () (Qualified (OpName nameType))
3833parseOp fromOp = token (either (const Nothing) fromOp) P.<?> "operator"
3934
4035matchOp
41− :: (a -> (Maybe (Qualified Ident)))
42− -> Qualified Ident
36+ :: (a -> (Maybe (Qualified (OpName nameType))))
37+ -> Qualified (OpName nameType)
4338 -> P.Parsec (Chain a) () ()
4439matchOp fromOp op = do
4540 ident <- parseOp fromOp
4641 guard $ ident == op
4742
4843opTable
49− :: [[(Qualified Ident, Associativity)]]
50− -> (a -> Maybe (Qualified Ident))
51− -> (Qualified Ident -> a -> a -> a)
44+ :: [[(Qualified (OpName nameType), Associativity)]]
45+ -> (a -> Maybe (Qualified (OpName nameType)))
46+ -> (Qualified (OpName nameType) -> a -> a -> a)
5247 -> [[P.Operator (Chain a) () Identity a]]
5348opTable ops fromOp reapply =
5449 map (map (\(name, a) -> P.Infix (P.try (matchOp fromOp name) >> return (reapply name)) (toAssoc a))) ops
5550 ++ [[ P.Infix (P.try (parseOp fromOp >>= \ident -> return (reapply ident))) P.AssocLeft ]]
5651
5752matchOperators
58− :: forall a
53+ :: forall a nameType
5954 . Show a
6055 => (a -> Bool)
6156 -> (a -> Maybe (a, a, a))
62− -> (a -> Maybe (Qualified Ident))
63− -> (Qualified Ident -> a -> a -> a)
57+ -> (a -> Maybe (Qualified (OpName nameType)))
58+ -> (Qualified (OpName nameType) -> a -> a -> a)
6459 -> ([[P.Operator (Chain a) () Identity a]] -> P.OperatorTable (Chain a) () Identity a)
65− -> [[(Qualified Ident, Associativity)]]
60+ -> [[(Qualified (OpName nameType), Associativity)]]
6661 -> a
6762 -> a
6863matchOperators isBinOp extractOp fromOp reapply modOpTable ops = parseChains
src/Language/PureScript/Sugar/Operators/Expr.hs+6−10
@@ -1,9 +1,5 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
41module Language.PureScript.Sugar.Operators.Expr where
52
6−import Prelude ()
73import Prelude.Compat
84
95import Data.Functor.Identity
@@ -15,7 +11,7 @@ import Language.PureScript.AST
1511import Language.PureScript.Names
1612import Language.PureScript.Sugar.Operators.Common
1713
18−matchExprOperators :: [[(Qualified Ident, Associativity)]] -> Expr -> Expr
14+matchExprOperators :: [[(Qualified (OpName 'ValueOpName), Associativity)]] -> Expr -> Expr
1915matchExprOperators = matchOperators isBinOp extractOp fromOp reapply modOpTable
2016 where
2117
@@ -27,12 +23,12 @@ matchExprOperators = matchOperators isBinOp extractOp fromOp reapply modOpTable
2723 extractOp (BinaryNoParens op l r) = Just (op, l, r)
2824 extractOp _ = Nothing
2925
30− fromOp :: Expr -> Maybe (Qualified Ident)
31− fromOp (Var q@(Qualified _ (Op _))) = Just q
26+ fromOp :: Expr -> Maybe (Qualified (OpName 'ValueOpName))
27+ fromOp (Op q@(Qualified _ (OpName _))) = Just q
3228 fromOp _ = Nothing
3329
34− reapply :: Qualified Ident -> Expr -> Expr -> Expr
35− reapply op t1 t2 = App (App (Var op) t1) t2
30+ reapply :: Qualified (OpName 'ValueOpName) -> Expr -> Expr -> Expr
31+ reapply op t1 t2 = App (App (Op op) t1) t2
3632
3733 modOpTable
3834 :: [[P.Operator (Chain Expr) () Identity Expr]]
@@ -44,5 +40,5 @@ matchExprOperators = matchOperators isBinOp extractOp fromOp reapply modOpTable
4440 parseTicks :: P.Parsec (Chain Expr) () Expr
4541 parseTicks = token (either (const Nothing) fromOther) P.<?> "infix function"
4642 where
47− fromOther (Var (Qualified _ (Op _))) = Nothing
43+ fromOther (Op _) = Nothing
4844 fromOther v = Just v
src/Language/PureScript/Sugar/Operators/Types.hs+4−5
@@ -1,6 +1,5 @@
11module Language.PureScript.Sugar.Operators.Types where
22
3−import Prelude ()
43import Prelude.Compat
54
65import Language.PureScript.AST
@@ -8,7 +7,7 @@ import Language.PureScript.Names
87import Language.PureScript.Sugar.Operators.Common
98import Language.PureScript.Types
109
11−matchTypeOperators :: [[(Qualified Ident, Associativity)]] -> Type -> Type
10+matchTypeOperators :: [[(Qualified (OpName 'TypeOpName), Associativity)]] -> Type -> Type
1211matchTypeOperators = matchOperators isBinOp extractOp fromOp reapply id
1312 where
1413
@@ -20,9 +19,9 @@ matchTypeOperators = matchOperators isBinOp extractOp fromOp reapply id
2019 extractOp (BinaryNoParensType op l r) = Just (op, l, r)
2120 extractOp _ = Nothing
2221
23− fromOp :: Type -> Maybe (Qualified Ident)
24− fromOp (TypeOp q@(Qualified _ (Op _))) = Just q
22+ fromOp :: Type -> Maybe (Qualified (OpName 'TypeOpName))
23+ fromOp (TypeOp q@(Qualified _ (OpName _))) = Just q
2524 fromOp _ = Nothing
2625
27− reapply :: Qualified Ident -> Type -> Type -> Type
26+ reapply :: Qualified (OpName 'TypeOpName) -> Type -> Type -> Type
2827 reapply = BinaryNoParensType . TypeOp
src/Language/PureScript/Sugar/TypeClasses.hs+11−15
@@ -1,7 +1,3 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−
51-- |
62-- This module implements the desugaring pass which creates type synonyms for type class dictionaries
73-- and dictionary expressions for type class instances.
@@ -12,7 +8,6 @@ module Language.PureScript.Sugar.TypeClasses
128 , superClassDictionaryNames
139 ) where
1410
15−import Prelude ()
1611import Prelude.Compat
1712
1813import Language.PureScript.Crash
@@ -52,7 +47,8 @@ desugarTypeClasses
5247desugarTypeClasses externs = flip evalStateT initialState . traverse desugarModule
5348 where
5449 initialState :: MemberMap
55− initialState = M.fromList (externs >>= \ExternsFile{..} -> mapMaybe (fromExternsDecl efModuleName) efDeclarations)
50+ initialState = M.singleton (ModuleName [ProperName C.prim], ProperName C.partial) ([], [], [])
51+ `M.union` M.fromList (externs >>= \ExternsFile{..} -> mapMaybe (fromExternsDecl efModuleName) efDeclarations)
5652
5753 fromExternsDecl
5854 :: ModuleName
@@ -233,11 +229,11 @@ typeClassDictionaryDeclaration
233229typeClassDictionaryDeclaration name args implies members =
234230 let superclassTypes = superClassDictionaryNames implies `zip`
235231 [ function unit (foldl TypeApp (TypeConstructor (fmap coerceProperName superclass)) tyArgs)
236− | (superclass, tyArgs) <- implies
232+ | (Constraint superclass tyArgs _) <- implies
237233 ]
238234 members' = map (first runIdent . memberToNameAndType) members
239235 mtys = members' ++ superclassTypes
240− in TypeSynonymDeclaration (coerceProperName name) args (TypeApp tyObject $ rowFromList (mtys, REmpty))
236+ in TypeSynonymDeclaration (coerceProperName name) args (TypeApp tyRecord $ rowFromList (mtys, REmpty))
241237
242238typeClassMemberToDictionaryAccessor
243239 :: ModuleName
@@ -249,13 +245,13 @@ typeClassMemberToDictionaryAccessor mn name args (TypeDeclaration ident ty) =
249245 let className = Qualified (Just mn) name
250246 in ValueDeclaration ident Private [] $ Right $
251247 TypedValue False (TypeClassDictionaryAccessor className ident) $
252− moveQuantifiersToFront (quantify (ConstrainedType [(className, map (TypeVar . fst) args)] ty))
248+ moveQuantifiersToFront (quantify (ConstrainedType [Constraint className (map (TypeVar . fst) args) Nothing] ty))
253249typeClassMemberToDictionaryAccessor mn name args (PositionedDeclaration pos com d) =
254250 PositionedDeclaration pos com $ typeClassMemberToDictionaryAccessor mn name args d
255251typeClassMemberToDictionaryAccessor _ _ _ _ = internalError "Invalid declaration in type class definition"
256252
257253unit :: Type
258−unit = TypeApp tyObject REmpty
254+unit = TypeApp tyRecord REmpty
259255
260256typeInstanceDictionaryDeclaration
261257 :: forall m
@@ -273,7 +269,7 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls =
273269
274270 -- Lookup the type arguments and member types for the type class
275271 (args, implies, tyDecls) <-
276− maybe (throwError . errorMessage $ UnknownTypeClass className) return $
272+ maybe (throwError . errorMessage . UnknownName $ fmap TyClassName className) return $
277273 M.lookup (qualify mn className) m
278274
279275 case mapMaybe declName tyDecls \\ mapMaybe declName decls of
@@ -289,11 +285,11 @@ typeInstanceDictionaryDeclaration name mn deps className tys decls =
289285 members <- zip (map typeClassMemberName decls) <$> traverse (memberToValue memberTypes) decls
290286
291287 -- Create the type of the dictionary
292− -- The type is an object type, but depending on type instance dependencies, may be constrained.
293− -- The dictionary itself is an object literal.
288+ -- The type is a record type, but depending on type instance dependencies, may be constrained.
289+ -- The dictionary itself is a record literal.
294290 let superclasses = superClassDictionaryNames implies `zip`
295291 [ Abs (Left (Ident C.__unused)) (SuperClassDictionary superclass tyArgs)
296− | (superclass, suTyArgs) <- implies
292+ | (Constraint superclass suTyArgs _) <- implies
297293 , let tyArgs = map (replaceAllTypeVars (zip (map fst args) tys)) suTyArgs
298294 ]
299295
@@ -330,5 +326,5 @@ typeClassMemberName _ = internalError "typeClassMemberName: Invalid declaration
330326superClassDictionaryNames :: [Constraint] -> [String]
331327superClassDictionaryNames supers =
332328 [ C.__superclass_ ++ showQualified runProperName pn ++ "_" ++ show (index :: Integer)
333− | (index, (pn, _)) <- zip [0..] supers
329+ | (index, Constraint pn _ _) <- zip [0..] supers
334330 ]
src/Language/PureScript/Sugar/TypeClasses/Deriving.hs+38−35
@@ -1,29 +1,23 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE MultiParamTypeClasses #-}
31{-# LANGUAGE OverloadedStrings #-}
4−{-# LANGUAGE PatternGuards #-}
5−{-# LANGUAGE RankNTypes #-}
6−{-# LANGUAGE ScopedTypeVariables #-}
72
83-- |
94-- This module implements the generic deriving elaboration that takes place during desugaring.
105--
116module Language.PureScript.Sugar.TypeClasses.Deriving (deriveInstances) where
127
13−import Prelude ()
148import Prelude.Compat
159
16−import Data.List (foldl', find, sortBy)
17−import Data.Maybe (fromMaybe)
18−import Data.Ord (comparing)
19−
2010import Control.Arrow (second)
2111import Control.Monad (replicateM)
22−import Control.Monad.Supply.Class (MonadSupply)
2312import Control.Monad.Error.Class (MonadError(..))
13+import Control.Monad.Supply.Class (MonadSupply)
14+
15+import Data.List (foldl', find, sortBy)
16+import Data.Maybe (fromMaybe)
17+import Data.Ord (comparing)
2418
25−import Language.PureScript.Crash
2619import Language.PureScript.AST
20+import Language.PureScript.Crash
2721import Language.PureScript.Environment
2822import Language.PureScript.Errors
2923import Language.PureScript.Names
@@ -50,11 +44,11 @@ deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@[ty] Derived
5044 , Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor ty
5145 , mn == fromMaybe mn mn'
5246 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveGeneric mn ds tyCon args
53− | className == Qualified (Just (ModuleName [ ProperName "Prelude" ])) (ProperName "Eq")
47+ | className == Qualified (Just (ModuleName [ ProperName "Data", ProperName "Eq" ])) (ProperName "Eq")
5448 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
5549 , mn == fromMaybe mn mn'
5650 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveEq mn ds tyCon
57− | className == Qualified (Just (ModuleName [ ProperName "Prelude" ])) (ProperName "Ord")
51+ | className == Qualified (Just (ModuleName [ ProperName "Data", ProperName "Ord" ])) (ProperName "Ord")
5852 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
5953 , mn == fromMaybe mn mn'
6054 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveOrd mn ds tyCon
@@ -218,8 +212,8 @@ deriveGeneric mn ds tyConNm dargs = do
218212 = App (lamCase (Ident "r") [ mkRecCase (decomposeRec rec)
219213 , CaseAlternative [NullBinder] (Right mkNothing)
220214 ])
221− (App e (mkPrelVar (Ident "unit")))
222− fromSpineFun e _ = App (mkGenVar (Ident C.fromSpine)) (App e (mkPrelVar (Ident "unit")))
215+ (App e unitVal)
216+ fromSpineFun e _ = App (mkGenVar (Ident C.fromSpine)) (App e unitVal)
223217
224218 mkRecCase :: [(String, Type)] -> CaseAlternative
225219 mkRecCase rs =
@@ -237,10 +231,13 @@ deriveGeneric mn ds tyConNm dargs = do
237231 -- Helpers
238232
239233 liftApplicative :: Expr -> [Expr] -> Expr
240− liftApplicative = foldl' (\x e -> App (App (mkPrelVar (Ident "apply")) x) e)
234+ liftApplicative = foldl' (\x e -> App (App applyFn x) e)
241235
242− mkPrelVar :: Ident -> Expr
243− mkPrelVar = mkVarMn (Just (ModuleName [ProperName C.prelude]))
236+ unitVal :: Expr
237+ unitVal = mkVarMn (Just (ModuleName [ProperName "Data", ProperName "Unit"])) (Ident "unit")
238+
239+ applyFn :: Expr
240+ applyFn = mkVarMn (Just (ModuleName [ProperName "Control", ProperName "Apply"])) (Ident "apply")
244241
245242 mkGenVar :: Ident -> Expr
246243 mkGenVar = mkVarMn (Just (ModuleName [ProperName "Data", ProperName C.generic]))
@@ -265,10 +262,10 @@ deriveEq mn ds tyConNm = do
265262 mkEqFunction _ = internalError "mkEqFunction: expected DataDeclaration"
266263
267264 preludeConj :: Expr -> Expr -> Expr
268− preludeConj = App . App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.conj)))
265+ preludeConj = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "HeytingAlgebra"])) (Ident C.conj)))
269266
270267 preludeEq :: Expr -> Expr -> Expr
271− preludeEq = App . App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.eq)))
268+ preludeEq = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "Eq"])) (Ident C.eq)))
272269
273270 addCatch :: [CaseAlternative] -> [CaseAlternative]
274271 addCatch xs
@@ -326,13 +323,19 @@ deriveOrd mn ds tyConNm = do
326323 | null xs = [catchAll] -- No type constructors
327324 | otherwise = xs
328325 where
329− catchAll = CaseAlternative [NullBinder, NullBinder] (Right (preludeCtor "EQ"))
326+ catchAll = CaseAlternative [NullBinder, NullBinder] (Right (orderingCtor "EQ"))
327+
328+ orderingName :: String -> Qualified (ProperName a)
329+ orderingName = Qualified (Just (ModuleName [ProperName "Data", ProperName "Ordering"])) . ProperName
330+
331+ orderingCtor :: String -> Expr
332+ orderingCtor = Constructor . orderingName
330333
331− preludeCtor :: String -> Expr
332− preludeCtor = Constructor . Qualified (Just (ModuleName [ProperName C.prelude])) . ProperName
334+ orderingBinder :: String -> Binder
335+ orderingBinder name = ConstructorBinder (orderingName name) []
333336
334− preludeCompare :: Expr -> Expr -> Expr
335− preludeCompare = App . App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.compare)))
337+ ordCompare :: Expr -> Expr -> Expr
338+ ordCompare = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "Ord"])) (Ident C.compare)))
336339
337340 mkCtorClauses :: ((ProperName 'ConstructorName, [Type]), Bool) -> m [CaseAlternative]
338341 mkCtorClauses ((ctorName, tys), isLast) = do
@@ -342,11 +345,11 @@ deriveOrd mn ds tyConNm = do
342345 extras | not isLast = [ CaseAlternative [ ConstructorBinder (Qualified (Just mn) ctorName) (replicate (length tys) NullBinder)
343346 , NullBinder
344347 ]
345− (Right (preludeCtor "LT"))
348+ (Right (orderingCtor "LT"))
346349 , CaseAlternative [ NullBinder
347350 , ConstructorBinder (Qualified (Just mn) ctorName) (replicate (length tys) NullBinder)
348351 ]
349− (Right (preludeCtor "GT"))
352+ (Right (orderingCtor "GT"))
350353 ]
351354 | otherwise = []
352355 return $ CaseAlternative [ caseBinder identsL
@@ -359,12 +362,12 @@ deriveOrd mn ds tyConNm = do
359362 caseBinder idents = ConstructorBinder (Qualified (Just mn) ctorName) (map VarBinder idents)
360363
361364 appendAll :: [Expr] -> Expr
362− appendAll [] = preludeCtor "EQ"
365+ appendAll [] = orderingCtor "EQ"
363366 appendAll [x] = x
364− appendAll (x : xs) = Case [x] [ CaseAlternative [ ConstructorBinder (Qualified (Just (ModuleName [ProperName C.prelude])) (ProperName "LT")) [] ]
365− (Right (preludeCtor "LT"))
366− , CaseAlternative [ ConstructorBinder (Qualified (Just (ModuleName [ProperName C.prelude])) (ProperName "GT")) [] ]
367− (Right (preludeCtor "GT"))
367+ appendAll (x : xs) = Case [x] [ CaseAlternative [orderingBinder "LT"]
368+ (Right (orderingCtor "LT"))
369+ , CaseAlternative [orderingBinder "GT"]
370+ (Right (orderingCtor "GT"))
368371 , CaseAlternative [ NullBinder ]
369372 (Right (appendAll xs))
370373 ]
@@ -374,7 +377,7 @@ deriveOrd mn ds tyConNm = do
374377 appendAll
375378 . map (\(str, typ) -> toOrdering (Accessor str l) (Accessor str r) typ)
376379 $ decomposeRec rec
377− toOrdering l r _ = preludeCompare l r
380+ toOrdering l r _ = ordCompare l r
378381
379382findTypeDecl
380383 :: (MonadError MultipleErrors m)
@@ -407,7 +410,7 @@ mkVar :: Ident -> Expr
407410mkVar = mkVarMn Nothing
408411
409412objectType :: Type -> Maybe Type
410−objectType (TypeApp (TypeConstructor (Qualified (Just (ModuleName [ProperName "Prim"])) (ProperName "Object"))) rec) = Just rec
413+objectType (TypeApp (TypeConstructor (Qualified (Just (ModuleName [ProperName "Prim"])) (ProperName "Record"))) rec) = Just rec
411414objectType _ = Nothing
412415
413416decomposeRec :: Type -> [(String, Type)]
src/Language/PureScript/Sugar/TypeDeclarations.hs+28−38
@@ -1,30 +1,13 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Sugar.TypeDeclarations
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−--
111-- |
12−-- This module implements the desugaring pass which replaces top-level type declarations with
13−-- type annotations on the corresponding expression.
2+-- This module implements the desugaring pass which replaces top-level type
3+-- declarations with type annotations on the corresponding expression.
144--
15−-----------------------------------------------------------------------------
16−
17−{-# LANGUAGE FlexibleContexts #-}
18−{-# LANGUAGE ScopedTypeVariables #-}
19−
20−module Language.PureScript.Sugar.TypeDeclarations (
21− desugarTypeDeclarationsModule
22−) where
5+module Language.PureScript.Sugar.TypeDeclarations
6+ ( desugarTypeDeclarationsModule
7+ ) where
238
24−import Prelude ()
259import Prelude.Compat
2610
27−import Control.Monad (forM)
2811import Control.Monad.Error.Class (MonadError(..))
2912
3013import Language.PureScript.AST
@@ -36,38 +19,45 @@ import Language.PureScript.Traversals
3619-- |
3720-- Replace all top level type declarations in a module with type annotations
3821--
39−desugarTypeDeclarationsModule :: forall m. (MonadError MultipleErrors m) => [Module] -> m [Module]
40−desugarTypeDeclarationsModule ms = forM ms $ \(Module ss coms name ds exps) ->
22+desugarTypeDeclarationsModule
23+ :: forall m
24+ . MonadError MultipleErrors m
25+ => Module
26+ -> m Module
27+desugarTypeDeclarationsModule (Module ss coms name ds exps) =
4128 rethrow (addHint (ErrorInModule name)) $
4229 Module ss coms name <$> desugarTypeDeclarations ds <*> pure exps
4330 where
4431
4532 desugarTypeDeclarations :: [Declaration] -> m [Declaration]
46− desugarTypeDeclarations (PositionedDeclaration pos com d : ds) = do
47− (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : ds)
48− return (PositionedDeclaration pos com d' : ds')
49− desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
33+ desugarTypeDeclarations (PositionedDeclaration pos com d : rest) = do
34+ (d' : rest') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : rest)
35+ return (PositionedDeclaration pos com d' : rest')
36+ desugarTypeDeclarations (TypeDeclaration name' ty : d : rest) = do
5037 (_, nameKind, val) <- fromValueDeclaration d
51− desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
38+ desugarTypeDeclarations (ValueDeclaration name' nameKind [] (Right (TypedValue True val ty)) : rest)
5239 where
5340 fromValueDeclaration :: Declaration -> m (Ident, NameKind, Expr)
54− fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
41+ fromValueDeclaration (ValueDeclaration name'' nameKind [] (Right val))
42+ | name' == name'' = return (name'', nameKind, val)
5543 fromValueDeclaration (PositionedDeclaration pos com d') = do
5644 (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
5745 return (ident, nameKind, PositionedValue pos com val)
58− fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
59− desugarTypeDeclarations [TypeDeclaration name _] = throwError . errorMessage $ OrphanTypeDeclaration name
60− desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
46+ fromValueDeclaration _ =
47+ throwError . errorMessage $ OrphanTypeDeclaration name'
48+ desugarTypeDeclarations [TypeDeclaration name' _] =
49+ throwError . errorMessage $ OrphanTypeDeclaration name'
50+ desugarTypeDeclarations (ValueDeclaration name' nameKind bs val : rest) = do
6151 let (_, f, _) = everywhereOnValuesTopDownM return go return
6252 f' (Left gs) = Left <$> mapM (pairM return f) gs
6353 f' (Right v) = Right <$> f v
64− (:) <$> (ValueDeclaration name nameKind bs <$> f' val)
54+ (:) <$> (ValueDeclaration name' nameKind bs <$> f' val)
6555 <*> desugarTypeDeclarations rest
6656 where
67− go (Let ds val') = Let <$> desugarTypeDeclarations ds <*> pure val'
57+ go (Let ds' val') = Let <$> desugarTypeDeclarations ds' <*> pure val'
6858 go other = return other
69− desugarTypeDeclarations (TypeInstanceDeclaration nm deps cls args (ExplicitInstance ds) : rest) =
70− (:) <$> (TypeInstanceDeclaration nm deps cls args . ExplicitInstance <$> desugarTypeDeclarations ds)
59+ desugarTypeDeclarations (TypeInstanceDeclaration nm deps cls args (ExplicitInstance ds') : rest) =
60+ (:) <$> (TypeInstanceDeclaration nm deps cls args . ExplicitInstance <$> desugarTypeDeclarations ds')
7161 <*> desugarTypeDeclarations rest
72− desugarTypeDeclarations (d:ds) = (:) d <$> desugarTypeDeclarations ds
62+ desugarTypeDeclarations (d:rest) = (:) d <$> desugarTypeDeclarations rest
7363 desugarTypeDeclarations [] = return []
src/Language/PureScript/Traversals.hs+27−42
@@ -1,42 +1,27 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.Traversals
4−-- Copyright : (c) 2014 Phil Freeman
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | Common functions for implementing generic traversals
12−--
13−-----------------------------------------------------------------------------
14−
15−module Language.PureScript.Traversals where
16−
17−import Prelude ()
18−import Prelude.Compat
19−
20−fstM :: (Functor f) => (a -> f c) -> (a, b) -> f (c, b)
21−fstM f (a, b) = flip (,) b <$> f a
22−
23−sndM :: (Functor f) => (b -> f c) -> (a, b) -> f (a, c)
24−sndM f (a, b) = (,) a <$> f b
25−
26−thirdM :: (Functor f) => (c -> f d) -> (a, b, c) -> f (a, b, d)
27−thirdM f (a, b, c) = (,,) a b <$> f c
28−
29−pairM :: (Applicative f) => (a -> f c) -> (b -> f d) -> (a, b) -> f (c, d)
30−pairM f g (a, b) = (,) <$> f a <*> g b
31−
32−maybeM :: (Applicative f) => (a -> f b) -> Maybe a -> f (Maybe b)
33−maybeM _ Nothing = pure Nothing
34−maybeM f (Just a) = Just <$> f a
35−
36−eitherM :: (Applicative f) => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
37−eitherM f _ (Left a) = Left <$> f a
38−eitherM _ g (Right b) = Right <$> g b
39−
40−defS :: (Monad m) => st -> val -> m (st, val)
41−defS s val = return (s, val)
42−
1+-- | Common functions for implementing generic traversals
2+module Language.PureScript.Traversals where
3+
4+import Prelude.Compat
5+
6+fstM :: (Functor f) => (a -> f c) -> (a, b) -> f (c, b)
7+fstM f (a, b) = flip (,) b <$> f a
8+
9+sndM :: (Functor f) => (b -> f c) -> (a, b) -> f (a, c)
10+sndM f (a, b) = (,) a <$> f b
11+
12+thirdM :: (Functor f) => (c -> f d) -> (a, b, c) -> f (a, b, d)
13+thirdM f (a, b, c) = (,,) a b <$> f c
14+
15+pairM :: (Applicative f) => (a -> f c) -> (b -> f d) -> (a, b) -> f (c, d)
16+pairM f g (a, b) = (,) <$> f a <*> g b
17+
18+maybeM :: (Applicative f) => (a -> f b) -> Maybe a -> f (Maybe b)
19+maybeM _ Nothing = pure Nothing
20+maybeM f (Just a) = Just <$> f a
21+
22+eitherM :: (Applicative f) => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
23+eitherM f _ (Left a) = Left <$> f a
24+eitherM _ g (Right b) = Right <$> g b
25+
26+defS :: (Monad m) => st -> val -> m (st, val)
27+defS s val = return (s, val)
src/Language/PureScript/TypeChecker.hs+54−103
@@ -1,42 +1,38 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
21{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE PatternGuards #-}
52
63-- |
74-- The top-level type checker, which checks all declarations in a module.
85--
9−module Language.PureScript.TypeChecker (
10− module T,
11− typeCheckModule
12−) where
6+module Language.PureScript.TypeChecker
7+ ( module T
8+ , typeCheckModule
9+ ) where
1310
14−import Prelude ()
1511import Prelude.Compat
1612
17−import Language.PureScript.TypeChecker.Monad as T
18−import Language.PureScript.TypeChecker.Kinds as T
19−import Language.PureScript.TypeChecker.Types as T
20−import Language.PureScript.TypeChecker.Synonyms as T
21−
22−import Data.Maybe
23−import Data.List (nub, nubBy, (\\), sort, group)
24−import Data.Foldable (for_, traverse_)
25−
26−import qualified Data.Map as M
27−
2813import Control.Monad (when, unless, void, forM, forM_)
29−import Control.Monad.Supply.Class (MonadSupply)
30−import Control.Monad.State.Class (MonadState(..), modify)
3114import Control.Monad.Error.Class (MonadError(..))
15+import Control.Monad.State.Class (MonadState(..), modify)
16+import Control.Monad.Supply.Class (MonadSupply)
3217import Control.Monad.Writer.Class (MonadWriter(..))
3318
19+import Data.Foldable (for_, traverse_)
20+import Data.List (nub, nubBy, (\\), sort, group)
21+import Data.Maybe
22+import qualified Data.Map as M
23+
3424import Language.PureScript.AST
3525import Language.PureScript.Crash
3626import Language.PureScript.Environment
3727import Language.PureScript.Errors
3828import Language.PureScript.Kinds
29+import Language.PureScript.Linter
3930import Language.PureScript.Names
31+import Language.PureScript.Traversals
32+import Language.PureScript.TypeChecker.Kinds as T
33+import Language.PureScript.TypeChecker.Monad as T
34+import Language.PureScript.TypeChecker.Synonyms as T
35+import Language.PureScript.TypeChecker.Types as T
4036import Language.PureScript.TypeClassDictionaries
4137import Language.PureScript.Types
4238
@@ -151,6 +147,7 @@ checkTypeClassInstance
151147 -> Type
152148 -> m ()
153149checkTypeClassInstance _ (TypeVar _) = return ()
150+checkTypeClassInstance _ (TypeLevelString _) = return ()
154151checkTypeClassInstance _ (TypeConstructor ctor) = do
155152 env <- getEnv
156153 when (ctor `M.member` typeSynonyms env) . throwError . errorMessage $ TypeSynonymInstance
@@ -187,7 +184,7 @@ typeCheckAll
187184 -> [DeclarationRef]
188185 -> [Declaration]
189186 -> m [Declaration]
190−typeCheckAll moduleName _ ds = traverse go ds <* traverse_ checkFixities ds
187+typeCheckAll moduleName _ = traverse go
191188 where
192189 go :: Declaration -> m Declaration
193190 go (DataDeclaration dtype name args dctors) = do
@@ -227,27 +224,32 @@ typeCheckAll moduleName _ ds = traverse go ds <* traverse_ checkFixities ds
227224 let args' = args `withKinds` kind
228225 addTypeSynonym moduleName name args' ty kind
229226 return $ TypeSynonymDeclaration name args ty
230− go TypeDeclaration{} = internalError "Type declarations should have been removed"
231− go (ValueDeclaration name nameKind [] (Right val)) =
227+ go TypeDeclaration{} =
228+ internalError "Type declarations should have been removed before typeCheckAlld"
229+ go (ValueDeclaration name nameKind [] (Right val)) = do
230+ env <- getEnv
232231 warnAndRethrow (addHint (ErrorInValueDeclaration name)) $ do
232+ val' <- checkExhaustiveExpr env moduleName val
233233 valueIsNotDefined moduleName name
234− [(_, (val', ty))] <- typesOf NonRecursiveBindingGroup moduleName [(name, val)]
234+ [(_, (val'', ty))] <- typesOf NonRecursiveBindingGroup moduleName [(name, val')]
235235 addValue moduleName name ty nameKind
236− return $ ValueDeclaration name nameKind [] $ Right val'
236+ return $ ValueDeclaration name nameKind [] $ Right val''
237237 go ValueDeclaration{} = internalError "Binders were not desugared"
238− go (BindingGroupDeclaration vals) =
238+ go (BindingGroupDeclaration vals) = do
239+ env <- getEnv
239240 warnAndRethrow (addHint (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
240− for_ (map (\(ident, _, _) -> ident) vals) $ \name ->
241− valueIsNotDefined moduleName name
242− tys <- typesOf RecursiveBindingGroup moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
243− vals' <- forM [ (name, val, nameKind, ty)
244− | (name, nameKind, _) <- vals
245− , (name', (val, ty)) <- tys
246− , name == name'
247− ] $ \(name, val, nameKind, ty) -> do
241+ for_ vals $ \(ident, _, _) ->
242+ valueIsNotDefined moduleName ident
243+ vals' <- mapM (thirdM (checkExhaustiveExpr env moduleName)) vals
244+ tys <- typesOf RecursiveBindingGroup moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals'
245+ vals'' <- forM [ (name, val, nameKind, ty)
246+ | (name, nameKind, _) <- vals'
247+ , (name', (val, ty)) <- tys
248+ , name == name'
249+ ] $ \(name, val, nameKind, ty) -> do
248250 addValue moduleName name ty nameKind
249251 return (name, nameKind, val)
250− return $ BindingGroupDeclaration vals'
252+ return $ BindingGroupDeclaration vals''
251253 go (d@(ExternDataDeclaration name kind)) = do
252254 env <- getEnv
253255 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (kind, ExternData) (types env) }
@@ -261,14 +263,14 @@ typeCheckAll moduleName _ ds = traverse go ds <* traverse_ checkFixities ds
261263 Just _ -> throwError . errorMessage $ RedefinedIdent name
262264 Nothing -> putEnv (env { names = M.insert (moduleName, name) (ty, External, Defined) (names env) })
263265 return d
264− go (d@FixityDeclaration{}) = return d
265− go (d@ImportDeclaration{}) = return d
266− go (d@(TypeClassDeclaration pn args implies tys)) = do
266+ go d@FixityDeclaration{} = return d
267+ go d@ImportDeclaration{} = return d
268+ go d@(TypeClassDeclaration pn args implies tys) = do
267269 addTypeClass moduleName pn args implies tys
268270 return d
269271 go (d@(TypeInstanceDeclaration dictName deps className tys body)) = rethrow (addHint (ErrorInInstance className tys)) $ do
270272 traverse_ (checkTypeClassInstance moduleName) tys
271− forM_ deps $ traverse_ (checkTypeClassInstance moduleName) . snd
273+ forM_ deps $ traverse_ (checkTypeClassInstance moduleName) . constraintArgs
272274 checkOrphanInstance dictName className tys
273275 _ <- traverseTypeInstanceBody checkInstanceMembers body
274276 let dict = TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) [] className tys (Just deps)
@@ -277,23 +279,6 @@ typeCheckAll moduleName _ ds = traverse go ds <* traverse_ checkFixities ds
277279 go (PositionedDeclaration pos com d) =
278280 warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> go d
279281
280− checkFixities :: Declaration -> m ()
281− checkFixities (FixityDeclaration _ name (Just (Qualified mn' (AliasValue ident)))) = do
282− ty <- lookupVariable moduleName (Qualified mn' ident)
283− addValue moduleName (Op name) ty Public
284− checkFixities (FixityDeclaration _ name (Just (Qualified mn' (AliasConstructor ctor)))) = do
285− env <- getEnv
286− let alias = Qualified mn' ctor
287− case M.lookup alias (dataConstructors env) of
288− Nothing -> throwError . errorMessage $ UnknownDataConstructor alias Nothing
289− Just (_, _, ty, _) -> addValue moduleName (Op name) ty Public
290− checkFixities (FixityDeclaration _ name Nothing) = do
291− env <- getEnv
292− guardWith (errorMessage (OrphanFixityDeclaration name)) $ M.member (moduleName, Op name) $ names env
293− checkFixities (PositionedDeclaration pos _ d) =
294− warnAndRethrowWithPosition pos $ checkFixities d
295− checkFixities _ = return ()
296−
297282 checkInstanceMembers :: [Declaration] -> m [Declaration]
298283 checkInstanceMembers instDecls = do
299284 let idents = sort . map head . group . map memberName $ instDecls
@@ -348,16 +333,17 @@ typeCheckModule
348333 . (MonadSupply m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
349334 => Module
350335 -> m Module
351−typeCheckModule (Module _ _ _ _ Nothing) = internalError "exports should have been elaborated"
352−typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint (ErrorInModule mn)) $ do
353− modify (\s -> s { checkCurrentModule = Just mn })
354− decls' <- typeCheckAll mn exps decls
355− for_ exps $ \e -> do
356− checkTypesAreExported e
357− checkClassMembersAreExported e
358− checkClassesAreExported e
359− checkNonAliasesAreExported (exportedDataConstructors exps) e
360− return $ Module ss coms mn decls' (Just exps)
336+typeCheckModule (Module _ _ _ _ Nothing) =
337+ internalError "exports should have been elaborated before typeCheckModule"
338+typeCheckModule (Module ss coms mn decls (Just exps)) =
339+ warnAndRethrow (addHint (ErrorInModule mn)) $ do
340+ modify (\s -> s { checkCurrentModule = Just mn })
341+ decls' <- typeCheckAll mn exps decls
342+ for_ exps $ \e -> do
343+ checkTypesAreExported e
344+ checkClassMembersAreExported e
345+ checkClassesAreExported e
346+ return $ Module ss coms mn decls' (Just exps)
361347 where
362348
363349 checkMemberExport :: (Type -> [DeclarationRef]) -> DeclarationRef -> m ()
@@ -415,7 +401,7 @@ typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint
415401 findClasses :: Type -> [DeclarationRef]
416402 findClasses = everythingOnTypes (++) go
417403 where
418− go (ConstrainedType cs _) = mapMaybe (fmap TypeClassRef . extractCurrentModuleClass . fst) cs
404+ go (ConstrainedType cs _) = mapMaybe (fmap TypeClassRef . extractCurrentModuleClass . constraintClass) cs
419405 go _ = []
420406 extractCurrentModuleClass :: Qualified (ProperName 'ClassName) -> Maybe (ProperName 'ClassName)
421407 extractCurrentModuleClass (Qualified (Just mn') name) | mn == mn' = Just name
@@ -436,38 +422,3 @@ typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint
436422 extractMemberName (TypeDeclaration memberName _) = memberName
437423 extractMemberName _ = internalError "Unexpected declaration in typeclass member list"
438424 checkClassMembersAreExported _ = return ()
439−
440− checkNonAliasesAreExported :: [ProperName 'ConstructorName] -> DeclarationRef -> m ()
441− checkNonAliasesAreExported exportedDctors dr@(ValueRef (Op name)) =
442− case listToMaybe (mapMaybe (getAlias getValueAlias name) decls) of
443− Just (Left ident) ->
444− unless (ValueRef ident `elem` exps) $
445− throwError . errorMessage $ TransitiveExportError dr [ValueRef ident]
446− Just (Right ctor) ->
447− unless (ctor `elem` exportedDctors) $
448− throwError . errorMessage $ TransitiveDctorExportError dr ctor
449− _ -> return ()
450− checkNonAliasesAreExported _ dr@(TypeOpRef (Op name)) =
451− case listToMaybe (mapMaybe (getAlias getTypeAlias name) decls) of
452− Just ty ->
453− unless (any (isTypeRefFor ty) exps) $
454− throwError . errorMessage $ TransitiveExportError dr [TypeRef ty Nothing]
455− _ -> return ()
456− where
457− isTypeRefFor :: ProperName 'TypeName -> DeclarationRef -> Bool
458− isTypeRefFor ty (TypeRef ty' _) = ty == ty'
459− isTypeRefFor _ _ = False
460− checkNonAliasesAreExported _ _ = return ()
461−
462− getAlias :: (FixityAlias -> Maybe a) -> String -> Declaration -> Maybe a
463− getAlias match name (PositionedDeclaration _ _ d) = getAlias match name d
464− getAlias match name (FixityDeclaration _ name' (Just (Qualified (Just mn') a)))
465− | Just alias <- match a, name == name' && mn == mn' = Just alias
466− getAlias _ _ _ = Nothing
467−
468− exportedDataConstructors :: [DeclarationRef] -> [ProperName 'ConstructorName]
469− exportedDataConstructors = foldMap extractCtor
470− where
471− extractCtor :: DeclarationRef -> [ProperName 'ConstructorName]
472− extractCtor (TypeRef _ (Just ctors)) = ctors
473− extractCtor _ = []
src/Language/PureScript/TypeChecker/Entailment.hs+20−21
@@ -1,27 +1,25 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE FlexibleContexts #-}
3−
41-- |
52-- Type class entailment
63--
7−module Language.PureScript.TypeChecker.Entailment (Context, replaceTypeClassDictionaries) where
4+module Language.PureScript.TypeChecker.Entailment
5+ ( Context
6+ , replaceTypeClassDictionaries
7+ ) where
88
9−import Prelude ()
109import Prelude.Compat
1110
11+import Control.Monad.Error.Class (MonadError(..))
12+import Control.Monad.State
13+import Control.Monad.Supply.Class (MonadSupply(..))
14+import Control.Monad.Writer
15+
1216import Data.Function (on)
1317import Data.List (minimumBy, sortBy, groupBy)
1418import Data.Maybe (maybeToList, mapMaybe)
1519import qualified Data.Map as M
1620
17−import Control.Arrow (Arrow(..))
18−import Control.Monad.State
19−import Control.Monad.Writer
20−import Control.Monad.Error.Class (MonadError(..))
21−import Control.Monad.Supply.Class (MonadSupply(..))
22−
23−import Language.PureScript.Crash
2421import Language.PureScript.AST
22+import Language.PureScript.Crash
2523import Language.PureScript.Errors
2624import Language.PureScript.Names
2725import Language.PureScript.TypeChecker.Unify
@@ -81,13 +79,13 @@ entails shouldGeneralize moduleName context = solve
8179 findDicts ctx cn = maybe [] M.elems . (>>= M.lookup cn) . flip M.lookup ctx
8280
8381 solve :: Constraint -> StateT Context m (Expr, [(Ident, Constraint)])
84− solve (className, tys) = do
85− (dict, unsolved) <- go 0 className tys
82+ solve con = do
83+ (dict, unsolved) <- go 0 con
8684 return (dictionaryValueToValue dict, unsolved)
8785 where
88− go :: Int -> Qualified (ProperName 'ClassName) -> [Type] -> StateT Context m (DictionaryValue, [(Ident, Constraint)])
89− go work className' tys' | work > 1000 = throwError . errorMessage $ PossiblyInfiniteInstance className' tys'
90− go work className' tys' = do
86+ go :: Int -> Constraint -> StateT Context m (DictionaryValue, [(Ident, Constraint)])
87+ go work (Constraint className' tys' _) | work > 1000 = throwError . errorMessage $ PossiblyInfiniteInstance className' tys'
88+ go work con'@(Constraint className' tys' _) = do
9189 -- Get the inferred constraint context so far, and merge it with the global context
9290 inferred <- get
9391 let instances = do
@@ -104,7 +102,7 @@ entails shouldGeneralize moduleName context = solve
104102 (mkDictionary (tcdName tcd) args)
105103 (tcdPath tcd)
106104 return (match, unsolved)
107− Right unsolved@(unsolvedClassName@(Qualified _ pn), unsolvedTys) -> do
105+ Right unsolved@(Constraint unsolvedClassName@(Qualified _ pn) unsolvedTys _) -> do
108106 -- Generate a fresh name for the unsolved constraint's new dictionary
109107 ident <- freshIdent ("dict" ++ runProperName pn)
110108 let qident = Qualified Nothing ident
@@ -117,8 +115,8 @@ entails shouldGeneralize moduleName context = solve
117115 where
118116
119117 unique :: [(a, TypeClassDictionaryInScope)] -> m (Either (a, TypeClassDictionaryInScope) Constraint)
120− unique [] | shouldGeneralize && all canBeGeneralized tys' = return $ Right (className, tys)
121− | otherwise = throwError . errorMessage $ NoInstanceFound className' tys'
118+ unique [] | shouldGeneralize && all canBeGeneralized tys' = return (Right con')
119+ | otherwise = throwError . errorMessage $ NoInstanceFound con'
122120 unique [a] = return $ Left a
123121 unique tcds | pairwise overlapping (map snd tcds) = do
124122 tell . errorMessage $ OverlappingInstances className' tys' (map (tcdName . snd) tcds)
@@ -148,7 +146,7 @@ entails shouldGeneralize moduleName context = solve
148146 solveSubgoals :: [(String, Type)] -> Maybe [Constraint] -> StateT Context m (Maybe [DictionaryValue], [(Ident, Constraint)])
149147 solveSubgoals _ Nothing = return (Nothing, [])
150148 solveSubgoals subst (Just subgoals) = do
151− zipped <- traverse (uncurry (go (work + 1)) . second (map (replaceAllTypeVars subst))) subgoals
149+ zipped <- traverse (go (work + 1) . mapConstraintArgs (map (replaceAllTypeVars subst))) subgoals
152150 let (dicts, unsolved) = unzip zipped
153151 return (Just dicts, concat unsolved)
154152
@@ -186,6 +184,7 @@ typeHeadsAreEqual _ (TUnknown u1) (TUnknown u2) | u1 == u2 = Just
186184typeHeadsAreEqual _ (Skolem _ s1 _ _) (Skolem _ s2 _ _) | s1 == s2 = Just []
187185typeHeadsAreEqual _ t (TypeVar v) = Just [(v, t)]
188186typeHeadsAreEqual _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
187+typeHeadsAreEqual _ (TypeLevelString s1) (TypeLevelString s2) | s1 == s2 = Just []
189188typeHeadsAreEqual m (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m h1 h2
190189 <*> typeHeadsAreEqual m t1 t2
191190typeHeadsAreEqual _ REmpty REmpty = Just []
src/Language/PureScript/TypeChecker/Kinds.hs+8−12
@@ -1,9 +1,4 @@
1−{-# LANGUAGE MultiParamTypeClasses #-}
21{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE TupleSections #-}
5−{-# LANGUAGE ScopedTypeVariables #-}
6−{-# LANGUAGE RankNTypes #-}
72
83-- |
94-- This module implements the kind checker
@@ -15,16 +10,15 @@ module Language.PureScript.TypeChecker.Kinds
1510 , kindsOfAll
1611 ) where
1712
18−import Prelude ()
1913import Prelude.Compat
2014
21−import qualified Data.Map as M
22−
2315import Control.Arrow (second)
2416import Control.Monad
2517import Control.Monad.Error.Class (MonadError(..))
26−import Control.Monad.Writer.Class (MonadWriter(..))
2718import Control.Monad.State
19+import Control.Monad.Writer.Class (MonadWriter(..))
20+
21+import qualified Data.Map as M
2822
2923import Language.PureScript.Crash
3024import Language.PureScript.Environment
@@ -93,6 +87,7 @@ unifyKinds k1 k2 = do
9387 go k (KUnknown u) = solveKind u k
9488 go Star Star = return ()
9589 go Bang Bang = return ()
90+ go Symbol Symbol = return ()
9691 go (Row k1') (Row k2') = go k1' k2'
9792 go (FunKind k1' k2') (FunKind k3 k4) = do
9893 go k1' k3
@@ -235,7 +230,8 @@ infer' other = (, []) <$> go other
235230 k' <- go ty
236231 unifyKinds k k'
237232 return k'
238− go TypeWildcard = freshKind
233+ go TypeWildcard{} = freshKind
234+ go (TypeLevelString _) = return Symbol
239235 go (TypeVar v) = do
240236 Just moduleName <- checkCurrentModule <$> get
241237 lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
@@ -245,7 +241,7 @@ infer' other = (, []) <$> go other
245241 go (TypeConstructor v) = do
246242 env <- getEnv
247243 case M.lookup v (types env) of
248− Nothing -> throwError . errorMessage $ UnknownTypeConstructor v
244+ Nothing -> throwError . errorMessage . UnknownName $ fmap TyName v
249245 Just (kind, _) -> return kind
250246 go (TypeApp t1 t2) = do
251247 k0 <- freshKind
@@ -262,7 +258,7 @@ infer' other = (, []) <$> go other
262258 unifyKinds k2 (Row k1)
263259 return $ Row k1
264260 go (ConstrainedType deps ty) = do
265− forM_ deps $ \(className, tys) -> do
261+ forM_ deps $ \(Constraint className tys _) -> do
266262 k <- go $ foldl TypeApp (TypeConstructor (fmap coerceProperName className)) tys
267263 unifyKinds k Star
268264 k <- go ty
src/Language/PureScript/TypeChecker/Monad.hs+4−8
@@ -1,7 +1,4 @@
11{-# LANGUAGE FlexibleInstances #-}
2−{-# LANGUAGE RankNTypes #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
4−{-# LANGUAGE FlexibleContexts #-}
52{-# LANGUAGE GADTs #-}
63
74-- |
@@ -9,17 +6,16 @@
96--
107module Language.PureScript.TypeChecker.Monad where
118
12−import Prelude ()
139import Prelude.Compat
1410
15−import Data.Maybe
16−import qualified Data.Map as M
17−
1811import Control.Arrow (second)
19−import Control.Monad.State
2012import Control.Monad.Error.Class (MonadError(..))
13+import Control.Monad.State
2114import Control.Monad.Writer.Class (MonadWriter(..), listen, censor)
2215
16+import Data.Maybe
17+import qualified Data.Map as M
18+
2319import Language.PureScript.Environment
2420import Language.PureScript.Errors
2521import Language.PureScript.Kinds
src/Language/PureScript/TypeChecker/Rows.hs+7−24
@@ -1,35 +1,18 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.TypeChecker.Rows
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-- Functions relating to type checking for rows
133--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE ScopedTypeVariables #-}
17−{-# LANGUAGE FlexibleContexts #-}
18−{-# LANGUAGE CPP #-}
4+module Language.PureScript.TypeChecker.Rows
5+ ( checkDuplicateLabels
6+ ) where
197
20−module Language.PureScript.TypeChecker.Rows (
21− checkDuplicateLabels
22−) where
8+import Prelude.Compat
239
24−import Data.List
25−
26−#if __GLASGOW_HASKELL__ < 710
27−import Control.Applicative
28−#endif
2910import Control.Monad
3011import Control.Monad.Error.Class (MonadError(..))
3112import Control.Monad.State.Class (MonadState(..))
3213
14+import Data.List
15+
3316import Language.PureScript.AST
3417import Language.PureScript.Errors
3518import Language.PureScript.TypeChecker.Monad
@@ -54,7 +37,7 @@ checkDuplicateLabels =
5437 checkDups (TypeApp t1 t2) = checkDups t1 >> checkDups t2
5538 checkDups (ForAll _ t _) = checkDups t
5639 checkDups (ConstrainedType args t) = do
57− mapM_ checkDups $ concatMap snd args
40+ mapM_ checkDups $ concatMap constraintArgs args
5841 checkDups t
5942 checkDups r@RCons{} =
6043 let (ls, _) = rowToList r in
src/Language/PureScript/TypeChecker/Skolems.hs+14−29
@@ -1,45 +1,30 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.TypeChecker.Skolems
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-- Functions relating to skolemization used during typechecking
133--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE FlexibleContexts #-}
17−
18−module Language.PureScript.TypeChecker.Skolems (
19− newSkolemConstant,
20− introduceSkolemScope,
21− newSkolemScope,
22− skolemize,
23− skolemizeTypesInValue,
24− skolemEscapeCheck
25−) where
4+module Language.PureScript.TypeChecker.Skolems
5+ ( newSkolemConstant
6+ , introduceSkolemScope
7+ , newSkolemScope
8+ , skolemize
9+ , skolemizeTypesInValue
10+ , skolemEscapeCheck
11+ ) where
2612
27−import Prelude ()
2813import Prelude.Compat
2914
30−import Data.List (nub, (\\))
31−import Data.Monoid
32−import Data.Functor.Identity (Identity(), runIdentity)
33−
3415import Control.Monad.Error.Class (MonadError(..))
3516import Control.Monad.State.Class (MonadState(..), gets, modify)
3617
37−import Language.PureScript.Crash
18+import Data.Functor.Identity (Identity(), runIdentity)
19+import Data.List (nub, (\\))
20+import Data.Monoid
21+
3822import Language.PureScript.AST
23+import Language.PureScript.Crash
3924import Language.PureScript.Errors
25+import Language.PureScript.Traversals (defS)
4026import Language.PureScript.TypeChecker.Monad
4127import Language.PureScript.Types
42−import Language.PureScript.Traversals (defS)
4328
4429-- |
4530-- Generate a new skolem constant
src/Language/PureScript/TypeChecker/Subsumption.hs+9−25
@@ -1,36 +1,20 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.TypeChecker.Subsumption
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-- Subsumption checking
133--
14−-----------------------------------------------------------------------------
4+module Language.PureScript.TypeChecker.Subsumption
5+ ( subsumes
6+ ) where
157
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE CPP #-}
8+import Prelude.Compat
189
19−module Language.PureScript.TypeChecker.Subsumption (
20− subsumes
21−) where
10+import Control.Monad.Error.Class (MonadError(..))
11+import Control.Monad.State.Class (MonadState(..))
2212
2313import Data.List (sortBy)
2414import Data.Ord (comparing)
2515
26−#if __GLASGOW_HASKELL__ < 710
27−import Control.Applicative
28−#endif
29−import Control.Monad.Error.Class (MonadError(..))
30−import Control.Monad.State.Class (MonadState(..))
31−
32−import Language.PureScript.Crash
3316import Language.PureScript.AST
17+import Language.PureScript.Crash
3418import Language.PureScript.Environment
3519import Language.PureScript.Errors
3620import Language.PureScript.TypeChecker.Monad
@@ -69,7 +53,7 @@ subsumes' val ty1 (KindedType ty2 _) =
6953subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
7054 dicts <- getTypeClassDictionaries
7155 subsumes' (Just $ foldl App val (map (flip TypeClassDictionary dicts) constraints)) ty1 ty2
72−subsumes' val (TypeApp f1 r1) (TypeApp f2 r2) | f1 == tyObject && f2 == tyObject = do
56+subsumes' val (TypeApp f1 r1) (TypeApp f2 r2) | f1 == tyRecord && f2 == tyRecord = do
7357 let
7458 (ts1, r1') = rowToList r1
7559 (ts2, r2') = rowToList r2
@@ -96,7 +80,7 @@ subsumes' val (TypeApp f1 r1) (TypeApp f2 r2) | f1 == tyObject && f2 == tyObject
9680 REmpty -> throwError . errorMessage $ PropertyIsMissing p2
9781 _ -> unifyTypes r1' (RCons p2 ty2 rest)
9882 go ((p1, ty1) : ts1) ts2 rest r2'
99−subsumes' val ty1 ty2@(TypeApp obj _) | obj == tyObject = subsumes val ty2 ty1
83+subsumes' val ty1 ty2@(TypeApp obj _) | obj == tyRecord = subsumes val ty2 ty1
10084subsumes' val ty1 ty2 = do
10185 unifyTypes ty1 ty2
10286 return val
src/Language/PureScript/TypeChecker/Synonyms.hs+8−24
@@ -1,36 +1,20 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.TypeChecker.Synonyms
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
1+{-# LANGUAGE GADTs #-}
2+
113-- |
124-- Functions for replacing fully applied type synonyms
135--
14−-----------------------------------------------------------------------------
15−
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE MultiParamTypeClasses #-}
18−{-# LANGUAGE PatternGuards #-}
19−{-# LANGUAGE GADTs #-}
6+module Language.PureScript.TypeChecker.Synonyms
7+ ( replaceAllTypeSynonyms
8+ ) where
209
21−module Language.PureScript.TypeChecker.Synonyms (
22− replaceAllTypeSynonyms
23−) where
24−
25−import Prelude ()
2610import Prelude.Compat
2711
28−import Data.Maybe (fromMaybe)
29−import qualified Data.Map as M
30−
3112import Control.Monad.Error.Class (MonadError(..))
3213import Control.Monad.State
3314
15+import Data.Maybe (fromMaybe)
16+import qualified Data.Map as M
17+
3418import Language.PureScript.Environment
3519import Language.PureScript.Errors
3620import Language.PureScript.TypeChecker.Monad
src/Language/PureScript/TypeChecker/Types.hs+39−39

This diff is too big to show here.

src/Language/PureScript/TypeChecker/Unify.hs+30−46

This diff is too big to show here.

src/Language/PureScript/TypeClassDictionaries.hs+2

This diff is too big to show here.

src/Language/PureScript/Types.hs+61−74

This diff is too big to show here.

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

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+8−1

This diff is too big to show here.

tests/Language/PureScript/Ide/FilterSpec.hs+1−1

This diff is too big to show here.

tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+5−12

This diff is too big to show here.

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

This diff is too big to show here.

tests/Language/PureScript/Ide/Integration.hs+59−22

This diff is too big to show here.

tests/Language/PureScript/Ide/MatcherSpec.hs+9−17

This diff is too big to show here.

tests/Language/PureScript/Ide/RebuildSpec.hs+8−17

This diff is too big to show here.

tests/Language/PureScript/Ide/ReexportsSpec.hs+6−3

This diff is too big to show here.

tests/Language/PureScript/IdeSpec.hs+1−1

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+1−1

This diff is too big to show here.

tests/TestPsci.hs+24−46

This diff is too big to show here.

tests/TestUtils.hs+43−18

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/RebuildSpecWithHiddenIdent.pursnew file+6

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.