Skip to content

Commit 1b0a0d9

Browse files
authored
Merge pull request #1230 from nwokafor-choongsaeng/morphir-component
Added Component structure in Distribution and Source
2 parents e112724 + dc0fc15 commit 1b0a0d9

File tree

9 files changed

+1678
-325
lines changed

9 files changed

+1678
-325
lines changed

src/Morphir/IR/Decoration.elm

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Morphir.IR.Decoration exposing
33
, getDecoratedNodeIds, getNodeIdsDecoratedWithValue, filterDecorations
44
)
55

6-
{-| Module to work with Decorations. A decoration is an additional piece of information added to your model that is not captured in the langauge
6+
{-| Module to work with Decorations. A decoration is an additional piece of information added to your model that is not captured in the language
77
88
@docs DecorationID, AllDecorationConfigAndData, DecorationData, DecorationConfigAndData
99
@docs getDecoratedNodeIds, getNodeIdsDecoratedWithValue, filterDecorations

src/Morphir/IR/Distribution.elm

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Morphir.IR.Distribution exposing
2-
( Distribution(..), library
2+
( Distribution(..), Component, library
33
, lookupModuleSpecification, lookupTypeSpecification, lookupValueSpecification, lookupBaseTypeName, lookupValueDefinition
44
, lookupPackageSpecification, lookupPackageName, typeSpecifications, lookupTypeConstructor
55
, resolveAliases, resolveType, resolveRecordConstructors
@@ -18,7 +18,7 @@ information:
1818
- The package definition which contains all the module definitions included in the library. The package definition
1919
contains implementations as well, even ones that are not exposed.
2020
21-
@docs Distribution, library
21+
@docs Distribution, Component, library
2222
2323
2424
# Lookups
@@ -39,10 +39,31 @@ import Morphir.IR.FQName exposing (FQName)
3939
import Morphir.IR.Module as Module exposing (ModuleName)
4040
import Morphir.IR.Name exposing (Name)
4141
import Morphir.IR.Package as Package exposing (PackageName, lookupModuleDefinition)
42+
import Morphir.IR.Path exposing (Path)
4243
import Morphir.IR.Type as Type exposing (Type)
4344
import Morphir.IR.Value as Value exposing (Value)
4445

4546

47+
{-| Type that represents a complete encapsulated and tree-shaken Component.
48+
A component is a superset of Library. It's similar to an application because it contains all the information needed
49+
to run the component. The fields of a component are:
50+
51+
- name: The name of the component
52+
- libraries: All the library dependencies with their implementation.
53+
- inputs: The inputs of the component as a dictionary of the unique input name and it's Morphir type.
54+
- states: The states of the component as a dictionary of the unique state name and it's Morphir type.
55+
- outputs: The outputs of the component as a dictionary of unique names and their values.
56+
57+
-}
58+
type alias Component =
59+
{ name : Path
60+
, libraries : Dict PackageName (Package.Definition () (Type ()))
61+
, inputs : Dict Name (Type ())
62+
, states : Dict Name (Type ())
63+
, outputs : Dict Name (Value () (Type ()))
64+
}
65+
66+
4667
{-| Type that represents a package distribution. Currently the only distribution type we provide is a `Library`.
4768
-}
4869
type Distribution

src/Morphir/IR/Distribution/Codec.elm

+61-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
-}
1616

1717

18-
module Morphir.IR.Distribution.Codec exposing (encodeDistribution, decodeDistribution)
18+
module Morphir.IR.Distribution.Codec exposing
19+
( encodeDistribution, decodeDistribution
20+
, encodeComponent, decodeComponent
21+
)
1922

2023
{-| Codecs for types in the `Morphir.IR.Distribution` module.
2124
@@ -24,17 +27,24 @@ module Morphir.IR.Distribution.Codec exposing (encodeDistribution, decodeDistrib
2427
2528
@docs encodeDistribution, decodeDistribution
2629
30+
31+
# Component
32+
33+
@docs encodeComponent, decodeComponent
34+
2735
-}
2836

2937
import Dict
3038
import Json.Decode as Decode
3139
import Json.Encode as Encode
3240
import Morphir.Codec exposing (decodeUnit, encodeUnit)
33-
import Morphir.IR.Distribution exposing (Distribution(..))
41+
import Morphir.IR.Distribution exposing (Component, Distribution(..))
3442
import Morphir.IR.Distribution.CodecV1 as CodecV1
43+
import Morphir.IR.Name as Name
3544
import Morphir.IR.Package.Codec as PackageCodec
3645
import Morphir.IR.Path.Codec exposing (decodePath, encodePath)
3746
import Morphir.IR.Type.Codec exposing (decodeType, encodeType)
47+
import Morphir.IR.Value.Codec exposing (decodeValue, encodeValue)
3848

3949

4050
{-| Encode Distribution.
@@ -87,3 +97,52 @@ decodeDistribution =
8797
other ->
8898
Decode.fail <| "Unknown value type: " ++ other
8999
)
100+
101+
102+
{-| Encodes a Component.
103+
-}
104+
encodeComponent : Component -> Encode.Value
105+
encodeComponent component =
106+
Encode.object
107+
[ ( "name", encodePath component.name )
108+
, ( "libraries"
109+
, component.libraries
110+
|> Dict.toList
111+
|> Encode.list
112+
(\( packageName, packageDef ) ->
113+
Encode.list identity
114+
[ encodePath packageName
115+
, PackageCodec.encodeDefinition encodeUnit (encodeType encodeUnit) packageDef
116+
]
117+
)
118+
)
119+
, ( "inputs", Encode.dict Name.toCamelCase (encodeType encodeUnit) component.inputs )
120+
, ( "states", Encode.dict Name.toCamelCase (encodeType encodeUnit) component.states )
121+
, ( "outputs", Encode.dict Name.toCamelCase (encodeValue encodeUnit <| encodeType encodeUnit) component.outputs )
122+
]
123+
124+
125+
{-| Decodes a Component.
126+
-}
127+
decodeComponent : Decode.Decoder Component
128+
decodeComponent =
129+
let
130+
nameKeyValueDecoder valueDecoder =
131+
Decode.keyValuePairs valueDecoder
132+
|> Decode.map
133+
(List.map (Tuple.mapFirst Name.fromString)
134+
>> Dict.fromList
135+
)
136+
137+
libraryEntryDecoder =
138+
Decode.map2 Tuple.pair
139+
(Decode.index 0 decodePath)
140+
(Decode.index 1 (PackageCodec.decodeDefinition decodeUnit (decodeType decodeUnit)))
141+
in
142+
Decode.map5
143+
Component
144+
(Decode.field "name" decodePath)
145+
(Decode.field "libraries" <| (Decode.list libraryEntryDecoder |> Decode.map Dict.fromList))
146+
(Decode.field "inputs" <| nameKeyValueDecoder (decodeType decodeUnit))
147+
(Decode.field "states" <| nameKeyValueDecoder (decodeType decodeUnit))
148+
(Decode.field "outputs" <| nameKeyValueDecoder (decodeValue decodeUnit (decodeType decodeUnit)))

src/Morphir/IR/Source.elm

+117-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,125 @@
1-
module Morphir.IR.Source exposing (..)
1+
{-
2+
Copyright 2020 Morgan Stanley
23
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
37
4-
type Located a
5-
= At Region a
8+
http://www.apache.org/licenses/LICENSE-2.0
69
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-}
716

8-
type alias Region =
9-
{ start : Location
10-
, end : Location
17+
18+
module Morphir.IR.Source exposing
19+
( Component, ComponentName, DataSourceName, OutputName, OutputSource, DataType(..)
20+
, component, outputSource
21+
, ParameterName
22+
)
23+
24+
{-| This module defines a JSON Source format for producing a new kind of Morphir IR defined in
25+
[Distribution](Distribution#Component). This format allows for the definition of entry points and their inputs that
26+
allows for the production of an encapsulated and tree-shaken component that has no external dependencies.
27+
28+
29+
# Types
30+
31+
@docs Component, ComponentName, DataSourceName, OutputName, ArgumentName, OutputSource, DataType
32+
33+
34+
# Creation
35+
36+
@docs component, outputSource
37+
38+
-}
39+
40+
import Dict exposing (Dict)
41+
import Morphir.IR.FQName exposing (FQName)
42+
import Morphir.IR.Literal exposing (Literal)
43+
import Morphir.IR.Name exposing (Name)
44+
import Morphir.IR.Path exposing (Path)
45+
46+
47+
{-| Type that defines the entry points of [Component](Distribution#Component).
48+
The fields of a component are:
49+
50+
- name: The name of the component
51+
- inputs: The inputs of the component as a dictionary of the unique input name and [data type](#DataType).
52+
- states: The states of the component as a dictionary of the unique state name and [data type](#DataType).
53+
- outputs: The outputs of the component as a dictionary of unique names and a list of [sources](#OutputSource) that contribute to the output.
54+
55+
-}
56+
type alias Component =
57+
{ name : ComponentName
58+
, inputs : Dict DataSourceName DataType
59+
, states : Dict DataSourceName DataType
60+
, outputs : Dict OutputName (List OutputSource)
61+
}
62+
63+
64+
{-| Represents a Component name.
65+
-}
66+
type alias ComponentName =
67+
Path
68+
69+
70+
{-| Represents a DataSource name.
71+
-}
72+
type alias DataSourceName =
73+
Name
74+
75+
76+
{-| Represents the types of data that can be used as a data source in either the inputs or states field of a [Component](#Component).
77+
-}
78+
type DataType
79+
= RowSet FQName
80+
| Literal Literal
81+
82+
83+
{-| Represents an Output name.
84+
-}
85+
type alias OutputName =
86+
Name
87+
88+
89+
{-| Represents the dependencies that contribute to an Output. The fields of an OutputSource are:
90+
91+
- functionReference: A fully qualified reference to a function that produces a slice of an output.
92+
- arguments: The arguments that are passed to the function reference. The keys are the parameter names and the values
93+
are the data source names. The data source names must be declared in inputs or states field of the [Component](#Component).
94+
95+
-}
96+
type alias OutputSource =
97+
{ functionReference : FQName
98+
, arguments : Dict ParameterName DataSourceName
99+
}
100+
101+
102+
{-| Represents an Argument name.
103+
-}
104+
type alias ParameterName =
105+
Name
106+
107+
108+
{-| Creates a new component with the given name, inputs, states and outputs.
109+
-}
110+
component : ComponentName -> Dict DataSourceName DataType -> Dict DataSourceName DataType -> Dict OutputName (List OutputSource) -> Component
111+
component name inputs states outputs =
112+
{ name = name
113+
, inputs = inputs
114+
, states = states
115+
, outputs = outputs
11116
}
12117

13118

14-
type alias Location =
15-
{ row : Int
16-
, column : Int
119+
{-| Creates a new output source with the given function reference and arguments.
120+
-}
121+
outputSource : FQName -> Dict ParameterName DataSourceName -> OutputSource
122+
outputSource functionName arguments =
123+
{ functionReference = functionName
124+
, arguments = arguments
17125
}

0 commit comments

Comments
 (0)