Skip to content

Commit

Permalink
Model Morphir IR in Scala 3 (#97)
Browse files Browse the repository at this point in the history
* Adding IR - #75

* Adding Package related IR types

* issue-94: add tuple to sdk (#98)

* issue-94: add tuple to sdk

* issue-94: run formatter

* Finishing up modeling of morphir IR in Scala 3

* Move IR into morphir-ir

Co-authored-by: willms2021 <[email protected]>
  • Loading branch information
DamianReeves and willms2021 authored Jul 16, 2021
1 parent 14cc17b commit dd2d4c7
Show file tree
Hide file tree
Showing 36 changed files with 556 additions and 17 deletions.
10 changes: 7 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ output/
.ionide
.vscode
out/
/.bloop/
/.metals/
.bloop/
.metals/
contrib/bsp/mill-external-bs
contrib/bsp/mill-out-bs
mill.iml
Expand All @@ -21,4 +21,8 @@ models/shared-domain/elm-stuff/
models/shared-domain/elm.json
elm-stuff/
.tmp/
null/
null/

metals.sbt

metals.sbt
2 changes: 1 addition & 1 deletion .mill-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.5
0.9.8
86 changes: 83 additions & 3 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,81 @@ align.preset = most
align.multiline = false
continuationIndent.defnSite = 2
assumeStandardLibraryStripMargin = true
docstrings = JavaDoc
docstrings.style = Asterisk
lineEndings = preserve
includeCurlyBraceInSelectChains = false
danglingParentheses.preset = true
version = "3.0.0-RC5"

align {
stripMargin = true
}

assumeStandardLibraryStripMargin = false

binPack {
literalArgumentLists = false
}

continuationIndent {
withSiteRelativeToExtends = 3
}

includeNoParensInSelectChains = true

indent {
caseSite = 5
}

indentOperator {
topLevelOnly = false
}

maxColumn = 100

newlines {
alwaysBeforeElseAfterCurlyIf = true
avoidInResultType = true
beforeCurlyLambdaParams = multilineWithCaseOnly
}

project {
excludeFilters = [
".metals"
]
}

rewrite {
rules = [
PreferCurlyFors
RedundantBraces
RedundantParens
SortModifiers
]
sortModifiers {
order = [
final
sealed
abstract
override
implicit
private
protected
lazy
]
}
}

rewriteTokens {
"⇒" = "=>"
"→" = "->"
"←" = "<-"
}

runner {
dialect = scala3
}

spaces {
inImportCurlyBraces = true
}
Expand All @@ -17,12 +88,21 @@ newlines.alwaysBeforeMultilineDef = false
rewrite.rules = [RedundantBraces]

project.excludeFilters = [

trailingCommas, multiple
]

rewrite.redundantBraces.generalExpressions = false
rewriteTokens = {
"⇒": "=>"
"→": "->"
"←": "<-"
}
}
verticalMultiline = {
arityThreshold = 3
atDefnSite = true
excludeDanglingParens = []
newlineAfterImplicitKW = true
newlineAfterOpenParen = true
newlineBeforeImplicitKW = false
}

52 changes: 52 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import sbt.Keys._
import sbt._

resolvers ++= Seq(
Resolver.mavenLocal,
Resolver.sonatypeRepo("releases"),
Resolver.sonatypeRepo("snapshots"),
Resolver.jcenterRepo
)

lazy val root = (project in file("."))
.settings(
commonSettings,
libraryDependencies ++= Dependencies.zioCommonDeps,
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
)
.aggregate(
morphirIR
)

lazy val commonSettings = Seq(
name := "morphir-ir",
version := "0.1.0",
scalacOptions ++= Seq(
"-deprecation",
"-language:postfixOps",
"-Ykind-projector",
"-Yexplicit-nulls",
"-source",
"future",
"-Xfatal-warnings"
) ++ Seq("-rewrite", "-indent"),
scalaVersion := "3.0.0"
)

lazy val morphirIR = project
.in(file("./morphir-ir"))
.settings(
name := "morphir-ir",
version := "0.1.0",
scalacOptions ++= Seq(
"-language:postfixOps",
"-Ykind-projector",
"-Yexplicit-nulls",
"-source",
"future",
"-Xfatal-warnings"
),
libraryDependencies ++= Dependencies.zioCommonDeps,
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework")),
scalaVersion := "3.0.0"
)
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{-
Copyright 2020 Morgan Stanley
Copyright 2020 Morgan Stanley
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-}


Expand Down Expand Up @@ -45,3 +45,9 @@ create text =

else
"Invalid email address" |> Result.Err

_ ->
"Invalid email address" |> Result.Err

_ ->
"Invalid email address" |> Result.Err
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.finos.morphir.ir

final case class AccessControlled[+A](access: Access, value: A) {

def isPrivate: Boolean = access == Access.Private
def isPublic: Boolean = access == Access.Public

def map[B](f: A => B): AccessControlled[B] =
copy(value = f(value))

def withPrivateAccess: A = access match {
case Access.Public => value
case Access.Private => value
}

def withPublicAccess: Option[A] = access match {
case Access.Public => Some(value)
case Access.Private => None
}
}

enum Access:
case Public
case Private
14 changes: 14 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/Constructors.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.finos.morphir.ir
import scala.collection.immutable.ListMap

/**
* Constructors in a dictionary keyed by their name. The values are the argument types for each
* constructor
*/
final case class TypeConstructors[+A](lookup: ListMap[Name, List[(Name, Type[A])]]):
def transform[B](f: A => B): TypeConstructors[B] =
TypeConstructors(
lookup.map((name, args) =>
(name, args.map((argName, argType) => (argName, argType.transform(f))))
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.finos.morphir.ir

enum Distribution:
case Library(packageName: PackageName)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.finos.morphir.ir

/**
* Type that represents a documented value.
*/
final case class Documented[+A](doc: String, value: A):
def map[B](f: A => B): Documented[B] = copy(value = f(value))
7 changes: 7 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/FQName.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.finos.morphir.ir

case class FQName(
packagePath: Path,
modulePath: Path,
localName: Name
)
10 changes: 10 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/Field.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.finos.morphir.ir

final case class Field[+A](name: String, fieldType: Type[A]):
def mapAttributes[B](f: A => B): Field[B] =
Field(name = name, fieldType = fieldType.transform(f))

object FieldList:
extension [A](self: List[Field[A]])
def mapAttributes[B](f: A => B): List[Field[B]] =
self.map(field => field.mapAttributes(f))
8 changes: 8 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/Lit.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.finos.morphir.ir

enum Lit:
case Bool(value: Boolean)
case Char(value: scala.Char)
case Str(value: String)
case Int(value: scala.Int) //TODO: Maybe BigInt
case Float(value: scala.Double)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.finos.morphir.ir
import scala.collection.immutable.ListMap

/**
* Type that represents a module definition. A module definition contains all the details including
* implementation and private types and values.
*
* A module contains types and values which is represented by two field in this type:
* - types: a map of local name to access controlled, documented type specification.
* - values: a map of local name to access controlled value specification.
*/
final case class ModuleDefinition[+TA, +VA](
types: ListMap[Name, AccessControlled[Documented[TypeDefinition[TA]]]],
values: ListMap[Name, AccessControlled[ValueDefinition[TA, VA]]]
):

def lookupValueDefinition(name: Name): Option[ValueDefinition[TA, VA]] =
values get name map (_.withPrivateAccess)

object ModuleDefinition:
def empty[TA, VA]: ModuleDefinition[TA, VA] =
ModuleDefinition[TA, VA](ListMap.empty, ListMap.empty)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.finos.morphir.ir

final case class ModuleName(path: List[Name])
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.finos.morphir.ir
import scala.collection.immutable.ListMap

final case class ModuleSpecification[+A](
types: ListMap[Name, Documented[TypeSpecification[A]]],
values: ListMap[Name, ValueSpecification[A]]
)
3 changes: 3 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/Name.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.finos.morphir.ir

final case class Name(name: List[String])
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.finos.morphir.ir

import scala.collection.immutable.ListMap

final case class PackageDefinition[TA, VA](
modules: ListMap[ModuleName, AccessControlled[ModuleDefinition[TA, VA]]]
)
object PackageDefinition:
val empty: PackageDefinition[Unit, Unit] = PackageDefinition[Unit, Unit](ListMap.empty)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.finos.morphir.ir

final case class PackageName(path: List[Name])
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.finos.morphir.ir
import scala.collection.immutable.ListMap

final case class PackageSpecification[+A](modules: ListMap[ModuleName, ModuleSpecification[A]])

object PackageSpecification:
def empty[A]: PackageSpecification[A] =
PackageSpecification[A](ListMap.empty)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.finos.morphir.ir

final case class ParameterInfo[+TA, +VA](
name: Name,
annotations: VA,
parameterType: Type[TA]
)
3 changes: 3 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/Path.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.finos.morphir.ir

final case class Path(path: List[Name])
13 changes: 13 additions & 0 deletions morphir-ir/src/main/scala/org/finos/morphir/ir/Pattern.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.finos.morphir.ir

case class Pattern[+A](ann: A, details: PatternDetails[A])

enum PatternDetails[+A]:
case Wildcard
case As(pattern: Pattern[A], name: Name)
case Tuple(components: List[Pattern[A]])
case Constructor(fqName: FQName, parameters: List[Pattern[A]])
case EmptyList
case HeadTail(head: Pattern[A], tail: Pattern[A])
case Literal(literal: Lit)
case Unit
Loading

0 comments on commit dd2d4c7

Please sign in to comment.