From bef804eed2e4ef5e60db6c6ede4d5af93ca66a71 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Wed, 2 Jul 2025 15:39:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86es2panda=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=97=B6=E9=80=92=E5=BD=92=E5=9C=B0=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E6=B3=9B=E5=9E=8B=E7=B1=BB=E5=9E=8B=E5=8F=82=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E5=8F=98=E5=9E=8B=E6=97=B6=E5=8F=91=E7=94=9Fcrash=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJG4D Signed-off-by: yp9522 --- ets2panda/checker/types/ets/etsObjectType.cpp | 9 +- .../ets/check_variance_recursively_test.ets | 198 ++++++++++++++++++ 2 files changed, 205 insertions(+), 2 deletions(-) create mode 100755 ets2panda/test/runtime/ets/check_variance_recursively_test.ets diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index e7d2fb4229..d732c17db2 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -1568,8 +1568,13 @@ void ETSObjectType::CheckVarianceRecursively(TypeRelation *relation, VarianceFla return; } - auto *params = GetDeclNode()->IsClassDefinition() ? GetDeclNode()->AsClassDefinition()->TypeParams() - : GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); + auto *declNode = GetDeclNode(); + if (declNode == nullptr) { + return; + } + + auto *params = declNode->IsClassDefinition() ? declNode->AsClassDefinition()->TypeParams() + : declNode->AsTSInterfaceDeclaration()->TypeParams(); if (params == nullptr) { return; } diff --git a/ets2panda/test/runtime/ets/check_variance_recursively_test.ets b/ets2panda/test/runtime/ets/check_variance_recursively_test.ets new file mode 100755 index 0000000000..4049d30760 --- /dev/null +++ b/ets2panda/test/runtime/ets/check_variance_recursively_test.ets @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +// object types are identical structurally + +class A { + kind: 'A' = 'A'; + foo: number = 0; +} + +class B { + kind: 'B' = 'B'; + foo: boolean = false; +} + +class C { + kind: 'C' = 'C'; + foo: T = null as T; +} + +interface I { + kind: 'I' = 'I'; + foo: Date; +} + +// Define explicit interfaces for inline object types +interface FooRegExp { + kind: 'FooRegExp' = 'FooRegExp'; + foo: RegExp; +} + +interface FooString { + kind: 'FooString' = 'FooString'; + foo: string; +} + +let a: FooRegExp = { kind: 'FooRegExp', foo: new RegExp("test") }; +let b: FooString = { kind: 'FooString', foo: "bar" }; + +// Helper function to create strongly-typed objects +function createA(): A { + return new A(); +} + +function createB(): B { + return new B(); +} + +function createC(value: T): C { + const c = new C(); + c.foo = value; + return c; +} + +function createI(date: Date): I { + return { kind: 'I', foo: date }; +} + +function createFooRegExp(value: RegExp): FooRegExp { + return { kind: 'FooRegExp', foo: value }; +} + +function createFooString(value: string): FooString { + return { kind: 'FooString', foo: value }; +} + +// Discriminated union version of foo5 +function foo5(x: A | B): void { + if (x.kind === 'A') { + // handle A + console.log("A: foo is number"); + } else { + // handle B + console.log("B: foo is boolean"); + } +} + +// Discriminated union version of foo5b +function foo5b(x: A | C): void { + if (x.kind === 'A') { + // handle A + console.log("A: foo is number"); + } else { + // handle C + console.log("C: foo is string"); + } +} + +// Discriminated union version of foo6 +function foo6(x: A | I): void { + if (x.kind === 'I') { + // handle I + console.log("I: foo is Date"); + } else { + // handle A + console.log("A: foo is number"); + } +} + +// Discriminated union version of foo7 +function foo7(x: A | FooRegExp): void { + if (x.kind === 'FooRegExp') { + // handle FooRegExp + console.log("x is like 'a': foo is RegExp"); + } else { + // handle A + console.log("A: foo is number"); + } +} + +// Discriminated union version of foo8 +function foo8(x: B | I): void { + if (x.kind === 'I') { + // handle I + console.log("I: foo is Date"); + } else { + // handle B + console.log("B: foo is boolean"); + } +} + +// Discriminated union version of foo9 +function foo9(x: B | C): void { + if (x.kind === 'C') { + // handle C + console.log("C: foo is string"); + } else { + // handle B + console.log("B: foo is boolean"); + } +} + +// Discriminated union version of foo10 +function foo10(x: B | FooRegExp): void { + if (x.kind === 'FooRegExp') { + // handle FooRegExp + console.log("x is like 'a': foo is RegExp"); + } else { + // handle B + console.log("B: foo is boolean"); + } +} + +// Discriminated union version of foo11 +function foo11(x: B | FooString): void { + if (x.kind === 'FooString') { + // handle FooString + console.log("x is like 'b': foo is string"); + } else { + // handle B + console.log("B: foo is boolean"); + } +} + +// Discriminated union version of foo12 +function foo12(x: I | C): void { + if (x.kind === 'I') { + // handle I + console.log("I: foo is Date"); + } else { + // handle C + console.log("C: foo is string"); + } +} + +// Discriminated union version of foo13 +function foo13(x: I | FooRegExp): void { + if (x.kind === 'FooRegExp') { + // handle FooRegExp + console.log("x is like 'a': foo is RegExp"); + } else { + // handle I + console.log("I: foo is Date"); + } +} + +// Discriminated union version of foo14 +function foo14(x: I | FooString): void { + if (x.kind === 'FooString') { + // handle FooString + console.log("x is like 'b': foo is string"); + } else { + // handle I + console.log("I: foo is Date"); + } +} \ No newline at end of file -- Gitee