-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1f5386b
commit 5c9e905
Showing
10 changed files
with
756 additions
and
5 deletions.
There are no files selected for viewing
111 changes: 111 additions & 0 deletions
111
codegen/src/main/scala/scommons/doctrine/Doctrine.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package scommons.doctrine | ||
|
||
import scommons.doctrine.DoctrineType._ | ||
import scommons.doctrine.raw.{DoctrineNativeType => NativeType, DoctrineNativeTypeName => TypeName, _} | ||
|
||
import scala.scalajs.js | ||
import scala.util.{Failure, Success, Try} | ||
|
||
/** | ||
* Doctrine is a JSDoc parser. | ||
* | ||
* @see https://www.npmjs.com/package/doctrine | ||
*/ | ||
object Doctrine { | ||
|
||
private[doctrine] var native = DoctrineNative | ||
|
||
def parse(jsDoc: String): DoctrineAnnotation = { | ||
val res = native.parse(jsDoc) | ||
|
||
DoctrineAnnotation( | ||
description = res.description, | ||
tags = res.tags.map { tag => | ||
val tagErrors = tag.errors.map(_.toList).getOrElse(Nil) | ||
val (maybeType, allErrors) = tag.`type`.toOption match { | ||
case None => (None, tagErrors) | ||
case Some(t) => | ||
Try(toDoctrineType(t)) match { | ||
case Success(value) => (Some(value), tagErrors) | ||
case Failure(ex) => (None, s"$ex" :: tagErrors) | ||
} | ||
} | ||
|
||
DoctrineTag( | ||
title = tag.title, | ||
description = tag.description, | ||
`type` = maybeType, | ||
name = tag.name.toOption, | ||
kind = tag.kind.toOption, | ||
errors = allErrors | ||
) | ||
}.toList | ||
) | ||
} | ||
|
||
private[doctrine] def toDoctrineType(t: NativeType): DoctrineType = t.`type` match { | ||
case TypeName.AllLiteral => AllLiteral | ||
case TypeName.ArrayType => new ArrayType( | ||
elements = toTypeList(t.elements) | ||
) | ||
case n@TypeName.FieldType => FieldType( | ||
key = getOrThrow(t.key, s"$n without key"), | ||
value = toTypeOpt(t.value) | ||
) | ||
case n@TypeName.FunctionType => new FunctionType( | ||
`this` = getOrThrow(t.`this`.map(toDoctrineType), s"$n without `this`"), | ||
`new` = getOrThrow(t.`new`.map(toDoctrineType), s"$n without `new`"), | ||
params = toTypeList(t.params), | ||
result = toTypeList(t.result) | ||
) | ||
case n@TypeName.NameExpression => NameExpression( | ||
name = getOrThrow(t.name, s"$n without name") | ||
) | ||
case n@TypeName.NonNullableType => NonNullableType( | ||
prefix = getOrThrow(t.prefix, s"$n without prefix"), | ||
expression = getOrThrow(t.expression.map(toDoctrineType), s"$n without expression") | ||
) | ||
case TypeName.NullableLiteral => NullableLiteral | ||
case n@TypeName.NullableType => NullableType( | ||
prefix = getOrThrow(t.prefix, s"$n without prefix"), | ||
expression = getOrThrow(t.expression.map(toDoctrineType), s"$n without expression") | ||
) | ||
case TypeName.NullLiteral => NullLiteral | ||
case n@TypeName.OptionalType => OptionalType( | ||
expression = getOrThrow(t.expression.map(toDoctrineType), s"$n without expression") | ||
) | ||
case n@TypeName.ParameterType => ParameterType( | ||
name = getOrThrow(t.name, s"$n without name"), | ||
expression = getOrThrow(t.expression.map(toDoctrineType), s"$n without expression") | ||
) | ||
case TypeName.RecordType => RecordType( | ||
fields = toTypeList(t.fields) | ||
) | ||
case TypeName.RestType => RestType( | ||
expression = toTypeOpt(t.expression) | ||
) | ||
case n@TypeName.TypeApplication => TypeApplication( | ||
expression = getOrThrow(t.expression.map(toDoctrineType), s"$n without expression"), | ||
applications = toTypeList(t.applications) | ||
) | ||
case TypeName.UndefinedLiteral => UndefinedLiteral | ||
case TypeName.UnionType => UnionType( | ||
elements = toTypeList(t.elements) | ||
) | ||
case TypeName.VoidLiteral => VoidLiteral | ||
case typeName => | ||
throw new IllegalStateException(s"Unknown Tag type: $typeName") | ||
} | ||
|
||
private def getOrThrow[T](maybeValue: js.UndefOr[T], error: => String): T = { | ||
maybeValue.getOrElse(throw new IllegalStateException(error)) | ||
} | ||
|
||
private def toTypeList(maybeArray: js.UndefOr[js.Array[NativeType]]): List[DoctrineType] = { | ||
maybeArray.map(_.toList).getOrElse(Nil).map(toDoctrineType) | ||
} | ||
|
||
private def toTypeOpt(maybeType: js.UndefOr[NativeType]): Option[DoctrineType] = { | ||
maybeType.map(toDoctrineType).toOption | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
codegen/src/main/scala/scommons/doctrine/DoctrineAnnotation.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package scommons.doctrine | ||
|
||
case class DoctrineAnnotation(description: String, tags: List[DoctrineTag]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package scommons.doctrine | ||
|
||
case class DoctrineTag(title: String, | ||
description: String, | ||
`type`: Option[DoctrineType], | ||
name: Option[String], | ||
kind: Option[String], | ||
errors: List[String]) |
44 changes: 44 additions & 0 deletions
44
codegen/src/main/scala/scommons/doctrine/DoctrineType.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package scommons.doctrine | ||
|
||
sealed trait DoctrineType | ||
|
||
object DoctrineType { | ||
|
||
case object AllLiteral extends DoctrineType | ||
|
||
case class ArrayType(elements: List[DoctrineType]) extends DoctrineType | ||
|
||
case class FieldType(key: String, value: Option[DoctrineType]) extends DoctrineType | ||
|
||
case class FunctionType(`this`: DoctrineType, | ||
`new`: DoctrineType, | ||
params: List[DoctrineType], | ||
result: List[DoctrineType]) extends DoctrineType | ||
|
||
case class NameExpression(name: String) extends DoctrineType | ||
|
||
case class NonNullableType(prefix: Boolean, expression: DoctrineType) extends DoctrineType | ||
|
||
case object NullableLiteral extends DoctrineType | ||
|
||
case class NullableType(prefix: Boolean, expression: DoctrineType) extends DoctrineType | ||
|
||
case object NullLiteral extends DoctrineType | ||
|
||
case class OptionalType(expression: DoctrineType) extends DoctrineType | ||
|
||
case class ParameterType(name: String, expression: DoctrineType) extends DoctrineType | ||
|
||
case class RecordType(fields: List[DoctrineType]) extends DoctrineType | ||
|
||
case class RestType(expression: Option[DoctrineType]) extends DoctrineType | ||
|
||
case class TypeApplication(expression: DoctrineType, | ||
applications: List[DoctrineType]) extends DoctrineType | ||
|
||
case object UndefinedLiteral extends DoctrineType | ||
|
||
case class UnionType(elements: List[DoctrineType]) extends DoctrineType | ||
|
||
case object VoidLiteral extends DoctrineType | ||
} |
82 changes: 82 additions & 0 deletions
82
codegen/src/main/scala/scommons/doctrine/raw/DoctrineNative.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package scommons.doctrine.raw | ||
|
||
import scala.scalajs.js | ||
import scala.scalajs.js.annotation.JSImport | ||
|
||
/** | ||
* Doctrine is a JSDoc parser. | ||
* | ||
* @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/doctrine/index.d.ts | ||
*/ | ||
@js.native | ||
@JSImport("doctrine", JSImport.Default) | ||
object DoctrineNative extends js.Object { | ||
|
||
def parse(jsDoc: String): DoctrineNativeAnnotation = js.native | ||
} | ||
|
||
@js.native | ||
trait DoctrineNativeAnnotation extends js.Object { | ||
|
||
def description: String | ||
def tags: js.Array[DoctrineNativeTag] | ||
} | ||
|
||
@js.native | ||
trait DoctrineNativeTag extends js.Object { | ||
|
||
def title: String | ||
def description: String | ||
def `type`: js.UndefOr[DoctrineNativeType] | ||
def name: js.UndefOr[String] | ||
def kind: js.UndefOr[String] | ||
def errors: js.UndefOr[js.Array[String]] | ||
} | ||
|
||
@js.native | ||
trait DoctrineNativeType extends js.Object { | ||
|
||
def `type`: DoctrineNativeTypeName | ||
|
||
def elements: js.UndefOr[js.Array[DoctrineNativeType]] | ||
|
||
def key: js.UndefOr[String] | ||
def value: js.UndefOr[DoctrineNativeType] | ||
|
||
def `this`: js.UndefOr[DoctrineNativeType] | ||
def `new`: js.UndefOr[DoctrineNativeType] | ||
def params: js.UndefOr[js.Array[DoctrineNativeType]] | ||
def result: js.UndefOr[js.Array[DoctrineNativeType]] | ||
|
||
def name: js.UndefOr[String] | ||
|
||
def prefix: js.UndefOr[Boolean] | ||
def expression: js.UndefOr[DoctrineNativeType] | ||
|
||
def fields: js.UndefOr[js.Array[DoctrineNativeType]] | ||
def applications: js.UndefOr[js.Array[DoctrineNativeType]] | ||
} | ||
|
||
@js.native | ||
sealed trait DoctrineNativeTypeName extends js.Object | ||
|
||
object DoctrineNativeTypeName { | ||
|
||
val AllLiteral: DoctrineNativeTypeName = "AllLiteral".asInstanceOf[DoctrineNativeTypeName] | ||
val ArrayType: DoctrineNativeTypeName = "ArrayType".asInstanceOf[DoctrineNativeTypeName] | ||
val FieldType: DoctrineNativeTypeName = "FieldType".asInstanceOf[DoctrineNativeTypeName] | ||
val FunctionType: DoctrineNativeTypeName = "FunctionType".asInstanceOf[DoctrineNativeTypeName] | ||
val NameExpression: DoctrineNativeTypeName = "NameExpression".asInstanceOf[DoctrineNativeTypeName] | ||
val NonNullableType: DoctrineNativeTypeName = "NonNullableType".asInstanceOf[DoctrineNativeTypeName] | ||
val NullableLiteral: DoctrineNativeTypeName = "NullableLiteral".asInstanceOf[DoctrineNativeTypeName] | ||
val NullableType: DoctrineNativeTypeName = "NullableType".asInstanceOf[DoctrineNativeTypeName] | ||
val NullLiteral: DoctrineNativeTypeName = "NullLiteral".asInstanceOf[DoctrineNativeTypeName] | ||
val OptionalType: DoctrineNativeTypeName = "OptionalType".asInstanceOf[DoctrineNativeTypeName] | ||
val ParameterType: DoctrineNativeTypeName = "ParameterType".asInstanceOf[DoctrineNativeTypeName] | ||
val RecordType: DoctrineNativeTypeName = "RecordType".asInstanceOf[DoctrineNativeTypeName] | ||
val RestType: DoctrineNativeTypeName = "RestType".asInstanceOf[DoctrineNativeTypeName] | ||
val TypeApplication: DoctrineNativeTypeName = "TypeApplication".asInstanceOf[DoctrineNativeTypeName] | ||
val UndefinedLiteral: DoctrineNativeTypeName = "UndefinedLiteral".asInstanceOf[DoctrineNativeTypeName] | ||
val UnionType: DoctrineNativeTypeName = "UnionType".asInstanceOf[DoctrineNativeTypeName] | ||
val VoidLiteral: DoctrineNativeTypeName = "VoidLiteral".asInstanceOf[DoctrineNativeTypeName] | ||
} |
Oops, something went wrong.