Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better error reporting in the CLI #32

Merged
merged 8 commits into from
Mar 24, 2020
4 changes: 2 additions & 2 deletions cli/morphir-elm-make.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ make(program.projectDir, program.output)
if (err.code == 'ENOENT') {
console.error(`Could not find file at '${err.path}'`)
} else {
console.error(err)
console.error(JSON.stringify(err))
}
process.exit(1)
})
Expand All @@ -43,7 +43,7 @@ async function make(projectDir, output) {
const morphirJsonPath = path.join(projectDir, 'morphir.json')
const morphirJsonContent = await readFile(morphirJsonPath)
const morphirJson = JSON.parse(morphirJsonContent.toString())
const sourceFiles = await readElmSources(morphirJson.sourceDirectory)
const sourceFiles = await readElmSources(path.join(projectDir, morphirJson.sourceDirectory))
const packageDef = await packageDefinitionFromSource(morphirJson, sourceFiles)
if (output) {
console.log(`Writing file ${output}.`)
Expand Down
4 changes: 2 additions & 2 deletions cli/src/Morphir/Elm/EncodersCLI.elm
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ encoderDeclarations sourceFiles =

getEncodersFromModuleDef : AccessControlled (Advanced.Definition SourceLocation) -> List (Node S.Declaration)
getEncodersFromModuleDef accessCtrlModuleDef =
case accessCtrlModuleDef of
Public { types, values } ->
case ( accessCtrlModuleDef.access, accessCtrlModuleDef.value ) of
( Public, { types, values } ) ->
Dict.toList types
|> List.map
(\typeNameAndDef ->
Expand Down
58 changes: 52 additions & 6 deletions src/Morphir/Elm/Frontend.elm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Morphir.IR.Advanced.Value as Value exposing (Value)
import Morphir.IR.FQName as FQName exposing (FQName, fQName)
import Morphir.IR.Name as Name exposing (Name)
import Morphir.IR.Path as Path exposing (Path)
import Morphir.JsonExtra as JsonExtra
import Morphir.ResultList as ResultList
import Morphir.Rewrite as Rewrite
import Parser
Expand Down Expand Up @@ -56,6 +57,12 @@ type alias SourceFile =
}


encodeSourceFile : SourceFile -> Encode.Value
encodeSourceFile sourceFile =
Encode.object
[ ( "path", Encode.string sourceFile.path ) ]


type alias ParsedFile =
{ sourceFile : SourceFile
, rawFile : RawFile
Expand All @@ -74,26 +81,50 @@ type alias SourceLocation =
}


encodeSourceLocation : SourceLocation -> Encode.Value
encodeSourceLocation sourceLocation =
Encode.object
[ ( "source", encodeSourceFile sourceLocation.source )
, ( "range", encodeContentRange sourceLocation.range )
]


type alias ContentRange =
{ start : ContentLocation
, end : ContentLocation
}


encodeContentRange : ContentRange -> Encode.Value
encodeContentRange contentRange =
Encode.object
[ ( "start", encodeContentLocation contentRange.start )
, ( "end", encodeContentLocation contentRange.end )
]


type alias ContentLocation =
{ row : Int
, column : Int
}


encodeContentLocation : ContentLocation -> Encode.Value
encodeContentLocation contentLocation =
Encode.object
[ ( "row", Encode.int contentLocation.row )
, ( "column", Encode.int contentLocation.column )
]


type alias Errors =
List Error


type Error
= ParseError String (List Parser.DeadEnd)
| CyclicModules (DAG (List String))
| ResolveError Resolve.Error
| ResolveError SourceLocation Resolve.Error


encodeError : Error -> Encode.Value
Expand All @@ -109,9 +140,10 @@ encodeError error =
[ ( "$type", Encode.string "CyclicModules" )
]

ResolveError _ ->
Encode.object
[ ( "$type", Encode.string "ResolveError" )
ResolveError sourceLocation resolveError ->
JsonExtra.encodeConstructor "ResolveError"
[ encodeSourceLocation sourceLocation
, Resolve.encodeError resolveError
]


Expand Down Expand Up @@ -259,7 +291,8 @@ mapProcessedFile currentPackagePath processedFile modulesSoFar =

valuesResult : Result Errors (Dict Name (AccessControlled (Value.Definition SourceLocation)))
valuesResult =
Ok Dict.empty
mapDeclarationsToValue processedFile.parsedFile.sourceFile moduleExpose (processedFile.file.declarations |> List.map Node.value)
|> Result.map Dict.fromList

moduleResult : Result Errors (Module.Definition SourceLocation)
moduleResult =
Expand Down Expand Up @@ -420,6 +453,19 @@ mapDeclarationsToType sourceFile expose decls =
|> Result.mapError List.concat


mapDeclarationsToValue : SourceFile -> Exposing -> List Declaration -> Result Errors (List ( Name, AccessControlled (Value.Definition SourceLocation) ))
mapDeclarationsToValue sourceFile expose decls =
decls
|> List.filterMap
(\decl ->
case decl of
_ ->
Nothing
)
|> ResultList.toResult
|> Result.mapError List.concat


mapTypeAnnotation : SourceFile -> Node TypeAnnotation -> Result Errors (Type SourceLocation)
mapTypeAnnotation sourceFile (Node range typeAnnotation) =
let
Expand Down Expand Up @@ -528,7 +574,7 @@ resolveLocalTypes packagePath modulePath moduleResolver moduleDef =
(\resolvedFullName ->
Type.Reference resolvedFullName args sourceLocation
)
|> Result.mapError ResolveError
|> Result.mapError (ResolveError sourceLocation)
|> Just

_ ->
Expand Down
50 changes: 47 additions & 3 deletions src/Morphir/Elm/Frontend/Resolve.elm
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
module Morphir.Elm.Frontend.Resolve exposing (Error(..), ModuleResolver, PackageResolver, createModuleResolver, createPackageResolver)
module Morphir.Elm.Frontend.Resolve exposing (Error(..), ModuleResolver, PackageResolver, createModuleResolver, createPackageResolver, encodeError)

import Dict exposing (Dict)
import Elm.Syntax.Exposing exposing (Exposing(..), TopLevelExpose(..))
import Elm.Syntax.Import exposing (Import)
import Elm.Syntax.Node as Node exposing (Node(..))
import Json.Encode as Encode
import Morphir.IR.Advanced.Module as Module
import Morphir.IR.Advanced.Package as Package
import Morphir.IR.Advanced.Type as Type
import Morphir.IR.FQName exposing (FQName, fQName)
import Morphir.IR.Name as Name exposing (Name)
import Morphir.IR.Path as Path exposing (Path)
import Morphir.JsonExtra as JsonExtra
import Morphir.Pattern exposing (matchAny)
import Set exposing (Set)

Expand All @@ -23,8 +25,7 @@ type alias LocalName =


type Error
= ModuleDoesNotExpose ModuleName LocalName
| CouldNotDecompose ModuleName
= CouldNotDecompose ModuleName
| CouldNotFindLocalName LocalName
| CouldNotFindName Path Path Name
| CouldNotFindModule Path Path
Expand All @@ -34,6 +35,49 @@ type Error
| PackageNotPrefixOfModule Path Path


encodeError : Error -> Encode.Value
encodeError error =
case error of
CouldNotDecompose moduleName ->
JsonExtra.encodeConstructor "CouldNotDecompose"
[ Encode.string (String.join "." moduleName) ]

CouldNotFindLocalName localName ->
JsonExtra.encodeConstructor "CouldNotFindLocalName"
[ Encode.string localName ]

CouldNotFindName packagePath modulePath localName ->
JsonExtra.encodeConstructor "CouldNotFindName"
[ packagePath |> Path.toString Name.toTitleCase "." |> Encode.string
, modulePath |> Path.toString Name.toTitleCase "." |> Encode.string
, localName |> Name.toTitleCase |> Encode.string
]

CouldNotFindModule packagePath modulePath ->
JsonExtra.encodeConstructor "CouldNotFindModule"
[ packagePath |> Path.toString Name.toTitleCase "." |> Encode.string
, modulePath |> Path.toString Name.toTitleCase "." |> Encode.string
]

CouldNotFindPackage packagePath ->
JsonExtra.encodeConstructor "CouldNotFindPackage"
[ packagePath |> Path.toString Name.toTitleCase "." |> Encode.string ]

ModuleNotImported moduleName ->
JsonExtra.encodeConstructor "ModuleNotImported"
[ Encode.string (String.join "." moduleName) ]

AliasNotFound alias ->
JsonExtra.encodeConstructor "AliasNotFound"
[ Encode.string alias ]

PackageNotPrefixOfModule packagePath modulePath ->
JsonExtra.encodeConstructor "PackageNotPrefixOfModule"
[ packagePath |> Path.toString Name.toTitleCase "." |> Encode.string
, modulePath |> Path.toString Name.toTitleCase "." |> Encode.string
]


type alias ModuleResolver =
{ resolveType : ModuleName -> LocalName -> Result Error FQName
, resolveValue : ModuleName -> LocalName -> Result Error FQName
Expand Down
12 changes: 11 additions & 1 deletion src/Morphir/IR/Advanced/Value.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Morphir.IR.Advanced.Value exposing
, Declaration
, Definition(..), typedDefinition, untypedDefinition
, encodeValue, encodeDeclaration, encodeDefinition
, mapDeclaration, mapDefinition, mapValueExtra
, getDefinitionBody, mapDeclaration, mapDefinition, mapValueExtra
)

{-| This module contains the building blocks of values in the Morphir IR.
Expand Down Expand Up @@ -137,6 +137,16 @@ type Definition extra
| UntypedDefinition (List Name) (Value extra)


getDefinitionBody : Definition extra -> Value extra
getDefinitionBody def =
case def of
TypedDefinition _ _ body ->
body

UntypedDefinition _ body ->
body



-- definitionToDeclaration : Definition extra -> Maybe (Declaration extra)
-- definitionToDeclaration def =
Expand Down