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

Model Morphir IR in Scala 3 (#97) #102

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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