Add smart constructors for the core nodes (#480)

This commit is contained in:
Ara Adkins 2020-02-13 09:52:05 +00:00 committed by GitHub
parent a288ecaa5c
commit 9dee1911f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 3550 additions and 93 deletions

View File

@ -312,6 +312,9 @@ lazy val graph = (project in file("common/graph/"))
"com.github.ghik" % "silencer-lib" % silencerVersion % Provided cross CrossVersion.full
),
addCompilerPlugin(
"org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full
),
addCompilerPlugin (
"org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full
),
addCompilerPlugin("io.tryp" % "splain" % "0.5.0" cross CrossVersion.patch),
@ -394,6 +397,9 @@ lazy val core_definition = (project in file("engine/core-definition"))
addCompilerPlugin(
"org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full
),
addCompilerPlugin(
"org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full
),
addCompilerPlugin("io.tryp" % "splain" % "0.5.0" cross CrossVersion.patch),
scalacOptions ++= Seq(
"-P:splain:infix:true",
@ -403,6 +409,7 @@ lazy val core_definition = (project in file("engine/core-definition"))
)
)
.dependsOn(graph)
.dependsOn(syntax.jvm)
lazy val runtime = (project in file("engine/runtime"))
.configs(Benchmark)
@ -444,6 +451,9 @@ lazy val runtime = (project in file("engine/runtime"))
addCompilerPlugin(
"org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full
),
addCompilerPlugin(
"org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full
),
addCompilerPlugin("io.tryp" % "splain" % "0.5.0" cross CrossVersion.patch),
scalacOptions ++= Seq(
"-P:splain:infix:true",

View File

@ -19,6 +19,8 @@ import shapeless.nat._
* as much as possible.
* - Basic equality testing (that should be overridden as needed).
* - An ability to define fields that store complex data such as `String`.
* - Add a `Default` typeclass, and ensure that all component fields are
* instances of it. Fields should then be initialised using it.
*/
/** This file contains the implementation of an incredibly generic graph.
@ -357,8 +359,6 @@ object Graph {
@newtype
final case class Ref[G <: Graph, C <: Component](ix: Int)
// === Refined ===
/** Type refinement for component references.
*
* Type refinement is used to add additional information to a [[Component]]
@ -370,11 +370,14 @@ object Graph {
* encoded having the following type `Refined[Shape, App, Node]`.
*/
@newtype
final case class Refined[C <: Component.Field, Spec, T](wrapped: T)
final case class Refined[F <: Component.Field, Spec, T](wrapped: T)
object Refined {
implicit def unwrap[C <: Component.Field, S, T](
t: Refined[C, S, T]
implicit def unwrap[F <: Component.Field, S <: F, T](
t: Refined[F, S, T]
): T = { t.wrapped }
def wrap[F <: Component.Field, S <: F, T](t: T): Refined[F, S, T] =
Refined(t)
}
// === List ===
@ -721,7 +724,8 @@ object Graph {
ev3: HListTakeUntil.Aux[C, ComponentList, PrevComponentList],
ev4: hlist.Length.Aux[PrevComponentList, ComponentIndex],
componentIndexEv: nat.ToInt[ComponentIndex],
componentSizeEv: KnownSize[FieldList]
componentSizeEv: KnownSize[FieldList],
listContainsComponent: Selector[ComponentList, C]
): HasComponent[G, C] = new HasComponent[G, C] {
val componentIndex = componentIndexEv()
val componentSize = componentSizeEv.asInt
@ -751,7 +755,8 @@ object Graph {
implicit
ev1: Component.Field.List.Aux[G, C, FieldList],
evx: HasComponent[G, C],
fieldOffsetEv: SizeUntil[F, FieldList]
fieldOffsetEv: SizeUntil[F, FieldList],
containsField: Selector[FieldList, F]
): HasComponentField[G, C, F] = new HasComponentField[G, C, F] {
val componentIndex = evx.componentIndex
val componentSize = evx.componentSize
@ -783,4 +788,76 @@ object Graph {
val sizes = info.componentSize +: tail.sizes
}
}
/** Allows casting between variant cases without actually mutating the
* underlying structure.
*
* This is a very unsafe operation and should be used with care.
*
* @param component the component to cast the variant field in
* @param ev evidence that component [[C]] has field [[G]] in graph [[G]]
* @tparam G the graph type
* @tparam C the component type
* @tparam F the field type
*/
implicit class VariantCast[
G <: Graph,
C <: Component,
F <: Component.Field
](val component: Component.Ref[G, C])(
implicit ev: HasComponentField[G, C, F],
graph: GraphData[G]
) {
/** Checks if [[component]] is in the variant case denoted by the type
* [[V]].
*
* @param variantIndexed information that [[F]] is indeed a variant, with
* [[V]] as a valid case
* @tparam V the type of the variant case in question
* @return `true` if [[component]] is of the form denoted by [[V]], `false`
* otherwise
*/
def is[V <: F](
implicit variantIndexed: VariantIndexed[F, V]
): Boolean = {
graph.unsafeReadField[C, F](component) == variantIndexed.ix
}
/** Casts the variant field [[F]] to behave as the variant branch [[V]].
*
* It should be noted that this is purely a superficial cast, and does not
* affect the underlying graph. This means that [[C]] will still pattern
* match as if it was its original variant branch.
*
* @param variantIndexed information that [[F]] is indeed a variant, with
* [[V]] as a valid case
* @tparam V the type of the variant case in question
* @return the component [[component]] refined to be the variant branch
* [[V]]
*/
def unsafeAs[V <: F](
implicit variantIndexed: VariantIndexed[F, V]
): Component.Refined[F, V, Component.Ref[G, C]] = {
Component.Refined[F, V, Component.Ref[G, C]](component)
}
/** Performs a checked cast of [[component]] to the variant state denoted
* by [[V]].
*
* @param variantIndexed information that [[F]] is indeed a variant, with
* [[V]] as a valid case
* @tparam V the type of the variant case in question
* @return [[Some]] if [[component]] is a [[V]], otherwise [[None]]
*/
def as[V <: F](
implicit variantIndexed: VariantIndexed[F, V]
): Option[Component.Refined[F, V, Component.Ref[G, C]]] = {
if (is[V]) {
Some(unsafeAs[V])
} else {
None
}
}
}
}

View File

@ -230,7 +230,11 @@ object Macro {
}
}
/** Generates a getter for an element of a non-variant field.
/** Generates a getter for an element of a field.
*
* In the case where the field is _not_ simple, the subfield offsets are
* all incremented by one, to account for the fact that the first index
* in a non-simple (variant) field encodes the variant branch.
*
* @param paramDef the definition of the subfield
* @param enclosingTypeName the name of the field type
@ -277,7 +281,7 @@ object Macro {
$graphTermName.Component.Ref(
graph.unsafeReadFieldByIndex[C, $enclosingTypeName](
$graphTermName.Component.Refined.unwrap(node),
$index
${index + 1}
)
)
}
@ -334,7 +338,7 @@ object Macro {
$graphTermName.Component.Ref(
graph.unsafeReadFieldByIndex[C, $enclosingTypeName](
$graphTermName.Component.Refined.unwrap(node).ix,
$index
${index + 1}
)
)
}
@ -343,7 +347,11 @@ object Macro {
}
}
/** Generates a setter for an element of a non-variant field.
/** Generates a setter for an element of field.
*
* In the case where the field is _not_ simple, the subfield offsets are
* all incremented by one, to account for the fact that the first index
* in a non-simple (variant) field encodes the variant branch.
*
* @param paramDef the definition of the subfield
* @param enclosingTypeName the name of the field type
@ -388,7 +396,7 @@ object Macro {
): Unit = {
graph.unsafeWriteFieldByIndex[C, $enclosingTypeName](
$graphTermName.Component.Refined.unwrap(node).ix,
$index,
${index + 1},
value
)
}
@ -441,7 +449,7 @@ object Macro {
): Unit = {
graph.unsafeWriteFieldByIndex[C, $enclosingTypeName](
$graphTermName.Component.Refined.unwrap(node).ix,
$index,
${index + 1},
value.ix
)
}
@ -459,12 +467,6 @@ object Macro {
*/
def makeTypeAccessorName(fieldName: TypeName): String = {
StringUtils.uncapitalize(fieldName.toString)
// val matcher = "([A-Z])(.*)".r
//
// matcher.findFirstMatchIn(fieldName.toString) match {
// case Some(t) => s"${t.group(1).toLowerCase()}${t.group(2)}"
// case None => fieldName.toString.toLowerCase
// }
}
/** Generates accessor methods for the 'value class', the one that can
@ -527,7 +529,7 @@ object Macro {
}
/** Determines whether the parameter definition is defining an opaque
* type. An opaque type is one not stored in the graph represntation.
* type. An opaque type is one not stored in the graph representation.
*
* @param paramDef the definition to check
* @return `true` if `paramDef` defines an opauqe type, otherwise `false`

View File

@ -95,7 +95,7 @@ class GraphTest extends FlatSpec with Matchers {
case GraphImpl.Node.Shape.App.any(n1) => n1.fn
}
refinedResult shouldEqual 1
refinedResult shouldEqual 0
}
"Component fields" can "be accessed properly" in {

View File

@ -173,9 +173,9 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Edge[G] =
// PrimGraph.Component.Ref(
// graph.primUnsafeReadField[C, Shape](
// graph.primUnsafeReadFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0
// 1
// )
// )
//
@ -183,9 +183,9 @@ object GraphTestDefinition {
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit =
// graph.primUnsafeWriteField[C, Shape](
// graph.primUnsafeWriteFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0,
// 1,
// value.ix
// )
//
@ -194,9 +194,9 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Edge[G] =
// PrimGraph.Component.Ref(
// graph.primUnsafeReadField[C, Shape](
// graph.primUnsafeReadFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 1
// 2
// )
// )
//
@ -204,9 +204,9 @@ object GraphTestDefinition {
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit =
// graph.primUnsafeWriteField[C, Shape](
// graph.primUnsafeWriteFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 1,
// 2,
// value.ix
// )
//
@ -265,9 +265,9 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Edge[G] =
// PrimGraph.Component.Ref(
// graph.primUnsafeReadField[C, Shape](
// graph.primUnsafeReadFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0
// 1
// )
// )
//
@ -275,9 +275,9 @@ object GraphTestDefinition {
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit =
// graph.primUnsafeWriteField[C, Shape](
// graph.primUnsafeWriteFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0,
// 2,
// value.ix
// )
//
@ -286,11 +286,7 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): CentreVal[G] = {
// CentreVal(
// PrimGraph.Component.Ref(
// graph.primUnsafeReadField[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0
// )
// this.fn
// )
// )
// }
@ -299,11 +295,7 @@ object GraphTestDefinition {
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit = {
// graph.primUnsafeWriteField[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0,
// value.fn.ix
// )
// this.fn = value.fn
// }
// }
// }
@ -362,9 +354,9 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Edge[G] = {
// PrimGraph.Component.Ref(
// graph.primUnsafeReadField[C, Shape](
// graph.primUnsafeReadFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0 // as the other field is opaque
// 1 // as the other field is opaque
// )
// )
// }
@ -373,9 +365,9 @@ object GraphTestDefinition {
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit = {
// graph.primUnsafeWriteField[C, Shape](
// graph.primUnsafeWriteFieldByIndex[C, Shape](
// PrimGraph.Component.Refined.unwrap(node).ix,
// 0,
// 1,
// value.ix
// )
// }
@ -422,7 +414,7 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, ParentLink]
// ): Edge[G] = {
// PrimGraph.Component.Ref(
// graph.unsafeReadField[C, ParentLink](node.ix, 0)
// graph.unsafeReadFieldByIndex[C, ParentLink](node.ix, 0)
// )
// }
//
@ -430,7 +422,7 @@ object GraphTestDefinition {
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, ParentLink]
// ): Unit = {
// graph.unsafeWriteField[C, ParentLink](node.ix, 0, value.ix)
// graph.unsafeWriteFieldByIndex[C, ParentLink](node.ix, 0, value.ix)
// }
//
// def parentLink(
@ -480,18 +472,18 @@ object GraphTestDefinition {
// def line_=(value: Int)(
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Location]
// ): Unit = graph.unsafeWriteField[C, Location](node.ix, 0, value)
// ): Unit = graph.unsafeWriteFieldByIndex[C, Location](node.ix, 0, value)
//
// def column(
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Location]
// ): Int =
// graph.unsafeReadField[C, Location](node.ix, 1)
// graph.unsafeReadFieldByIndex[C, Location](node.ix, 1)
//
// def column_=(value: Int)(
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Location]
// ): Unit = graph.unsafeWriteField[C, Location](node.ix, 1, value)
// ): Unit = graph.unsafeWriteFieldByIndex[C, Location](node.ix, 1, value)
//
// def location(
// implicit graph: PrimGraph.GraphData[G],
@ -593,26 +585,28 @@ object GraphTestDefinition {
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Node[G] =
// PrimGraph.Component.Ref(
// graph.unsafeReadField[C, Shape](node.ix, 0)
// graph.unsafeReadFieldByIndex[C, Shape](node.ix, 0)
// )
//
// def source_=(value: Node[G])(
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit = graph.unsafeWriteField[C, Shape](node.ix, 0, value.ix)
// ): Unit =
// graph.unsafeWriteFieldByIndex[C, Shape](node.ix, 0, value.ix)
//
// def target(
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Node[G] =
// PrimGraph.Component.Ref(
// graph.unsafeReadField[C, Shape](node.ix, 1)
// graph.unsafeReadFieldByIndex[C, Shape](node.ix, 1)
// )
//
// def target_=(value: Node[G])(
// implicit graph: PrimGraph.GraphData[G],
// ev: PrimGraph.HasComponentField[G, C, Shape]
// ): Unit = graph.unsafeWriteField[C, Shape](node.ix, 1, value.ix)
// ): Unit =
// graph.unsafeWriteFieldByIndex[C, Shape](node.ix, 1, value.ix)
//
// def shape(
// implicit graph: PrimGraph.GraphData[G],

View File

@ -18,7 +18,6 @@ class DocParserTests extends FlatSpec with Matchers {
val output = DocParser.run(input)
output match {
case Result(_, Result.Success(value)) =>
pprint.pprintln(value)
assert(value == result)
assert(value.show() == new Reader(input).toString())
case _ =>

View File

@ -3,8 +3,8 @@ package org.enso.core
import org.enso.graph.definition.Macro.{component, field, genGraph, opaque}
import org.enso.graph.{Sized, VariantIndexed, Graph => PrimGraph}
import shapeless.{::, HNil}
import org.enso.syntax.text.AST
// TODO [AA] More detailed semantic descriptions for each node shape in future.
object CoreGraph {
@genGraph object Definition {
@ -38,6 +38,9 @@ object CoreGraph {
*/
@opaque case class Parent(opaque: Vector[Int])
/** Storage for raw AST nodes. */
@opaque case class Ast(opaque: AST)
// ========================================================================
// === Node ===============================================================
// ========================================================================
@ -176,7 +179,7 @@ object CoreGraph {
/** An import statement.
*
* @param segments the segments of the import path, represented as a
* [[NameLiteral]].
* [[MetaList]].
*/
case class Import(segments: Link[G])
@ -199,7 +202,8 @@ object CoreGraph {
/** An expanded-form type definition, with a body.
*
* @param name the name of the aggregate type
* @param typeParams the type parameters to the definition
* @param typeParams the type parameters to the definition, as a
* [[MetaList]] of bindings
* @param body the body of the type definition, represented as a
* [[MetaList]] of bindings
*/
@ -211,7 +215,7 @@ object CoreGraph {
// === Typing =========================================================
/** A type signature.
/** The ascription of a type to a value.
*
* @param typed the expression being ascribed a type
* @param sig the signature being ascribed to [[typed]]
@ -446,7 +450,7 @@ object CoreGraph {
/** A case branch.
*
* All case patterns will initially be desugared to a
* [[StructuralMatch]] and will be refined during further desugaring
* [[StructuralPattern]] and will be refined during further desugaring
* passes, some of which may depend on type checking.
*
* @param pattern the pattern to match the scrutinee against
@ -459,7 +463,7 @@ object CoreGraph {
* @param matchExpression the expression representing the possible
* structure of the scrutinee
*/
case class StructuralMatch(matchExpression: Link[G])
case class StructuralPattern(matchExpression: Link[G])
/** A pattern that matches on the scrutinee purely based on a type
* subsumption judgement.
@ -467,7 +471,7 @@ object CoreGraph {
* @param matchExpression the expression representing the possible type
* of the scrutinee
*/
case class TypeMatch(matchExpression: Link[G])
case class TypePattern(matchExpression: Link[G])
/** A pattern that matches on the scrutinee based on a type subsumption
* judgement and assigns a new name to it for use in the branch.
@ -475,10 +479,10 @@ object CoreGraph {
* @param matchExpression the expression representing the possible type
* of the scrutinee, and its new name
*/
case class NamedMatch(matchExpression: Link[G])
case class NamedPattern(matchExpression: Link[G])
/** A pattern that matches on any scrutinee. */
case class FallbackMatch()
case class FallbackPattern()
// === Comments =======================================================
@ -502,17 +506,61 @@ object CoreGraph {
/** A syntax error.
*
* @param errorNode the node representation of the syntax error
* @param errorAst the raw AST representation of the syntax error
*/
case class SyntaxError(errorNode: Link[G])
case class SyntaxError(errorAst: OpaqueData[AST, AstStorage])
// TODO [AA] Fill in the error types as they become evident
/** Returned on an attempt to construct erroneous core.
*
* @param erroneousCore a [[MetaList]] containing the one-or-more core
* nodes that were in an incorrect format
*/
case class ConstructionError(erroneousCore: Link[G])
}
// ======================================================================
// === Utility Functions ================================================
// ======================================================================
/** Adds a link as a parent of the provided node.
*
* This should _only_ be used when the [[target]] field of [[link]]
* points to [[node]].
*
* @param node the node to add a parent to
* @param link the link to add as a parent
* @param graph the graph in which this takes place
* @param map the graph's parent storage
*/
def addParent(
node: Node[CoreGraph],
link: Link[CoreGraph]
)(
implicit graph: PrimGraph.GraphData[CoreGraph],
map: ParentStorage
): Unit = {
import Node.ParentLinks._
node.parents = node.parents :+ link.ix
}
/** Adds a node to the graph with its shape already set to a given shape.
*
* @param graph the graph to add the node to
* @param ev evidence that the variant field is indexed
* @tparam V the shape to set the node to
* @return a refined node reference
*/
def addRefined[V <: Node.Shape](
implicit graph: PrimGraph.GraphData[CoreGraph],
ev: VariantIndexed[Node.Shape, V]
): PrimGraph.Component.Refined[Node.Shape, V, Node[CoreGraph]] = {
val node = graph.addNode()
setShape[V](node)
PrimGraph.Component.Refined[Node.Shape, V, Node[CoreGraph]](node)
}
/** Sets the shape of the provided [[node]] to [[Shape]].
*
* @param node the node to set
@ -539,6 +587,7 @@ object CoreGraph {
)(implicit graph: PrimGraph.GraphData[CoreGraph]): Boolean = {
node match {
case Shape.SyntaxError.any(_) => true
case Shape.ConstructionError.any(_) => true
case _ => false
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
package org.enso.compiler.test.core
import org.enso.compiler.test.CompilerTest
import org.enso.core.CoreGraph.DefinitionGen.Node.LocationVal
import org.enso.core.CoreGraph.DefinitionGen.{
AstStorage,
Link,
LiteralStorage,
NameStorage,
@ -10,6 +12,7 @@ import org.enso.core.CoreGraph.DefinitionGen.{
}
import org.scalatest.BeforeAndAfterEach
import org.enso.graph.{Graph => PrimGraph}
import org.enso.syntax.text.AST
/** This file tests the primitive, low-level operations on core.
*
@ -22,7 +25,7 @@ import org.enso.graph.{Graph => PrimGraph}
class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
// === Test Setup ===========================================================
import org.enso.core.CoreGraph.DefinitionGen.CoreGraph
import org.enso.core.CoreGraph.DefinitionGen._
import org.enso.core.CoreGraph.DefinitionGen.Link.Shape._
import org.enso.core.CoreGraph.DefinitionGen.Node.Shape._
import org.enso.core.CoreGraph.DefinitionGen.Node.Location._
@ -33,12 +36,14 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
implicit var literalStorage: LiteralStorage = _
implicit var parentStorage: ParentStorage = _
implicit var nameStorage: NameStorage = _
implicit var astStorage: AstStorage = _
override def beforeEach(): Unit = {
graph = PrimGraph[CoreGraph]()
literalStorage = LiteralStorage()
parentStorage = ParentStorage()
nameStorage = NameStorage()
astStorage = AstStorage()
}
// === Tests for Links ======================================================
@ -124,6 +129,34 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
}
}
node should "be able to be constructed without clobbering its fields" in {
val emptyLink = graph.addLink()
val nilLink = graph.addLink()
val consNode = Node.addRefined[MetaList]
consNode.head = emptyLink
consNode.tail = nilLink
consNode.location = LocationVal[CoreGraph](20, 30)
consNode.parents = Vector()
// Intentional re-assignment in reverse order to check for clobbering
consNode.tail = nilLink
consNode.head = emptyLink
consNode.head shouldEqual emptyLink
consNode.tail shouldEqual nilLink
consNode.sourceStart shouldEqual 20
consNode.sourceEnd shouldEqual 30
consNode.parents shouldEqual Vector()
consNode.wrapped match {
case MetaList.any(_) => succeed
case _ => fail
}
}
// === Tests for Node Shapes ================================================
nodeShape should "be able to be empty" in {
val n1 = graph.addNode()
@ -807,13 +840,13 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
val n1 = graph.addNode()
val l1 = graph.addLink()
Node.setShape[StructuralMatch](n1)
Node.setShape[StructuralPattern](n1)
n1 match {
case StructuralMatch.any(n1) =>
case StructuralPattern.any(n1) =>
n1.matchExpression = l1
n1.structuralMatch shouldEqual StructuralMatchVal(l1)
n1.structuralPattern shouldEqual StructuralPatternVal(l1)
case _ => fail
}
}
@ -822,13 +855,13 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
val n1 = graph.addNode()
val l1 = graph.addLink()
Node.setShape[TypeMatch](n1)
Node.setShape[TypePattern](n1)
n1 match {
case TypeMatch.any(n1) =>
case TypePattern.any(n1) =>
n1.matchExpression = l1
n1.typeMatch shouldEqual TypeMatchVal(l1)
n1.typePattern shouldEqual TypePatternVal(l1)
case _ => fail
}
}
@ -837,13 +870,13 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
val n1 = graph.addNode()
val l1 = graph.addLink()
Node.setShape[NamedMatch](n1)
Node.setShape[NamedPattern](n1)
n1 match {
case NamedMatch.any(n1) =>
case NamedPattern.any(n1) =>
n1.matchExpression = l1
n1.namedMatch shouldEqual NamedMatchVal(l1)
n1.namedPattern shouldEqual NamedPatternVal(l1)
case _ => fail
}
}
@ -851,10 +884,10 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
nodeShape should "be able to represent fallback patterns" in {
val n1 = graph.addNode()
Node.setShape[FallbackMatch](n1)
Node.setShape[FallbackPattern](n1)
n1 match {
case FallbackMatch.any(_) => succeed
case FallbackPattern.any(_) => succeed
case _ => fail
}
}
@ -895,16 +928,30 @@ class CorePrimTest extends CompilerTest with BeforeAndAfterEach {
nodeShape should "be able to represent syntax errors" in {
val n1 = graph.addNode()
val l1 = graph.addLink()
val ast = AST.Blank()
Node.setShape[SyntaxError](n1)
n1 match {
case SyntaxError.any(n1) =>
n1.errorNode = l1
n1.errorAst = ast
n1.syntaxError shouldEqual SyntaxErrorVal(l1)
n1.syntaxError shouldEqual SyntaxErrorVal(ast)
case _ => fail
}
}
nodeShape should "be able to represent construction errors" in {
val n1 = graph.addNode()
val l1 = graph.addLink()
Node.setShape[ConstructionError](n1)
n1 match {
case ConstructionError.any(n1) =>
n1.erroneousCore = l1
n1.constructionError shouldEqual ConstructionErrorVal(l1)
}
}
}

View File

@ -10,6 +10,4 @@ import org.enso.compiler.test.CompilerTest
// - Linked List
// - Parent Link walk to same place
// - etc.
class CoreTest extends CompilerTest {
}
class CoreTest extends CompilerTest {}