Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Convert.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ import org.jacodb.ets.model.EtsStrictNotEqExpr
import org.jacodb.ets.model.EtsStringConstant
import org.jacodb.ets.model.EtsStringLiteralType
import org.jacodb.ets.model.EtsStringType
import org.jacodb.ets.model.EtsSymbolType
import org.jacodb.ets.model.EtsSubExpr
import org.jacodb.ets.model.EtsThis
import org.jacodb.ets.model.EtsThrowStmt
Expand Down Expand Up @@ -742,6 +743,8 @@ fun TypeDto.toEtsType(): EtsType = when (this) {

StringTypeDto -> EtsStringType

SymbolTypeDto -> EtsSymbolType

is TupleTypeDto -> EtsTupleType(
types = types.map { it.toEtsType() },
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ internal val valueModule = SerializersModule {
internal val typeModule = SerializersModule {
polymorphic(TypeDto::class) {
subclass(BigIntTypeDto::class, BigIntTypeDto.serializer())
subclass(SymbolTypeDto::class, SymbolTypeDto.serializer())
}
polymorphicDefaultDeserializer(TypeDto::class) { RawTypeSerializer }
}
Expand Down
7 changes: 7 additions & 0 deletions jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ data object StringTypeDto : PrimitiveTypeDto {
get() = "string"
}

@Serializable
@SerialName("SymbolType")
data object SymbolTypeDto : PrimitiveTypeDto {
override val name: String
get() = "symbol"
}

@Serializable
@SerialName("NullType")
data object NullTypeDto : PrimitiveTypeDto {
Expand Down
16 changes: 16 additions & 0 deletions jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Type.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ interface EtsType : TypeName, CommonType {
error("Cannot handle ${type::class.java.simpleName}: $type")
}
fun visit(type: EtsStringType): R
fun visit(type: EtsSymbolType): R {
if (this is Default) return defaultVisit(type)
error("Cannot handle ${type::class.java.simpleName}: $type")
}
fun visit(type: EtsNullType): R
fun visit(type: EtsUndefinedType): R
fun visit(type: EtsVoidType): R
Expand Down Expand Up @@ -83,6 +87,7 @@ interface EtsType : TypeName, CommonType {
override fun visit(type: EtsNumberType): R = defaultVisit(type)
override fun visit(type: EtsBigIntType): R = defaultVisit(type)
override fun visit(type: EtsStringType): R = defaultVisit(type)
override fun visit(type: EtsSymbolType): R = defaultVisit(type)
override fun visit(type: EtsNullType): R = defaultVisit(type)
override fun visit(type: EtsUndefinedType): R = defaultVisit(type)
override fun visit(type: EtsVoidType): R = defaultVisit(type)
Expand Down Expand Up @@ -261,6 +266,17 @@ object EtsStringType : EtsPrimitiveType {
}
}

object EtsSymbolType : EtsPrimitiveType {
override val typeName: String
get() = "symbol"

override fun toString(): String = typeName

override fun <R> accept(visitor: EtsType.Visitor<R>): R {
return visitor.visit(this)
}
}

object EtsNullType : EtsPrimitiveType {
override val typeName: String
get() = "null"
Expand Down
76 changes: 76 additions & 0 deletions jacodb-ets/src/test/kotlin/org/jacodb/ets/test/EtsTsSymbolTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2022 UnitTestBot contributors (utbot.org)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jacodb.ets.test

import kotlin.io.path.createTempDirectory
import kotlin.io.path.exists
import kotlin.io.path.readText
import kotlin.io.path.writeText
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.jacodb.ets.dto.EtsFileDto
import org.jacodb.ets.dto.dtoModule
import org.jacodb.ets.dto.toEtsFile
import org.jacodb.ets.utils.DEFAULT_ARK_CLASS_NAME
import org.jacodb.ets.utils.EtsIrProvider
import org.jacodb.ets.utils.generateEtsIR
import org.junit.jupiter.api.Test
import org.jacodb.ets.dto.SymbolTypeDto
import org.jacodb.ets.model.EtsSymbolType

class EtsTsSymbolTest {
companion object {
/** Run the PRODUCTION integration path: generateEtsIR + EtsFileDto.loadFromJson. */
private fun runFrontend(source: String, fileName: String = "test.ts"): EtsFileDto {
val dir = createTempDirectory("ts-frontend-test")
val inputPath = dir.resolve(fileName)
inputPath.writeText(source)

val outputPath = generateEtsIR(
inputPath,
isProject = false,
timeout = null,
provider = EtsIrProvider.TS_FRONTEND,
)
assertTrue(outputPath.exists(), "ts-frontend did not produce output: $outputPath")

return EtsFileDto.loadFromJson(outputPath.readText())
}
}

@Test
fun `symbol parameter and return types survive frontend JSON and model conversion`() {
val frontendDto = runFrontend(source = "export function same(value: symbol): symbol { return value; }")
val roundTripped = EtsFileDto.loadFromJson(
Json { serializersModule = dtoModule }.encodeToString(frontendDto),
)
val methodDto = roundTripped.classes.single { it.signature.name == DEFAULT_ARK_CLASS_NAME }
.methods.single { it.signature.name == "same" }

assertEquals(SymbolTypeDto, methodDto.signature.parameters.single().type)
assertEquals(SymbolTypeDto, methodDto.signature.returnType)

val modelMethod = roundTripped.toEtsFile().classes.single { it.name == DEFAULT_ARK_CLASS_NAME }
.methods.single { it.name == "same" }

assertEquals(EtsSymbolType, modelMethod.signature.parameters.single().type)
assertEquals(EtsSymbolType, modelMethod.signature.returnType)
}

}
6 changes: 6 additions & 0 deletions jacodb-ets/ts-frontend/src/dto/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export type TypeDto =
| NumberTypeDto
| BigIntTypeDto
| StringTypeDto
| SymbolTypeDto
| NullTypeDto
| UndefinedTypeDto
| LiteralTypeDto
Expand Down Expand Up @@ -127,6 +128,10 @@ export interface StringTypeDto {
readonly _: "StringType";
}

export interface SymbolTypeDto {
readonly _: "SymbolType";
}

export interface NullTypeDto {
readonly _: "NullType";
}
Expand Down Expand Up @@ -185,5 +190,6 @@ export const BOOLEAN_TYPE: BooleanTypeDto = { _: "BooleanType" };
export const NUMBER_TYPE: NumberTypeDto = { _: "NumberType" };
export const BIGINT_TYPE: BigIntTypeDto = { _: "BigIntType" };
export const STRING_TYPE: StringTypeDto = { _: "StringType" };
export const SYMBOL_TYPE: SymbolTypeDto = { _: "SymbolType" };
export const NULL_TYPE: NullTypeDto = { _: "NullType" };
export const UNDEFINED_TYPE: UndefinedTypeDto = { _: "UndefinedType" };
4 changes: 4 additions & 0 deletions jacodb-ets/ts-frontend/src/types/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
NULL_TYPE,
NUMBER_TYPE,
STRING_TYPE,
SYMBOL_TYPE,
TypeDto,
UNDEFINED_TYPE,
UNKNOWN_TYPE,
Expand Down Expand Up @@ -169,6 +170,8 @@ export class TypeConverter {
return BIGINT_TYPE;
case ts.SyntaxKind.StringKeyword:
return STRING_TYPE;
case ts.SyntaxKind.SymbolKeyword:
return SYMBOL_TYPE;
case ts.SyntaxKind.ObjectKeyword:
return this.materializeStructuralClass(node, [], depth, substitutions);
case ts.SyntaxKind.VoidKeyword:
Expand Down Expand Up @@ -569,6 +572,7 @@ export class TypeConverter {
if (flags & ts.TypeFlags.NumberLike) return NUMBER_TYPE;
if (flags & ts.TypeFlags.BigIntLike) return BIGINT_TYPE;
if (flags & ts.TypeFlags.StringLike) return STRING_TYPE;
if (flags & ts.TypeFlags.ESSymbolLike) return SYMBOL_TYPE;

if (flags & ts.TypeFlags.TypeParameter) {
return { _: "GenericType", name: this.typeName(type) };
Expand Down
2 changes: 2 additions & 0 deletions jacodb-ets/ts-frontend/test/types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe("convertTypeNode (annotations)", () => {
expect(annotationOf("let x: undefined;")).toEqual({ _: "UndefinedType" });
expect(annotationOf("let x: never;")).toEqual({ _: "NeverType" });
expect(annotationOf("let x: bigint;")).toEqual({ _: "BigIntType" });
expect(annotationOf("let x: symbol;")).toEqual({ _: "SymbolType" });
});

it("converts literal types with bare JSON primitives", () => {
Expand Down Expand Up @@ -342,6 +343,7 @@ describe("typeOfNode (inference)", () => {
expect(inferredOf(`let x = "s";`)).toEqual({ _: "StringType" });
expect(inferredOf("let x = true;")).toEqual({ _: "BooleanType" });
expect(inferredOf("let x = 1n;")).toEqual({ _: "BigIntType" });
expect(inferredOf("let x = Symbol();")).toEqual({ _: "SymbolType" });
});

it("keeps literal types for const-declarations", () => {
Expand Down
Loading