From 435bd65bf5c2aae185019e72166589b1421d968e Mon Sep 17 00:00:00 2001 From: Charlie Harding Date: Tue, 28 Apr 2020 15:35:07 +0100 Subject: [PATCH] [DSL] Remove target blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These aren’t being used, and as we always generate OpenAPI specs, there isn’t really any need for them until we also generate code from the OpenAPI specs. At the moment they’re just a way of specifying a language name, which may be useful one day, so I’ll leave a PR in for their readdition. --- .../DockerGeneratorIntegrationTest.scala | 1 - .../scala/temple/DSL/semantics/Analyzer.scala | 19 +++------------- .../temple/DSL/semantics/ServiceRenamer.scala | 10 --------- .../temple/DSL/semantics/Validator.scala | 13 ++++------- .../scala/temple/DSL/syntax/DSLRootItem.scala | 2 +- src/main/scala/temple/ast/Metadata.scala | 14 +----------- src/main/scala/temple/ast/TargetBlock.scala | 8 ------- src/main/scala/temple/ast/Templefile.scala | 7 ++---- .../DSL/semantics/SemanticAnalyzerTest.scala | 22 ------------------- .../DSL/semantics/TempleBlockTest.scala | 4 ---- .../temple/DSL/semantics/ValidatorTest.scala | 9 ++++---- .../temple/builder/BuilderTestData.scala | 2 -- 12 files changed, 15 insertions(+), 96 deletions(-) delete mode 100644 src/main/scala/temple/ast/TargetBlock.scala diff --git a/src/it/scala/temple/generate/docker/DockerGeneratorIntegrationTest.scala b/src/it/scala/temple/generate/docker/DockerGeneratorIntegrationTest.scala index 785c9a60a..d705df0d4 100644 --- a/src/it/scala/temple/generate/docker/DockerGeneratorIntegrationTest.scala +++ b/src/it/scala/temple/generate/docker/DockerGeneratorIntegrationTest.scala @@ -48,7 +48,6 @@ class DockerGeneratorIntegrationTest extends HadolintSpec with Matchers with Bef val templefile = Templefile( "ExampleProject", ProjectBlock(), - targets = Map(), services = Map("ComplexService" -> DockerGeneratorIntegrationTestData.sampleService), ) diff --git a/src/main/scala/temple/DSL/semantics/Analyzer.scala b/src/main/scala/temple/DSL/semantics/Analyzer.scala index cf2e6457b..fe66e2f5e 100644 --- a/src/main/scala/temple/DSL/semantics/Analyzer.scala +++ b/src/main/scala/temple/DSL/semantics/Analyzer.scala @@ -181,11 +181,6 @@ object Analyzer { registerKeywordWithContext("writable", "by", TokenArgType)(Writable) } - /** A parser of Metadata items that can occur in target blocks */ - private val parseTargetMetadata = new MetadataParser[TargetMetadata] { - registerKeywordWithContext("language", TokenArgType)(TargetLanguage) - } - /** * Parse a service block from a list of entries into the distinct attributes, metadatas and structs * @@ -241,9 +236,6 @@ object Analyzer { private def parseProjectBlock(entries: Seq[Entry])(implicit context: SemanticContext): ProjectBlock = ProjectBlock(parseMetadataBlock(entries, parseProjectMetadata)) - private def parseTargetBlock(entries: Seq[Entry])(implicit context: SemanticContext): TargetBlock = - TargetBlock(parseMetadataBlock(entries, parseTargetMetadata)) - private def parseStructBlock(entries: Seq[Entry])(implicit context: SemanticContext): StructBlock = { val attributes = mutable.LinkedHashMap[String, AbstractAttribute]() val metadata = parseBlockWithMetadata(entries, parseStructMetadata) { @@ -257,15 +249,13 @@ object Analyzer { /** * Turns an AST of a Templefile into a semantic representation * @param templefile the AST parsed from the Templefile - * @return A semantic representation of the project, as well as all the targets and services, defined in the - * Templefile + * @return A semantic representation of the project, as well as all the services, defined in the Templefile * @throws SemanticParsingException when there is no project information, as well as when any of the definitions are * malformed */ private[semantics] def parseSemantics(templefile: syntax.Templefile): Templefile = { var projectNameBlock: Option[(String, ProjectBlock)] = None - val targets = mutable.LinkedHashMap[String, TargetBlock]() val services = mutable.LinkedHashMap[String, ServiceBlock]() templefile.foreach { @@ -278,8 +268,6 @@ object Analyzer { projectNameBlock.fold { projectNameBlock = Some(key -> parseProjectBlock(entries)) } { case (str, _) => context.fail(s"Second project found in addition to $str,") } - // TODO: error message - case "target" => targets.safeInsert(key -> parseTargetBlock(entries)) case _ => context.fail(s"Unknown block type") } @@ -289,14 +277,13 @@ object Analyzer { throw new SemanticParsingException("Temple file has no project block") } - Templefile(projectName, projectBlock, targets.to(ListMap), services.to(ListMap)) + Templefile(projectName, projectBlock, services.to(ListMap)) } /** * Turns an AST of a Templefile into a semantic representation and validates it * @param templefileAST the AST parsed from the Templefile - * @return A semantic representation of the project, as well as all the targets and services, defined in the - * Templefile + * @return A semantic representation of the project, as well as all the services, defined in the Templefile * @throws SemanticParsingException when there is no project information, as well as when any of the definitions are * malformed or the contents is not valid */ diff --git a/src/main/scala/temple/DSL/semantics/ServiceRenamer.scala b/src/main/scala/temple/DSL/semantics/ServiceRenamer.scala index 5c4c38e51..2a2affb5b 100644 --- a/src/main/scala/temple/DSL/semantics/ServiceRenamer.scala +++ b/src/main/scala/temple/DSL/semantics/ServiceRenamer.scala @@ -9,12 +9,6 @@ case class ServiceRenamer(renamingMap: Map[String, String]) { private def rename(string: String): String = renamingMap.getOrElse(string, { throw new NoSuchElementException(s"Key $string missing from renaming map") }) - private def renameTargetBlock(block: TargetBlock): TargetBlock = - // currently `identity`, as language is the only metadata - TargetBlock(block.metadata.map { - case language: Metadata.TargetLanguage => language - }) - private def renameProjectBlock(block: ProjectBlock): ProjectBlock = // currently `identity`, as no metadata contains a service name ProjectBlock( @@ -29,9 +23,6 @@ case class ServiceRenamer(renamingMap: Map[String, String]) { }, ) - private def renameTargetBlocks(targets: Map[String, TargetBlock]): Map[String, TargetBlock] = - targets.view.mapValues(renameTargetBlock).toMap - private def renameServiceMetadata(metadata: Metadata.ServiceMetadata): Metadata.ServiceMetadata = metadata match { // rename any services referenced in #uses case Metadata.Uses(services) => Metadata.Uses(services.map(rename)) @@ -90,7 +81,6 @@ case class ServiceRenamer(renamingMap: Map[String, String]) { Templefile( templefile.projectName, renameProjectBlock(templefile.projectBlock), - renameTargetBlocks(templefile.targets), renameServiceBlocks(templefile.services), ) } diff --git a/src/main/scala/temple/DSL/semantics/Validator.scala b/src/main/scala/temple/DSL/semantics/Validator.scala index 92b328b83..6a8757366 100644 --- a/src/main/scala/temple/DSL/semantics/Validator.scala +++ b/src/main/scala/temple/DSL/semantics/Validator.scala @@ -143,7 +143,6 @@ private class Validator private (templefile: Templefile) { errors += context.errorMessage(s"Multiple occurrences of ${classTag[T].runtimeClass.getSimpleName} metadata") metadata foreach { - case _: Metadata.TargetLanguage => assertUnique[Metadata.TargetLanguage]() case _: Metadata.ServiceLanguage => assertUnique[Metadata.ServiceLanguage]() case _: Metadata.Database => assertUnique[Metadata.Database]() case _: Metadata.AuthMethod => @@ -221,8 +220,8 @@ private class Validator private (templefile: Templefile) { case FloatType(_, _, _) => // all good } - private def validateBlockOfMetadata[T <: Metadata](target: TempleBlock[T], context: SemanticContext): Unit = - validateMetadata(target.metadata, context) + private def validateBlockOfMetadata[T <: Metadata](block: TempleBlock[T], context: SemanticContext): Unit = + validateMetadata(block.metadata, context) private val referenceCycles: Set[Set[String]] = { val graph = templefile.providedBlockNames.map { blockName => @@ -239,17 +238,13 @@ private class Validator private (templefile: Templefile) { newServices = templefile.services.transform { case (name, service) => validateService(name, service, context :+ name) } - templefile.targets.foreach { - case (name, block) => validateBlockOfMetadata(block, context :+ name) - } validateBlockOfMetadata(templefile.projectBlock, context :+ s"${templefile.projectName} project") val rootNames: Seq[(String, String)] = Seq(templefile.projectName -> "project") ++ templefile.services.keys.map(_ -> "service") ++ - templefile.structNames.map(_ -> "struct") ++ - templefile.targets.keys.map(_ -> "target") + templefile.structNames.map(_ -> "struct") val duplicates = rootNames .groupBy(_._1) .collect { case (name, repeats) if repeats.sizeIs > 1 => (name, repeats.map(_._2)) } @@ -261,7 +256,7 @@ private class Validator private (templefile: Templefile) { val suffix = if (duplicates.sizeIs == 1) s"duplicate found: $duplicateString" else s"duplicates found: $duplicateString" - errors += context.errorMessage(s"Project, targets and structs must be globally unique, $suffix") + errors += context.errorMessage(s"Project, services and structs must be globally unique, $suffix") } rootNames.collect { case (name, location) if !name.head.isUpper => diff --git a/src/main/scala/temple/DSL/syntax/DSLRootItem.scala b/src/main/scala/temple/DSL/syntax/DSLRootItem.scala index 88cd851c5..bbcd46f6a 100644 --- a/src/main/scala/temple/DSL/syntax/DSLRootItem.scala +++ b/src/main/scala/temple/DSL/syntax/DSLRootItem.scala @@ -2,7 +2,7 @@ package temple.DSL.syntax import temple.utils.StringUtils.indent -/** An item at the root of the Templefile, e.g. services and targets */ +/** An item at the root of the Templefile, e.g. services */ case class DSLRootItem(key: String, tag: String, entries: Seq[Entry]) extends Entry(s"$tag block ($key)") { override def toString: String = { diff --git a/src/main/scala/temple/ast/Metadata.scala b/src/main/scala/temple/ast/Metadata.scala index 08672ea6b..bb8754b9f 100644 --- a/src/main/scala/temple/ast/Metadata.scala +++ b/src/main/scala/temple/ast/Metadata.scala @@ -3,26 +3,14 @@ package temple.ast import temple.collection.enumeration._ import temple.errors.ErrorHandlingContext -/** A piece of metadata modifying a service/project/target block */ +/** A piece of metadata modifying a service/project block */ sealed trait Metadata object Metadata { - sealed trait TargetMetadata extends Metadata sealed trait ProjectMetadata extends Metadata sealed trait ServiceMetadata extends Metadata sealed trait StructMetadata extends ServiceMetadata - sealed abstract class TargetLanguage private (name: String, aliases: String*) - extends EnumEntry(name, aliases) - with TargetMetadata - - object TargetLanguage extends Enum[TargetLanguage] { - val values: IndexedSeq[TargetLanguage] = findValues - - case object Swift extends TargetLanguage("Swift") - case object JavaScript extends TargetLanguage("JavaScript", "js") - } - sealed abstract class ServiceLanguage private (name: String, aliases: String*) extends EnumEntry(name, aliases) with ServiceMetadata diff --git a/src/main/scala/temple/ast/TargetBlock.scala b/src/main/scala/temple/ast/TargetBlock.scala deleted file mode 100644 index af93c6621..000000000 --- a/src/main/scala/temple/ast/TargetBlock.scala +++ /dev/null @@ -1,8 +0,0 @@ -package temple.ast - -import temple.ast.Metadata.TargetMetadata - -/** A block describing one client to generate code for */ -case class TargetBlock( - metadata: Seq[TargetMetadata] = Nil, -) extends TempleBlock[TargetMetadata] diff --git a/src/main/scala/temple/ast/Templefile.scala b/src/main/scala/temple/ast/Templefile.scala index daf7213f1..e19771ef9 100644 --- a/src/main/scala/temple/ast/Templefile.scala +++ b/src/main/scala/temple/ast/Templefile.scala @@ -1,9 +1,7 @@ package temple.ast import temple.ast.AbstractServiceBlock._ - -import temple.ast.Metadata.{Metrics, ServiceAuth} - +import temple.ast.Metadata.Metrics import temple.ast.Templefile.Ports import temple.builder.project.ProjectConfig @@ -14,11 +12,10 @@ import scala.reflect.ClassTag case class Templefile( projectName: String, projectBlock: ProjectBlock = ProjectBlock(), - targets: Map[String, TargetBlock] = Map(), services: Map[String, ServiceBlock] = Map(), ) extends TempleNode { // Inform every child node of their parent, so that they can access the project information - for (block <- Iterator(projectBlock) ++ targets.valuesIterator ++ services.valuesIterator) { + for (block <- Iterator(projectBlock) ++ services.valuesIterator) { block.setParent(this) } diff --git a/src/test/scala/temple/DSL/semantics/SemanticAnalyzerTest.scala b/src/test/scala/temple/DSL/semantics/SemanticAnalyzerTest.scala index e44ccc03d..55ad9adfc 100644 --- a/src/test/scala/temple/DSL/semantics/SemanticAnalyzerTest.scala +++ b/src/test/scala/temple/DSL/semantics/SemanticAnalyzerTest.scala @@ -397,28 +397,6 @@ class SemanticAnalyzerTest extends FlatSpec with Matchers { parseSemantics(Seq(DSLRootItem("Test", "project", Seq()), DSLRootItem("other", "badItem", Seq()))) } should have message "Unknown block type in other badItem" } - - it should "parse target blocks correctly" in { - noException should be thrownBy { - parseSemantics( - mkTemplefileAST(DSLRootItem("mobile", "target", Seq(Entry.Metadata("language", Args(Seq(TokenArg("swift"))))))), - ) - } - - the[SemanticParsingException] thrownBy { - parseSemantics( - mkTemplefileAST(DSLRootItem("mobile", "target", Seq(Entry.Metadata("badKey", Args(Seq(TokenArg("swift"))))))), - ) - } should have message "No valid metadata badKey in mobile target" - - the[SemanticParsingException] thrownBy { - parseSemantics( - mkTemplefileAST( - DSLRootItem("mobile", "target", Seq(Entry.Attribute("field", syntax.AttributeType.Primitive("int")))), - ), - ) - } should have message "Found unexpected attribute: `field: int;` in mobile target" - } } object SemanticAnalyzerTest { diff --git a/src/test/scala/temple/DSL/semantics/TempleBlockTest.scala b/src/test/scala/temple/DSL/semantics/TempleBlockTest.scala index 5d5a1e322..f2b775966 100644 --- a/src/test/scala/temple/DSL/semantics/TempleBlockTest.scala +++ b/src/test/scala/temple/DSL/semantics/TempleBlockTest.scala @@ -12,10 +12,6 @@ class TempleBlockTest extends FlatSpec with Matchers { val projectBlock = ProjectBlock(Seq(Metadata.Database.Postgres)) projectBlock.lookupLocalMetadata[Metadata.ServiceLanguage] shouldBe None projectBlock.lookupLocalMetadata[Metadata.Database] shouldBe Some(Metadata.Database.Postgres) - - val targetBlock = TargetBlock(Seq(Metadata.TargetLanguage.JavaScript)) - targetBlock.lookupLocalMetadata[Metadata.TargetLanguage] shouldBe Some(Metadata.TargetLanguage.JavaScript) - targetBlock.lookupLocalMetadata[Metadata.Database] shouldBe None } it should "fail to lookupMetadata without being in a project file" in { diff --git a/src/test/scala/temple/DSL/semantics/ValidatorTest.scala b/src/test/scala/temple/DSL/semantics/ValidatorTest.scala index 8e459aee5..6f60b744b 100644 --- a/src/test/scala/temple/DSL/semantics/ValidatorTest.scala +++ b/src/test/scala/temple/DSL/semantics/ValidatorTest.scala @@ -63,14 +63,13 @@ class ValidatorTest extends FlatSpec with Matchers { ), ), ) shouldBe Set( - "Project, targets and structs must be globally unique, duplicate found: User (service, struct)", + "Project, services and structs must be globally unique, duplicate found: User (service, struct)", ) validationErrors( Templefile( "Box", projectBlock = ProjectBlock(Seq(Database.Postgres)), - targets = Map("User" -> TargetBlock(Seq(TargetLanguage.JavaScript))), services = Map( "User" -> ServiceBlock( attributes = Map( @@ -90,7 +89,7 @@ class ValidatorTest extends FlatSpec with Matchers { ), ), ) shouldBe Set( - "Project, targets and structs must be globally unique, duplicates found: Box (project, struct), User (service, struct, target)", + "Project, services and structs must be globally unique, duplicates found: Box (project, struct), User (service, struct)", ) validationErrors( @@ -106,7 +105,7 @@ class ValidatorTest extends FlatSpec with Matchers { ), ), ) shouldBe Set( - "Project, targets and structs must be globally unique, duplicate found: User (project, service)", + "Project, services and structs must be globally unique, duplicate found: User (project, service)", ) } @@ -467,7 +466,7 @@ class ValidatorTest extends FlatSpec with Matchers { ) } should have message { """An error was encountered while validating the Templefile - |Project, targets and structs must be globally unique, duplicate found: User (service, struct)""".stripMargin + |Project, services and structs must be globally unique, duplicate found: User (service, struct)""".stripMargin } the[SemanticParsingException] thrownBy { diff --git a/src/test/scala/temple/builder/BuilderTestData.scala b/src/test/scala/temple/builder/BuilderTestData.scala index 7c6aa38dc..daaef911a 100644 --- a/src/test/scala/temple/builder/BuilderTestData.scala +++ b/src/test/scala/temple/builder/BuilderTestData.scala @@ -44,7 +44,6 @@ object BuilderTestData { val simpleTemplefile: Templefile = Templefile( "TestProject", ProjectBlock(Seq(ServiceLanguage.Go)), - targets = Map(), services = Map("TestService" -> sampleService), ) @@ -80,7 +79,6 @@ object BuilderTestData { val complexTemplefile: Templefile = Templefile( "TestComplexProject", ProjectBlock(Seq(ServiceLanguage.Go)), - targets = Map(), services = Map("TestComplexService" -> sampleComplexService), ) }