Skip to content

Commit

Permalink
Support abstract new syntax (#320)
Browse files Browse the repository at this point in the history
  • Loading branch information
oyvindberg authored Jun 1, 2021
1 parent c25b788 commit e780fba
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ class TsTypeFormatter(val keepComments: Boolean) {
case TsTypeLiteral(l) => lit(l)
case TsTypeObject(cs, members) => Comments.format(cs, keepComments) + s"{${members.map(member).mkString(", ")}}"
case TsTypeFunction(s) => s"${sig(s)}"
case TsTypeConstructor(f) => s"new ${apply(f)}"
case TsTypeConstructor(true, f) => s"abstract new ${apply(f)}"
case TsTypeConstructor(false, f) => s"new ${apply(f)}"
case TsTypeIs(ident, x) => s"${ident.value} is ${apply(x)}"
case TsTypeTuple(elems) => s"[${elems.map(tupleElement).mkString(", ")}]"
case TsTypeQuery(expr) => s"typeof ${qident(expr)}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ final case class TsTypeObject(comments: Comments, members: IArray[TsMember]) ext

final case class TsTypeFunction(signature: TsFunSig) extends TsType

final case class TsTypeConstructor(signature: TsTypeFunction) extends TsType
final case class TsTypeConstructor(isAbstract: Boolean, signature: TsTypeFunction) extends TsType

final case class TsTypeIs(ident: TsIdent, tpe: TsType) extends TsType

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class ImportType(stdNames: QualifiedName.StdNames) {
case TsTypeIntersect(types) =>
TypeRef.Intersection(types.map(apply(Wildcards.No, scope, importName)), NoComments)

case TsTypeConstructor(TsTypeFunction(sig)) =>
case TsTypeConstructor(_, TsTypeFunction(sig)) =>
newableFunction(scope, importName, sig, NoComments)

case keyof @ TsTypeKeyOf(of) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ final class ParserTests extends AnyFunSuite {
TsIdentSimple("ActionsClassConstructor"),
Empty,
TsTypeConstructor(
isAbstract = false,
TsTypeFunction(
TsFunSig(
NoComments,
Expand Down Expand Up @@ -2038,6 +2039,7 @@ type Readonly<T> = {
TsIdentSimple("T"),
Some(
TsTypeConstructor(
isAbstract = false,
TsTypeFunction(
TsFunSig(
NoComments,
Expand All @@ -2061,6 +2063,7 @@ type Readonly<T> = {
TsTypeExtends(
T,
TsTypeConstructor(
isAbstract = false,
TsTypeFunction(
TsFunSig(
NoComments,
Expand Down Expand Up @@ -2856,7 +2859,7 @@ export {};
shouldParseAs(content, TsParser.tsDeclFunction)(
TsDeclFunction(
NoComments,
true,
declared = true,
TsIdentSimple("isNotTestHost"),
TsFunSig(
NoComments,
Expand All @@ -2881,7 +2884,7 @@ export {};
shouldParseAs(content, TsParser.tsDeclFunction)(
TsDeclFunction(
NoComments,
true,
declared = true,
TsIdentSimple("foo"),
TsFunSig(
NoComments,
Expand All @@ -2900,4 +2903,62 @@ export {};
),
)
}

test("T extends abstract new") {
val content =
"type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never"

shouldParseAs(content, TsParser.tsDeclTypeAlias)(
TsDeclTypeAlias(
NoComments,
declared = false,
TsIdentSimple("ConstructorParameters"),
IArray(
TsTypeParam(
NoComments,
TsIdentSimple("T"),
Some(
TsTypeConstructor(
isAbstract = true,
TsTypeFunction(
TsFunSig(
NoComments,
IArray(),
IArray(TsFunParam(NoComments, TsIdentSimple("args"), Some(TsTypeRef.any))),
Some(TsTypeRef.any),
),
),
),
),
None,
),
),
TsTypeConditional(
TsTypeExtends(
T,
TsTypeConstructor(
isAbstract = true,
TsTypeFunction(
TsFunSig(
NoComments,
IArray(),
IArray(
TsFunParam(
NoComments,
TsIdentSimple("any"),
Some(TsTypeInfer(TsTypeParam(NoComments, TsIdentSimple("P"), None, None))),
),
),
Some(TsTypeRef.any),
),
),
),
),
TsTypeRef(NoComments, TsQIdent(IArray(TsIdentSimple("P"))), IArray()),
TsTypeRef.never,
),
CodePath.NoPath,
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ trait TreeTransformation[T] { self =>
val xx = enterTsTypeConstructor(withTree(t, x))(x)
val tt = withTree(t, xx)
xx match {
case TsTypeConstructor(_1) => TsTypeConstructor(visitTsTypeFunction(tt)(_1))
case TsTypeConstructor(_1, _2) => TsTypeConstructor(_1, visitTsTypeFunction(tt)(_2))
}
}
final def visitTsTypeConditional(t: T)(x: TsTypeConditional): TsTypeConditional = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ class TsParser(path: Option[(os.Path, Int)]) extends StdTokenParsers with Parser
((tsIdent <~ "is") ~ tsType ^^ TsTypeIs
| comments ~ tsMembers ^^ TsTypeObject
| tsTypeFunction
| "new" ~> tsTypeFunction ^^ TsTypeConstructor
| ("abstract".isDefined <~ "new") ~ tsTypeFunction ^^ TsTypeConstructor
| "unique" ~> "symbol" ~> success(TsTypeRef(NoComments, TsQIdent.symbol, Empty))
| "typeof" ~> qualifiedIdent ^^ TsTypeQuery
| tsTypeTuple
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ object ExtractClasses extends TransformLeaveMembers {
}

FollowAliases(scope)(tpe) match {
case TsTypeIntersect(types) => types.flatMap(findCtors(scope, loopDetector))
case TsTypeConstructor(TsTypeFunction(sig)) => IArray(sig)
case TsTypeIntersect(types) => types.flatMap(findCtors(scope, loopDetector))
case TsTypeConstructor(_, TsTypeFunction(sig)) => IArray(sig)
case tr: TsTypeRef =>
loopDetector.including(tr, scope) match {
case Left(()) => Empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ object ResolveTypeQueries extends TransformMembers with TransformLeaveClassMembe
object RewrittenClass {
def asTypeCtor(cls: TsDeclClass, cs: Comments, params: IArray[TsFunParam]) =
TsTypeConstructor(
isAbstract = false,
TsTypeFunction(
TsFunSig(
comments = cs,
Expand Down

0 comments on commit e780fba

Please sign in to comment.