Skip to content

Commit

Permalink
One step closer to singularity (#69)
Browse files Browse the repository at this point in the history
* Added missing module declarations. #37

* Process only those modules that are reachable from exposed ones. Remove package path from module names. #21

* Renaming concepts based on review feedback. #41

* Moved Advanced module up a level. #43

* Removed unused unindent function.

* Moved name to SDK.

* Added missing module to SDK.

* Partial implementation of value mapping.

* Ignore all generated JS.

* Change extra arg position and naming. #46, #25

* Change extra arg position and naming. #46, #25

* Removed remaining references to extra. #5

* Change extra arg position. #46, #25, #5

* Added more coverage. #46, #25, #5

* Changes suggested in the PR. #46, #25, #5

* Use more explicit names.

* All patterns supported.

* Pattern-match supported.

* Added support for SDK operators. #52

* Fix compile errors.

* Prepare Elm module publishing. #2

* Fix repo name. #2

* Support for let expressions. #54

* Simple join implementations. #64

* Refactoring to make the code more organized.

* Refactoring to make the code more organized.

* Prepare value mapping utils. #53

* More descriptive naming.

* More descriptive naming.

* Removed unused function

* Better naming

* Added utility function and removed unused one.

* Added variable resolution.

* Hooked up variable resolution and updated tests. #53

* Completed reference resolution. #53

* Added missing docs and refactored. #68

* Document and refactor driven by the goal to process Morphir using Morphir. #68
  • Loading branch information
AttilaMihaly committed Apr 27, 2020
1 parent f92b5f1 commit 7731cb3
Show file tree
Hide file tree
Showing 41 changed files with 1,794 additions and 1,739 deletions.
9 changes: 8 additions & 1 deletion elm.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@
"license": "Apache-2.0",
"version": "1.0.0",
"exposed-modules": [
"Morphir.SDK.StatefulApp"
"Morphir.SDK.StatefulApp",
"Morphir.IR.Name",
"Morphir.IR.Path",
"Morphir.IR.QName",
"Morphir.IR.FQName",
"Morphir.IR.AccessControlled",
"Morphir.IR.Type",
"Morphir.IR.Value"
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {
Expand Down
11 changes: 9 additions & 2 deletions morphir.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
"name": "Morphir",
"sourceDirectory": "src",
"exposedModules": [
"IR.Advanced.Type",
"IR.Advanced.Value"
"IR.Name",
"IR.Path",
"IR.QName",
"IR.FQName",
"IR.AccessControlled",
"IR.Type",
"IR.Value",
"IR.Module",
"IR.Package"
]
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "Elm bindings for Morphir",
"scripts": {
"test": "elm-test",
"make-cli": "cd cli && elm make src/Morphir/Elm/CLI.elm --output Morphir.Elm.CLI.js --optimize && elm make src/Morphir/Elm/DaprCLI.elm --output Morphir.Elm.DaprCLI.js --optimize"
"make-cli": "cd cli && elm make src/Morphir/Elm/CLI.elm --output Morphir.Elm.CLI.js --optimize && elm make src/Morphir/Elm/DaprCLI.elm --output Morphir.Elm.DaprCLI.js --optimize",
"make-cli-dev": "cd cli && elm make src/Morphir/Elm/CLI.elm --output Morphir.Elm.CLI.js && elm make src/Morphir/Elm/DaprCLI.elm --output Morphir.Elm.DaprCLI.js"
},
"repository": {
"type": "git",
Expand Down
219 changes: 140 additions & 79 deletions src/Morphir/Elm/Frontend.elm

Large diffs are not rendered by default.

56 changes: 44 additions & 12 deletions src/Morphir/Elm/Frontend/Resolve.elm
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@ type alias PackageResolver =
defaultImports : List Import
defaultImports =
let
importExplicit : ModuleName -> Maybe ModuleName -> List TopLevelExpose -> Import
importExplicit : ModuleName -> Maybe String -> List TopLevelExpose -> Import
importExplicit moduleName maybeAlias exposingList =
Import
(Node emptyRange moduleName)
(maybeAlias
|> Maybe.map (Node emptyRange)
|> Maybe.map (List.singleton >> Node emptyRange)
)
(exposingList
|> List.map (Node emptyRange)
Expand All @@ -111,16 +111,25 @@ defaultImports =
)
in
[ importExplicit [ "Morphir", "SDK", "Bool" ] Nothing [ TypeOrAliasExpose "Bool" ]
, importExplicit [ "Morphir", "SDK", "Char" ] Nothing [ TypeOrAliasExpose "Char" ]
, importExplicit [ "Morphir", "SDK", "Char" ] (Just "Char") [ TypeOrAliasExpose "Char" ]
, importExplicit [ "Morphir", "SDK", "Int" ] Nothing [ TypeOrAliasExpose "Int" ]
, importExplicit [ "Morphir", "SDK", "Float" ] Nothing [ TypeOrAliasExpose "Float" ]
, importExplicit [ "Morphir", "SDK", "String" ] Nothing [ TypeOrAliasExpose "String" ]
, importExplicit [ "Morphir", "SDK", "Maybe" ] Nothing [ TypeOrAliasExpose "Maybe" ]
, importExplicit [ "Morphir", "SDK", "Result" ] Nothing [ TypeOrAliasExpose "Result" ]
, importExplicit [ "Morphir", "SDK", "List" ] Nothing [ TypeOrAliasExpose "List" ]
, importExplicit [ "Morphir", "SDK", "String" ] (Just "String") [ TypeOrAliasExpose "String" ]
, importExplicit [ "Morphir", "SDK", "Maybe" ] (Just "Maybe") [ TypeOrAliasExpose "Maybe" ]
, importExplicit [ "Morphir", "SDK", "Result" ] (Just "Result") [ TypeOrAliasExpose "Result" ]
, importExplicit [ "Morphir", "SDK", "List" ] (Just "List") [ TypeOrAliasExpose "List" ]
, importExplicit [ "Morphir", "SDK", "Regex" ] (Just "Regex") [ TypeOrAliasExpose "Regex" ]
, importExplicit [ "Morphir", "SDK", "Tuple" ] (Just "Tuple") []
]


moduleMapping : Dict ModuleName ModuleName
moduleMapping =
Dict.fromList
[ ( [ "Dict" ], [ "Morphir", "SDK", "Dict" ] )
]


createPackageResolver : Dict Path (Package.Specification a) -> Path -> Dict Path (Module.Specification a) -> PackageResolver
createPackageResolver dependencies currentPackagePath currentPackageModules =
let
Expand Down Expand Up @@ -220,9 +229,13 @@ createPackageResolver dependencies currentPackagePath currentPackageModules =
decomposeModuleName : ModuleName -> Result Error ( Path, Path )
decomposeModuleName moduleName =
let
morphirModuleName : ModuleName
morphirModuleName =
moduleMapping |> Dict.get moduleName |> Maybe.withDefault moduleName

suppliedModulePath : Path
suppliedModulePath =
moduleName
morphirModuleName
|> List.map Name.fromString

matchModuleToPackagePath modulePath packagePath =
Expand All @@ -240,14 +253,31 @@ createPackageResolver dependencies currentPackagePath currentPackageModules =
|> List.filterMap (matchModuleToPackagePath suppliedModulePath)
|> List.head
)
|> Result.fromMaybe (CouldNotDecompose moduleName)
|> Result.fromMaybe (CouldNotDecompose morphirModuleName)
in
PackageResolver currentPackagePath ctorNames exposesType exposesValue decomposeModuleName


createModuleResolver : PackageResolver -> List Import -> Path -> Module.Definition a -> ModuleResolver
createModuleResolver packageResolver explicitImports currenctModulePath moduleDef =
createModuleResolver packageResolver elmImports currenctModulePath moduleDef =
let
explicitImports : List Import
explicitImports =
elmImports
|> List.map
(\imp ->
{ imp
| moduleName =
imp.moduleName
|> Node.map
(\moduleName ->
moduleMapping
|> Dict.get moduleName
|> Maybe.withDefault moduleName
)
}
)

imports : List Import
imports =
defaultImports ++ explicitImports
Expand Down Expand Up @@ -441,11 +471,13 @@ createModuleResolver packageResolver explicitImports currenctModulePath moduleDe
resolveExternally isType elmModuleName elmLocalName

resolveType : ModuleName -> LocalName -> Result Error FQName
resolveType =
resolveType moduleName =
resolve True
(moduleMapping |> Dict.get moduleName |> Maybe.withDefault moduleName)

resolveValue : ModuleName -> LocalName -> Result Error FQName
resolveValue =
resolveValue moduleName =
resolve False
(moduleMapping |> Dict.get moduleName |> Maybe.withDefault moduleName)
in
ModuleResolver resolveType resolveValue
57 changes: 9 additions & 48 deletions src/Morphir/IR/AccessControlled.elm
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
module Morphir.IR.AccessControlled exposing
( AccessControlled
( AccessControlled, Access(..)
, public, private
, withPublicAccess, withPrivateAccess
, decodeAccessControlled, encodeAccessControlled
, Access(..), map
, map
)

{-| Module to manage access to a node in the IR. This is only used to declare access levels
not to enforce them. Enforcement can be done through the helper functions
[withPublicAccess](#withPublicAccess) and [withPrivateAccess](#withPrivateAccess) but it's
up to the consumer of the API to call the righ function.
@docs AccessControlled
@docs AccessControlled, Access
# Creation
Expand All @@ -24,15 +23,12 @@ up to the consumer of the API to call the righ function.
@docs withPublicAccess, withPrivateAccess
# Serialization
# Transform
@docs decodeAccessControlled, encodeAccessControlled
@docs map
-}

import Json.Decode as Decode
import Json.Encode as Encode


{-| Type that represents different access levels.
-}
Expand All @@ -42,6 +38,8 @@ type alias AccessControlled a =
}


{-| Public or private access.
-}
type Access
= Public
| Private
Expand Down Expand Up @@ -95,45 +93,8 @@ withPrivateAccess ac =
ac.value


{-| Apply a function to the access controlled value but keep the access unchanged.
-}
map : (a -> b) -> AccessControlled a -> AccessControlled b
map f ac =
AccessControlled ac.access (f ac.value)


{-| Encode AccessControlled to JSON.
-}
encodeAccessControlled : (a -> Encode.Value) -> AccessControlled a -> Encode.Value
encodeAccessControlled encodeValue ac =
case ac.access of
Public ->
Encode.list identity
[ Encode.string "Public"
, encodeValue ac.value
]

Private ->
Encode.list identity
[ Encode.string "Private"
, encodeValue ac.value
]


{-| Decode AccessControlled from JSON.
-}
decodeAccessControlled : Decode.Decoder a -> Decode.Decoder (AccessControlled a)
decodeAccessControlled decodeValue =
Decode.index 0 Decode.string
|> Decode.andThen
(\tag ->
case tag of
"Public" ->
Decode.map (AccessControlled Public)
(Decode.index 1 decodeValue)

"Private" ->
Decode.map (AccessControlled Private)
(Decode.index 1 decodeValue)

other ->
Decode.fail <| "Unknown access controlled type: " ++ other
)
45 changes: 45 additions & 0 deletions src/Morphir/IR/AccessControlled/Codec.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module Morphir.IR.AccessControlled.Codec exposing (..)

{-| Encode AccessControlled to JSON.
-}

import Json.Decode as Decode
import Json.Encode as Encode
import Morphir.IR.AccessControlled exposing (Access(..), AccessControlled)


encodeAccessControlled : (a -> Encode.Value) -> AccessControlled a -> Encode.Value
encodeAccessControlled encodeValue ac =
case ac.access of
Public ->
Encode.list identity
[ Encode.string "Public"
, encodeValue ac.value
]

Private ->
Encode.list identity
[ Encode.string "Private"
, encodeValue ac.value
]


{-| Decode AccessControlled from JSON.
-}
decodeAccessControlled : Decode.Decoder a -> Decode.Decoder (AccessControlled a)
decodeAccessControlled decodeValue =
Decode.index 0 Decode.string
|> Decode.andThen
(\tag ->
case tag of
"Public" ->
Decode.map (AccessControlled Public)
(Decode.index 1 decodeValue)

"Private" ->
Decode.map (AccessControlled Private)
(Decode.index 1 decodeValue)

other ->
Decode.fail <| "Unknown access controlled type: " ++ other
)
54 changes: 3 additions & 51 deletions src/Morphir/IR/FQName.elm
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
module Morphir.IR.FQName exposing
( FQName(..), fQName, fromQName, getPackagePath, getModulePath, getLocalName
, fuzzFQName
, encodeFQName, decodeFQName
)
module Morphir.IR.FQName exposing (FQName(..), fQName, fromQName, getPackagePath, getModulePath, getLocalName)

{-| Module to work with fully-qualified names. A qualified name is a combination of a package path, a module path and a local name.
@docs FQName, fQName, fromQName, getPackagePath, getModulePath, getLocalName
# Property Testing
@docs fuzzFQName
# Serialization
@docs encodeFQName, decodeFQName
-}

import Fuzz exposing (Fuzzer)
import Json.Decode as Decode
import Json.Encode as Encode
import Morphir.IR.Name exposing (Name, decodeName, encodeName, fuzzName)
import Morphir.IR.Path exposing (Path, decodePath, encodePath, fuzzPath)
import Morphir.IR.Name exposing (Name)
import Morphir.IR.Path exposing (Path)
import Morphir.IR.QName as QName exposing (QName)


Expand Down Expand Up @@ -67,34 +50,3 @@ getModulePath (FQName _ m _) =
getLocalName : FQName -> Name
getLocalName (FQName _ _ l) =
l


{-| FQName fuzzer.
-}
fuzzFQName : Fuzzer FQName
fuzzFQName =
Fuzz.map3 FQName
fuzzPath
fuzzPath
fuzzName


{-| Encode a fully-qualified name to JSON.
-}
encodeFQName : FQName -> Encode.Value
encodeFQName (FQName packagePath modulePath localName) =
Encode.list identity
[ packagePath |> encodePath
, modulePath |> encodePath
, localName |> encodeName
]


{-| Decode a fully-qualified name from JSON.
-}
decodeFQName : Decode.Decoder FQName
decodeFQName =
Decode.map3 FQName
(Decode.index 0 decodePath)
(Decode.index 1 decodePath)
(Decode.index 2 decodeName)
29 changes: 29 additions & 0 deletions src/Morphir/IR/FQName/Codec.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Morphir.IR.FQName.Codec exposing (..)

{-| Encode a fully-qualified name to JSON.
-}

import Json.Decode as Decode
import Json.Encode as Encode
import Morphir.IR.FQName exposing (FQName(..))
import Morphir.IR.Name.Codec exposing (decodeName, encodeName)
import Morphir.IR.Path.Codec exposing (decodePath, encodePath)


encodeFQName : FQName -> Encode.Value
encodeFQName (FQName packagePath modulePath localName) =
Encode.list identity
[ packagePath |> encodePath
, modulePath |> encodePath
, localName |> encodeName
]


{-| Decode a fully-qualified name from JSON.
-}
decodeFQName : Decode.Decoder FQName
decodeFQName =
Decode.map3 FQName
(Decode.index 0 decodePath)
(Decode.index 1 decodePath)
(Decode.index 2 decodeName)
Loading

0 comments on commit 7731cb3

Please sign in to comment.