Skip to content

Commit

Permalink
Merge pull request #777 from performantdata/ast-separation
Browse files Browse the repository at this point in the history
AST separation
  • Loading branch information
yanns authored Nov 10, 2021
2 parents 3eb4c9c + adb31f0 commit 5a342c2
Show file tree
Hide file tree
Showing 57 changed files with 588 additions and 389 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
run: sbt ++${{ matrix.scala }} test

- name: Compress target directories
run: tar cf targets.tar target modules/core/target modules/benchmarks/target project/target
run: tar cf targets.tar target modules/ast/target modules/core/target modules/benchmarks/target project/target

- name: Upload target directories
uses: actions/upload-artifact@v2
Expand Down
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# folders
.bsp
.idea
target
lib
classes
.bsp/
.idea/
target/
lib/
classes/

# files
*.iml
Expand Down
147 changes: 145 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,165 @@ ThisBuild / mimaBinaryIssueFilters ++= Seq(
"sangria.execution.ExecutionPath.productElementName"),
ProblemFilters.exclude[IncompatibleMethTypeProblem]("sangria.execution.ExecutionPath.this"),
ProblemFilters.exclude[DirectMissingMethodProblem]("sangria.execution.ExecutionPath.this"),
ProblemFilters.exclude[MissingTypesProblem]("sangria.execution.ExecutionPath$")
ProblemFilters.exclude[MissingTypesProblem]("sangria.execution.ExecutionPath$"),

// removed the `ast` package to its own library
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Argument"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Argument$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.AstLocation"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.AstLocation$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.AstNode"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.AstNode$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.BigDecimalValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.BigDecimalValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.BigIntValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.BigIntValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.BooleanValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.BooleanValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Comment"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Comment$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ConditionalFragment"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Definition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Directive"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Directive$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.DirectiveDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.DirectiveDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.DirectiveLocation"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.DirectiveLocation$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Document"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Document$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumTypeExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumValueDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.EnumValueDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Field"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Field$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FieldDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FieldDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FloatValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FloatValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FragmentDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FragmentDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FragmentSpread"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.FragmentSpread$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InlineFragment"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InlineFragment$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputDocument"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputDocument$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputObjectTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputObjectTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputObjectTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputObjectTypeExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputValueDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InputValueDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.IntValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.IntValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InterfaceTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InterfaceTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InterfaceTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.InterfaceTypeExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ListType"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ListType$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ListValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ListValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NameValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NamedType"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NamedType$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NotNullType"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NotNullType$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NullValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.NullValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectField"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectField$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectLikeTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectTypeExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ObjectValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationType"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationType$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationType$Mutation$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationType$Query$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationType$Subscription$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.OperationTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ScalarTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ScalarTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ScalarTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ScalarTypeExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.ScalarValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.SchemaAstNode"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.SchemaDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.SchemaDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.SchemaExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.SchemaExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Selection"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.SelectionContainer"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.StringValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.StringValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Type"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.TypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.TypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.TypeSystemDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.TypeSystemExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.UnionTypeDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.UnionTypeDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.UnionTypeExtensionDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.UnionTypeExtensionDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.Value"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.VariableDefinition"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.VariableDefinition$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.VariableValue"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.VariableValue$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.WithArguments"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.WithComments"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.WithDescription"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.WithDirectives"),
ProblemFilters.exclude[MissingClassProblem]("sangria.ast.WithTrailingComments"),
ProblemFilters.exclude[MissingClassProblem]("sangria.parser.AggregateSourceMapper"),
ProblemFilters.exclude[MissingClassProblem]("sangria.parser.AggregateSourceMapper$"),
ProblemFilters.exclude[MissingClassProblem]("sangria.parser.DefaultSourceMapper"),
ProblemFilters.exclude[MissingClassProblem]("sangria.parser.SourceMapper"),

// added type annotation
ProblemFilters.exclude[IncompatibleResultTypeProblem](
"sangria.renderer.QueryRenderer.renderCommentLines"),
ProblemFilters.exclude[IncompatibleResultTypeProblem](
"sangria.renderer.QueryRenderer.renderCommentLines")
)

lazy val root = project
.in(file("."))
.withId("sangria-root")
.aggregate(core, benchmarks)
.aggregate(ast, core, benchmarks)
.settings(inThisBuild(projectInfo))
.settings(
scalacSettings ++ shellSettings ++ noPublishSettings
)
.disablePlugins(MimaPlugin)

lazy val ast = project
.in(file("modules/ast"))
.withId("sangria-ast")
.settings(scalacSettings ++ shellSettings)
.settings(
name := "sangria-ast",
description := "Scala GraphQL AST representation"
)
.disablePlugins(MimaPlugin)

lazy val core = project
.in(file("modules/core"))
.withId("sangria-core")
.dependsOn(ast)
.settings(scalacSettings ++ shellSettings)
.settings(
name := "sangria",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
package sangria.ast

import sangria.execution.InputDocumentMaterializer
import sangria.marshalling.{FromInput, InputUnmarshaller}
import sangria.parser.{AggregateSourceMapper, DeliveryScheme, SourceMapper}
import sangria.renderer.QueryRenderer
import sangria.validation.DocumentAnalyzer
import sangria.schema.{InputType, Schema}
import sangria.validation.TypeInfo
import sangria.visitor._

import scala.collection.immutable.ListMap

/** A complete GraphQL request operated on by a GraphQL service.
*
* @param definitions
* The definitions, which primarily constitute the document.
* @param sourceMapper
*
* @see
* [[https://spec.graphql.org/June2018/#Document]]
Expand Down Expand Up @@ -73,15 +63,6 @@ case class Document(
*/
def +(other: Document): Document = merge(other)

lazy val analyzer: DocumentAnalyzer = DocumentAnalyzer(this)

lazy val separateOperations: Map[Option[String], Document] = analyzer.separateOperations

def separateOperation(definition: OperationDefinition): Document =
analyzer.separateOperation(definition)
def separateOperation(operationName: Option[String]): Option[Document] =
analyzer.separateOperation(operationName)

override def equals(other: Any): Boolean = other match {
case that: Document =>
that.canEqual(this) &&
Expand Down Expand Up @@ -141,39 +122,9 @@ case class InputDocument(
*/
def +(other: InputDocument): InputDocument = merge(other)

def to[T](
schema: Schema[_, _],
inputType: InputType[T]
)(implicit fromInput: FromInput[T], scheme: DeliveryScheme[Vector[T]]): scheme.Result =
InputDocumentMaterializer.to(schema, this, inputType)

def to[T, Vars](
schema: Schema[_, _],
inputType: InputType[T],
variables: Vars
)(implicit
iu: InputUnmarshaller[Vars],
fromInput: FromInput[T],
scheme: DeliveryScheme[Vector[T]]): scheme.Result =
InputDocumentMaterializer.to(schema, this, inputType, variables)

def to[T](inputType: InputType[T])(implicit
fromInput: FromInput[T],
scheme: DeliveryScheme[Vector[T]]): scheme.Result =
InputDocumentMaterializer.to(this, inputType)

def to[T, Vars](
inputType: InputType[T],
variables: Vars = InputUnmarshaller.emptyMapVars
)(implicit
iu: InputUnmarshaller[Vars],
fromInput: FromInput[T],
scheme: DeliveryScheme[Vector[T]]): scheme.Result =
InputDocumentMaterializer.to(this, inputType, variables)

override def equals(other: Any): Boolean = other match {
case that: InputDocument =>
(that.canEqual(this)) &&
that.canEqual(this) &&
values == that.values &&
location == that.location
case _ => false
Expand All @@ -184,7 +135,7 @@ case class InputDocument(
}

object InputDocument {
def merge(documents: Traversable[InputDocument]): InputDocument =
def merge(documents: Iterable[InputDocument]): InputDocument =
InputDocument(documents.toVector.flatMap(_.values))
}

Expand Down Expand Up @@ -396,9 +347,7 @@ case class Argument(
* [[https://spec.graphql.org/June2018/#Value]]
* @group value
*/
sealed trait Value extends AstNode with WithComments {
override def renderPretty: String = QueryRenderer.render(this, QueryRenderer.PrettyInput)
}
sealed trait Value extends AstNode with WithComments

/** @group scalar
*/
Expand Down Expand Up @@ -798,22 +747,6 @@ sealed trait AstNode {
/** Location at which this node lexically begins in the GraphQL request source code. */
def location: Option[AstLocation]
def cacheKeyHash: Int = System.identityHashCode(this)

def renderPretty: String = QueryRenderer.render(this, QueryRenderer.Pretty)
def renderCompact: String = QueryRenderer.render(this, QueryRenderer.Compact)

def visit(visitor: AstVisitor): this.type =
AstVisitor.visit(this, visitor)

def visit(onEnter: AstNode => VisitorCommand, onLeave: AstNode => VisitorCommand): this.type =
AstVisitor.visit(this, onEnter, onLeave)

def visitAstWithTypeInfo(schema: Schema[_, _])(visitorFn: TypeInfo => AstVisitor): this.type =
AstVisitor.visitAstWithTypeInfo[this.type](schema, this)(visitorFn)

def visitAstWithState[S](schema: Schema[_, _], state: S)(
visitorFn: (TypeInfo, S) => AstVisitor): S =
AstVisitor.visitAstWithState(schema, this, state)(visitorFn)
}

/** @group typesystem
Expand Down Expand Up @@ -847,16 +780,3 @@ sealed trait TypeExtensionDefinition extends TypeSystemExtensionDefinition with
sealed trait ObjectLikeTypeExtensionDefinition extends TypeExtensionDefinition {
def fields: Vector[FieldDefinition]
}

object AstNode {
def withoutAstLocations[T <: AstNode](node: T, stripComments: Boolean = false): T = {
val enterComment = (_: Comment) =>
if (stripComments) VisitorCommand.Delete else VisitorCommand.Continue

visit[AstNode](
node,
Visit[Comment](enterComment),
VisitAnyField[AstNode, Option[AstLocation]]((_, _) => VisitorCommand.Transform(None)))
.asInstanceOf[T]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
package sangria.parser

import org.parboiled2.ParserInput
import sangria.ast.AstLocation
package sangria.ast

/** Set of functions that convert a [[AstLocation GraphQL source code location]] to human-readable
* strings.
Expand Down Expand Up @@ -30,15 +27,21 @@ trait SourceMapper {
def renderLinePosition(location: AstLocation, prefix: String = ""): String
}

/** [[SourceMapper]] for a single GraphQL document. */
class DefaultSourceMapper(val id: String, val parserInput: ParserInput) extends SourceMapper {
override lazy val source: String = parserInput.sliceString(0, parserInput.length)
trait SourceMapperInput {
def source: String
def getLine(line: Int): String
}

/** [[sangria.ast.SourceMapper]] for a single GraphQL document. */
class DefaultSourceMapper(val id: String, val sourceMapperInput: SourceMapperInput)
extends sangria.ast.SourceMapper {
override lazy val source: String = sourceMapperInput.source

override def renderLocation(location: AstLocation) =
s"(line ${location.line}, column ${location.column})"

override def renderLinePosition(location: AstLocation, prefix: String = ""): String =
parserInput
sourceMapperInput
.getLine(location.line)
.replace("\r", "") + "\n" + prefix + (" " * (location.column - 1)) + "^"
}
Expand Down
Loading

0 comments on commit 5a342c2

Please sign in to comment.