From cac286c91580e6032ac1ec57e3f7518732477172 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Fri, 26 Nov 2021 09:18:12 +0000 Subject: [PATCH] [JS IR] Access with exported properties by its name, not accessor [JS IR] Export properties to ts as getter/setter, not fields [JS IR] Fix typescript tests Merge-request: KT-MR-5074 --- .../ir/backend/js/export/ExportModel.kt | 1 + .../backend/js/export/ExportModelGenerator.kt | 6 +- .../js/export/ExportModelToTsDeclarations.kt | 21 ++++-- .../js/transformers/irToJs/jsAstUtils.kt | 2 +- .../kotlin/ir/backend/js/utils/IrJsUtils.kt | 3 + js/js.translator/testData/package-lock.json | 6 +- js/js.translator/testData/package.json | 2 +- .../classes/inner-class.d.ts | 16 ++--- .../constructors/constructors.d.ts | 12 ++-- .../declarations/declarations.d.ts | 57 ++++++++-------- .../escapedDeclarations.d.ts | 23 ++++--- .../implicitExport/declarations.d.ts | 5 +- .../inheritance/inheritance.d.ts | 64 +++++++++-------- .../inheritance/inheritance__main.js | 68 ++++++++++++++----- .../inheritance/inheritance__main.ts | 45 +++++++----- .../moduleSystems/commonjs.d.ts | 2 +- .../moduleSystems/plain.d.ts | 2 +- .../typescript-export/moduleSystems/umd.d.ts | 2 +- .../namespaces/namespaces.d.ts | 6 +- .../selectiveExport/selectiveExport.d.ts | 4 +- .../visibility/visibility.d.ts | 26 +++---- 21 files changed, 228 insertions(+), 145 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModel.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModel.kt index 5405d5ef6d2..874264884ae 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModel.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModel.kt @@ -56,6 +56,7 @@ class ExportedProperty( val isStatic: Boolean = false, val isAbstract: Boolean, val isProtected: Boolean, + val isField: Boolean, val irGetter: IrFunction?, val irSetter: IrFunction?, val exportedObject: ExportedClass? = null, diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt index a9febeea511..6aa86742db8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt @@ -144,6 +144,7 @@ class ExportModelGenerator( isStatic = false, isAbstract = parentClass?.isInterface == false && property.modality == Modality.ABSTRACT, isProtected = property.visibility == DescriptorVisibilities.PROTECTED, + isField = parentClass?.isInterface == true, irGetter = property.getter, irSetter = property.setter ) @@ -169,6 +170,7 @@ class ExportModelGenerator( isProtected = false, irGetter = null, irSetter = null, + isField = false, ) val nameProperty = fakeProperty( @@ -195,7 +197,8 @@ class ExportModelGenerator( isProtected = parentClass.visibility == DescriptorVisibilities.PROTECTED, irGetter = context.mapping.enumEntryToGetInstanceFun[irEnumEntry] ?: error("Unable to find get instance fun for ${field.fqNameWhenAvailable}"), - irSetter = null + irSetter = null, + isField = false, ) } @@ -385,6 +388,7 @@ class ExportModelGenerator( irGetter = context.mapping.objectToGetInstanceFunction[klass]!!, irSetter = null, exportedObject = exportedClass, + isField = false, ) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToTsDeclarations.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToTsDeclarations.kt index d7edb983fe8..ca466d4af4b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToTsDeclarations.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelToTsDeclarations.kt @@ -24,7 +24,7 @@ fun wrapTypeScript(name: String, moduleKind: ModuleKind, dts: String): String { else -> "declare " } val types = """ - type Nullable = T | null | undefined + type Nullable = T | null | undefined ${declareKeyword}const __doNotImplementIt: unique symbol type __doNotImplementIt = typeof __doNotImplementIt """.trimIndent().prependIndent(moduleKind.indent) + "\n" @@ -105,7 +105,7 @@ fun ExportedDeclaration.toTypeScript(indent: String, prefix: String = ""): Strin is ExportedProperty -> { val visibility = if (isProtected) "protected " else "" val keyword = when { - isMember -> (if (isAbstract) "abstract " else "") + (if (!mutable) "readonly " else "") + isMember -> (if (isAbstract) "abstract " else "") else -> if (mutable) "let " else "const " } val possibleStatic = if (isMember && isStatic) "static " else "" @@ -114,7 +114,18 @@ fun ExportedDeclaration.toTypeScript(indent: String, prefix: String = ""): Strin isMember && containsUnresolvedChar -> "\"$name\"" else -> name } - if (!isMember && containsUnresolvedChar) "" else "$prefix$visibility$possibleStatic$keyword$memberName: ${type.toTypeScript(indent)};" + val typeToTypeScript = type.toTypeScript(indent) + if (isMember && !isField) { + val getter = "$prefix$visibility$possibleStatic${keyword}get $memberName(): $typeToTypeScript;" + if (!mutable) getter + else getter + "\n" + "$indent$prefix$visibility$possibleStatic${keyword}set $memberName(value: $typeToTypeScript);" + } else { + if (!isMember && containsUnresolvedChar) "" + else { + val readonly = if (isMember && !mutable) "readonly " else "" + "$prefix$visibility$possibleStatic$keyword$readonly$memberName: $typeToTypeScript;" + } + } } is ExportedClass -> { @@ -202,8 +213,9 @@ fun List.withMagicProperty(): List { isStatic = false, isAbstract = false, isProtected = false, + isField = true, irGetter = null, - irSetter = null + irSetter = null, ) ) } @@ -250,6 +262,7 @@ fun ExportedClass.toReadonlyProperty(): ExportedProperty { isStatic = false, isAbstract = false, isProtected = false, + isField = false, irGetter = null, irSetter = null ) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt index 50f8535d522..464b39cd4a2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt @@ -124,7 +124,7 @@ fun translateCall( val property = function.correspondingPropertySymbol?.owner if ( property != null && - (property.isEffectivelyExternal() || property.isExportedInterfaceMember()) + (property.isEffectivelyExternal() || property.isExportedMember()) ) { val propertyName = context.getNameForProperty(property) val nameRef = when (jsDispatchReceiver) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt index 27eda221734..c428efec871 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt @@ -11,6 +11,9 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.util.parentClassOrNull +fun IrDeclaration.isExportedMember() = + parentClassOrNull.let { it is IrClass && it.isJsExport() } + fun IrDeclaration?.isExportedClass() = this is IrClass && kind.isClass && isJsExport() diff --git a/js/js.translator/testData/package-lock.json b/js/js.translator/testData/package-lock.json index 016df6286e5..25c90bc32b7 100644 --- a/js/js.translator/testData/package-lock.json +++ b/js/js.translator/testData/package-lock.json @@ -276,9 +276,9 @@ } }, "typescript": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", - "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", "dev": true }, "wrappy": { diff --git a/js/js.translator/testData/package.json b/js/js.translator/testData/package.json index bc1cd39c895..553bd592f8a 100644 --- a/js/js.translator/testData/package.json +++ b/js/js.translator/testData/package.json @@ -5,7 +5,7 @@ "devDependencies": { "mocha": "3.2.0", "mocha-teamcity-reporter": "1.1.1", - "typescript": "^3.5.3" + "typescript": "^4.5.2" }, "scripts": { "runOnTeamcity": "mocha --reporter mocha-teamcity-reporter", diff --git a/js/js.translator/testData/typescript-export/classes/inner-class.d.ts b/js/js.translator/testData/typescript-export/classes/inner-class.d.ts index 6fa28923ddc..b0a4d559303 100644 --- a/js/js.translator/testData/typescript-export/classes/inner-class.d.ts +++ b/js/js.translator/testData/typescript-export/classes/inner-class.d.ts @@ -5,28 +5,28 @@ declare namespace JS_TESTS { namespace foo { class TestInner { constructor(a: string); - readonly a: string; - readonly Inner: { + get a(): string; + get Inner(): { new(a: string): TestInner.Inner; } & typeof TestInner.Inner; } namespace TestInner { class Inner { protected constructor($outer: foo.TestInner, a: string); - readonly a: string; - readonly concat: string; + get a(): string; + get concat(): string; static fromNumber(a: number): foo.TestInner.Inner; - readonly SecondLayerInner: { + get SecondLayerInner(): { new(a: string): TestInner.Inner.SecondLayerInner; } & typeof TestInner.Inner.SecondLayerInner; } namespace Inner { class SecondLayerInner { protected constructor($outer: foo.TestInner.Inner, a: string); - readonly a: string; - readonly concat: string; + get a(): string; + get concat(): string; } } } } -} \ No newline at end of file +} diff --git a/js/js.translator/testData/typescript-export/constructors/constructors.d.ts b/js/js.translator/testData/typescript-export/constructors/constructors.d.ts index b19e0d9d046..f40276ddb53 100644 --- a/js/js.translator/testData/typescript-export/constructors/constructors.d.ts +++ b/js/js.translator/testData/typescript-export/constructors/constructors.d.ts @@ -4,26 +4,26 @@ declare namespace JS_TESTS { type __doNotImplementIt = typeof __doNotImplementIt class ClassWithDefaultCtor { constructor(); - readonly x: string; + get x(): string; } class ClassWithPrimaryCtor { constructor(x: string); - readonly x: string; + get x(): string; } class ClassWithSecondaryCtor { private constructor(); - readonly x: string; + get x(): string; static create(y: string): ClassWithSecondaryCtor; } class ClassWithMultipleSecondaryCtors { private constructor(); - readonly x: string; + get x(): string; static createFromString(y: string): ClassWithMultipleSecondaryCtors; static createFromInts(y: number, z: number): ClassWithMultipleSecondaryCtors; } class OpenClassWithMixedConstructors { constructor(x: string); - readonly x: string; + get x(): string; static createFromStrings(y: string, z: string): OpenClassWithMixedConstructors; static createFromInts(y: number, z: number): OpenClassWithMixedConstructors; } @@ -34,6 +34,6 @@ declare namespace JS_TESTS { } class KotlinGreeter { constructor(greeting: string); - readonly greeting: string; + get greeting(): string; } } diff --git a/js/js.translator/testData/typescript-export/declarations/declarations.d.ts b/js/js.translator/testData/typescript-export/declarations/declarations.d.ts index fb0e2ba2abf..fec9af202de 100644 --- a/js/js.translator/testData/typescript-export/declarations/declarations.d.ts +++ b/js/js.translator/testData/typescript-export/declarations/declarations.d.ts @@ -26,40 +26,43 @@ declare namespace JS_TESTS { } class A1 { constructor(x: number); - readonly x: number; + get x(): number; } class A2 { constructor(x: string, y: boolean); - readonly x: string; - y: boolean; + get x(): string; + get y(): boolean; + set y(value: boolean); } class A3 { constructor(); - readonly x: number; + get x(): number; } class A4 { constructor(); - readonly _valCustom: number; - readonly _valCustomWithField: number; - _varCustom: number; - _varCustomWithField: number; + get _valCustom(): number; + get _valCustomWithField(): number; + get _varCustom(): number; + set _varCustom(value: number); + get _varCustomWithField(): number; + set _varCustomWithField(value: number); } const O0: { }; const O: { - readonly x: number; + get x(): number; foo(): number; }; function takesO(o: typeof foo.O): number; class KT_37829 { constructor(); - static readonly Companion: { - readonly x: number; + static get Companion(): { + get x(): number; }; } class TestSealed { protected constructor(name: string); - readonly name: string; + get name(): string; } namespace TestSealed { class AA extends foo.TestSealed { @@ -73,7 +76,7 @@ declare namespace JS_TESTS { } abstract class TestAbstract { constructor(name: string); - readonly name: string; + get name(): string; } namespace TestAbstract { class AA extends foo.TestAbstract { @@ -87,7 +90,7 @@ declare namespace JS_TESTS { } class TestDataClass { constructor(name: string); - readonly name: string; + get name(): string; component1(): string; copy(name: string): foo.TestDataClass; toString(): string; @@ -97,32 +100,32 @@ declare namespace JS_TESTS { namespace TestDataClass { class Nested { constructor(); - readonly prop: string; + get prop(): string; } } abstract class TestEnumClass { private constructor(); - readonly constructorParameter: string; - static readonly A: foo.TestEnumClass & { - readonly name: "A"; - readonly ordinal: 0; + get constructorParameter(): string; + static get A(): foo.TestEnumClass & { + get name(): "A"; + get ordinal(): 0; }; - static readonly B: foo.TestEnumClass & { - readonly name: "B"; - readonly ordinal: 1; + static get B(): foo.TestEnumClass & { + get name(): "B"; + get ordinal(): 1; }; - readonly foo: number; + get foo(): number; bar(value: string): string; bay(): string; static values(): Array; static valueOf(value: string): foo.TestEnumClass; - readonly name: "A" | "B"; - readonly ordinal: 0 | 1; + get name(): "A" | "B"; + get ordinal(): 0 | 1; } namespace TestEnumClass { class Nested { constructor(); - readonly prop: string; + get prop(): string; } } interface TestInterface { @@ -132,7 +135,7 @@ declare namespace JS_TESTS { } class TestInterfaceImpl implements foo.TestInterface { constructor(value: string); - readonly value: string; + get value(): string; getOwnerName(): string; readonly __doNotUseIt: __doNotImplementIt; } diff --git a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.d.ts b/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.d.ts index fd9608a47fc..95e4edce30c 100644 --- a/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.d.ts +++ b/js/js.translator/testData/typescript-export/escapedDeclarations/escapedDeclarations.d.ts @@ -3,19 +3,21 @@ declare namespace JS_TESTS { const __doNotImplementIt: unique symbol type __doNotImplementIt = typeof __doNotImplementIt namespace foo { - - - + + + function invalid_args_name_sum(first_value: number, second_value: number): number; - + class A1 { constructor(first_value: number, second_value: number); - readonly "first value": number; - "second.value": number; + get "first value"(): number; + get "second.value"(): number; + set "second.value"(value: number); } class A2 { constructor(); - "invalid:name": number; + get "invalid:name"(): number; + set "invalid:name"(value: number); } class A3 { constructor(); @@ -24,10 +26,11 @@ declare namespace JS_TESTS { } class A4 { constructor(); - static readonly Companion: { - "@invalid+name@": number; + static get Companion(): { + get "@invalid+name@"(): number; + set "@invalid+name@"(value: number); "^)run.something.weird^("(): string; }; } } -} \ No newline at end of file +} diff --git a/js/js.translator/testData/typescript-export/implicitExport/declarations.d.ts b/js/js.translator/testData/typescript-export/implicitExport/declarations.d.ts index ae8f719471f..597b97cf691 100644 --- a/js/js.translator/testData/typescript-export/implicitExport/declarations.d.ts +++ b/js/js.translator/testData/typescript-export/implicitExport/declarations.d.ts @@ -10,7 +10,8 @@ declare namespace JS_TESTS { function consumer(value: any/* foo.NonExportedType */): number; class A { constructor(value: any/* foo.NonExportedType */); - value: any/* foo.NonExportedType */; + get value(): any/* foo.NonExportedType */; + set value(value: any/* foo.NonExportedType */); increment(t: T): any/* foo.NonExportedType */; } class B /* extends foo.NonExportedType */ { @@ -31,4 +32,4 @@ declare namespace JS_TESTS { constructor(); } } -} \ No newline at end of file +} diff --git a/js/js.translator/testData/typescript-export/inheritance/inheritance.d.ts b/js/js.translator/testData/typescript-export/inheritance/inheritance.d.ts index edc86ef62ed..0beacfc474f 100644 --- a/js/js.translator/testData/typescript-export/inheritance/inheritance.d.ts +++ b/js/js.translator/testData/typescript-export/inheritance/inheritance.d.ts @@ -17,16 +17,17 @@ declare namespace JS_TESTS { namespace foo { abstract class AC implements foo.I2 { constructor(); - x: string; - abstract readonly y: boolean; + get x(): string; + set x(value: string); + abstract get y(): boolean; abstract z(z: number): void; - readonly acProp: string; - abstract readonly acAbstractProp: string; + get acProp(): string; + abstract get acAbstractProp(): string; } class OC extends foo.AC implements foo.I { constructor(y: boolean, acAbstractProp: string); - readonly y: boolean; - readonly acAbstractProp: string; + get y(): boolean; + get acAbstractProp(): string; z(z: number): void; } class FC extends foo.OC { @@ -50,48 +51,53 @@ declare namespace JS_TESTS { function getC(): foo.I3; abstract class A2 implements foo.I3 { constructor(); - abstract readonly foo: string; - abstract bar: string; - abstract readonly baz: string; + abstract get foo(): string; + abstract get bar(): string; + abstract set bar(value: string); + abstract get baz(): string; abstract bay(): string; readonly __doNotUseIt: __doNotImplementIt; } class B2 extends foo.A2 { constructor(); - readonly foo: string; - bar: string; - readonly baz: string; + get foo(): string; + get bar(): string; + set bar(value: string); + get baz(): string; bay(): string; } class C2 extends foo.B2 { constructor(); - readonly foo: string; - bar: string; - baz: string; + get foo(): string; + get bar(): string; + set bar(value: string); + get baz(): string; + set baz(value: string); bay(): string; } abstract class EC implements foo.I3 { private constructor(); - static readonly EC1: foo.EC & { - readonly name: "EC1"; - readonly ordinal: 0; + static get EC1(): foo.EC & { + get name(): "EC1"; + get ordinal(): 0; }; - static readonly EC2: foo.EC & { - readonly name: "EC2"; - readonly ordinal: 1; + static get EC2(): foo.EC & { + get name(): "EC2"; + get ordinal(): 1; }; - static readonly EC3: foo.EC & { - readonly name: "EC3"; - readonly ordinal: 2; + static get EC3(): foo.EC & { + get name(): "EC3"; + get ordinal(): 2; }; - readonly foo: string; - bar: string; + get foo(): string; + get bar(): string; + set bar(value: string); bay(): string; static values(): Array; static valueOf(value: string): foo.EC; - readonly name: "EC1" | "EC2" | "EC3"; - readonly ordinal: 0 | 1 | 2; - abstract readonly baz: string; + get name(): "EC1" | "EC2" | "EC3"; + get ordinal(): 0 | 1 | 2; + abstract get baz(): string; readonly __doNotUseIt: __doNotImplementIt; } } diff --git a/js/js.translator/testData/typescript-export/inheritance/inheritance__main.js b/js/js.translator/testData/typescript-export/inheritance/inheritance__main.js index b25545bf97c..c73c978cd0a 100644 --- a/js/js.translator/testData/typescript-export/inheritance/inheritance__main.js +++ b/js/js.translator/testData/typescript-export/inheritance/inheritance__main.js @@ -3,10 +3,12 @@ var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); @@ -24,6 +26,7 @@ var getC = JS_TESTS.foo.getC; var B2 = JS_TESTS.foo.B2; var C2 = JS_TESTS.foo.C2; var EC = JS_TESTS.foo.EC; +var A2 = JS_TESTS.foo.A2; var Impl = /** @class */ (function (_super) { __extends(Impl, _super); function Impl() { @@ -43,16 +46,42 @@ var Impl = /** @class */ (function (_super) { }); return Impl; }(AC)); -// class A2Impl extends A2 { -// bar: string = "barA2" -// readonly baz: string = "bazA2" -// readonly foo: string = "fooA2" -// -// bay(): string { -// return "bayA2"; -// } -// -// } +var A2Impl = /** @class */ (function (_super) { + __extends(A2Impl, _super); + function A2Impl() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._bar = "barA2"; + return _this; + } + Object.defineProperty(A2Impl.prototype, "bar", { + get: function () { + return this._bar; + }, + set: function (value) { + this._bar = value; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(A2Impl.prototype, "baz", { + get: function () { + return "bazA2"; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(A2Impl.prototype, "foo", { + get: function () { + return "fooA2"; + }, + enumerable: false, + configurable: true + }); + A2Impl.prototype.bay = function () { + return "bayA2"; + }; + return A2Impl; +}(A2)); function box() { var impl = new Impl(); if (impl.acProp !== "acProp") @@ -115,11 +144,18 @@ function box() { return "Fail 25"; if (getC().bay() != "bayC") return "Fail 26"; - // const a2Impl = new A2Impl() - // if (a2Impl.foo != "fooA2") return "Fail 27" - // if (a2Impl.bar != "barA2") return "Fail 28" - // if (a2Impl.baz != "bazA2") return "Fail 29" - // if (a2Impl.bay() != "bayA2") return "Fail 30" + var a2Impl = new A2Impl(); + if (a2Impl.foo != "fooA2") + return "Fail 27"; + if (a2Impl.bar != "barA2") + return "Fail 28"; + a2Impl.bar = "barA2.2"; + if (a2Impl.bar != "barA2.2") + return "Fail 28.2"; + if (a2Impl.baz != "bazA2") + return "Fail 29"; + if (a2Impl.bay() != "bayA2") + return "Fail 30"; var b2 = new B2(); if (b2.foo != "fooB2") return "Fail 31"; diff --git a/js/js.translator/testData/typescript-export/inheritance/inheritance__main.ts b/js/js.translator/testData/typescript-export/inheritance/inheritance__main.ts index cd0be08464c..204f5719be0 100644 --- a/js/js.translator/testData/typescript-export/inheritance/inheritance__main.ts +++ b/js/js.translator/testData/typescript-export/inheritance/inheritance__main.ts @@ -10,6 +10,7 @@ import getC = JS_TESTS.foo.getC; import B2 = JS_TESTS.foo.B2; import C2 = JS_TESTS.foo.C2; import EC = JS_TESTS.foo.EC; +import A2 = JS_TESTS.foo.A2; class Impl extends AC { z(z: number): void { @@ -19,17 +20,27 @@ class Impl extends AC { get y(): boolean { return true; } } -// TODO: Uncomment with fix of export open properties -// class A2Impl extends A2 { -// bar: string = "barA2" -// readonly baz: string = "bazA2" -// readonly foo: string = "fooA2" -// -// bay(): string { -// return "bayA2"; -// } -// -// } +class A2Impl extends A2 { + _bar: string = "barA2" + + get bar(): string { + return this._bar + } + set bar(value: string) { + this._bar = value + } + get baz(): string { + return "bazA2" + } + get foo(): string { + return "fooA2" + } + + bay(): string { + return "bayA2"; + } + +} function box(): string { const impl = new Impl(); @@ -75,11 +86,13 @@ function box(): string { if (getC().baz != "bazC") return "Fail 25" if (getC().bay() != "bayC") return "Fail 26" - // const a2Impl = new A2Impl() - // if (a2Impl.foo != "fooA2") return "Fail 27" - // if (a2Impl.bar != "barA2") return "Fail 28" - // if (a2Impl.baz != "bazA2") return "Fail 29" - // if (a2Impl.bay() != "bayA2") return "Fail 30" + const a2Impl = new A2Impl() + if (a2Impl.foo != "fooA2") return "Fail 27" + if (a2Impl.bar != "barA2") return "Fail 28" + a2Impl.bar = "barA2.2" + if (a2Impl.bar != "barA2.2") return "Fail 28.2" + if (a2Impl.baz != "bazA2") return "Fail 29" + if (a2Impl.bay() != "bayA2") return "Fail 30" const b2 = new B2() if (b2.foo != "fooB2") return "Fail 31" diff --git a/js/js.translator/testData/typescript-export/moduleSystems/commonjs.d.ts b/js/js.translator/testData/typescript-export/moduleSystems/commonjs.d.ts index 61f3f4212cd..0d690020c61 100644 --- a/js/js.translator/testData/typescript-export/moduleSystems/commonjs.d.ts +++ b/js/js.translator/testData/typescript-export/moduleSystems/commonjs.d.ts @@ -5,7 +5,7 @@ export namespace foo { const prop: number; class C { constructor(x: number); - readonly x: number; + get x(): number; doubleX(): number; } function box(): string; diff --git a/js/js.translator/testData/typescript-export/moduleSystems/plain.d.ts b/js/js.translator/testData/typescript-export/moduleSystems/plain.d.ts index 5b23509e69d..c9bb86a5f7d 100644 --- a/js/js.translator/testData/typescript-export/moduleSystems/plain.d.ts +++ b/js/js.translator/testData/typescript-export/moduleSystems/plain.d.ts @@ -6,7 +6,7 @@ declare namespace JS_TESTS { const prop: number; class C { constructor(x: number); - readonly x: number; + get x(): number; doubleX(): number; } function box(): string; diff --git a/js/js.translator/testData/typescript-export/moduleSystems/umd.d.ts b/js/js.translator/testData/typescript-export/moduleSystems/umd.d.ts index 6e9a3e175c0..56d97afc155 100644 --- a/js/js.translator/testData/typescript-export/moduleSystems/umd.d.ts +++ b/js/js.translator/testData/typescript-export/moduleSystems/umd.d.ts @@ -5,7 +5,7 @@ export namespace foo { const prop: number; class C { constructor(x: number); - readonly x: number; + get x(): number; doubleX(): number; } function box(): string; diff --git a/js/js.translator/testData/typescript-export/namespaces/namespaces.d.ts b/js/js.translator/testData/typescript-export/namespaces/namespaces.d.ts index c24c4ed8191..ad0a287402c 100644 --- a/js/js.translator/testData/typescript-export/namespaces/namespaces.d.ts +++ b/js/js.translator/testData/typescript-export/namespaces/namespaces.d.ts @@ -5,7 +5,7 @@ declare namespace JS_TESTS { namespace foo.bar.baz { class C1 { constructor(value: string); - readonly value: string; + get value(): string; component1(): string; copy(value: string): foo.bar.baz.C1; toString(): string; @@ -17,7 +17,7 @@ declare namespace JS_TESTS { namespace a.b { class C2 { constructor(value: string); - readonly value: string; + get value(): string; component1(): string; copy(value: string): a.b.C2; toString(): string; @@ -28,7 +28,7 @@ declare namespace JS_TESTS { } class C3 { constructor(value: string); - readonly value: string; + get value(): string; component1(): string; copy(value: string): C3; toString(): string; diff --git a/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.d.ts b/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.d.ts index 1080cdfff6d..b9aa7a96863 100644 --- a/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.d.ts +++ b/js/js.translator/testData/typescript-export/selectiveExport/selectiveExport.d.ts @@ -15,7 +15,7 @@ declare namespace JS_TESTS { function exportedFun(): number; class ExportedClass { constructor(); - readonly value: number; + get value(): number; } } namespace foo { @@ -23,7 +23,7 @@ declare namespace JS_TESTS { function fileLevelExportedFun(): number; class FileLevelExportedClass { constructor(); - readonly value: number; + get value(): number; } } } diff --git a/js/js.translator/testData/typescript-export/visibility/visibility.d.ts b/js/js.translator/testData/typescript-export/visibility/visibility.d.ts index 78aeb0e8aff..a70cce14a66 100644 --- a/js/js.translator/testData/typescript-export/visibility/visibility.d.ts +++ b/js/js.translator/testData/typescript-export/visibility/visibility.d.ts @@ -11,14 +11,14 @@ declare namespace JS_TESTS { } class Class { constructor(); - protected readonly protectedVal: number; + protected get protectedVal(): number; protected protectedFun(): number; - protected static readonly protectedNestedObject: { + protected static get protectedNestedObject(): { }; - protected static readonly Companion: { - readonly companionObjectProp: number; + protected static get Companion(): { + get companionObjectProp(): number; }; - readonly publicVal: number; + get publicVal(): number; publicFun(): number; } namespace Class { @@ -35,17 +35,17 @@ declare namespace JS_TESTS { } abstract class EnumClass { private constructor(); - static readonly EC1: EnumClass & { - readonly name: "EC1"; - readonly ordinal: 0; + static get EC1(): EnumClass & { + get name(): "EC1"; + get ordinal(): 0; }; - static readonly EC2: EnumClass & { - readonly name: "EC2"; - readonly ordinal: 1; + static get EC2(): EnumClass & { + get name(): "EC2"; + get ordinal(): 1; }; static values(): Array; static valueOf(value: string): EnumClass; - readonly name: "EC1" | "EC2"; - readonly ordinal: 0 | 1; + get name(): "EC1" | "EC2"; + get ordinal(): 0 | 1; } }