已合并
Add missing cte for late-init obj literal #9768
dddzzzhhh创建于 1月22日
Add missing cte for late-init obj literal #9768
已合并
共 6 个文件变更+139-11
| @@ -3234,10 +3234,9 @@ checker::Type *ETSAnalyzer::Check(ir::ObjectExpression *expr) const | |||
| 3234 | return tsType; | 3234 | return tsType; |
| 3235 | } | 3235 | } |
| 3236 | 3236 | ||
| 3237 | -void ETSAnalyzer::CollectNonOptionalProperty(const ETSObjectType *objType, | 3237 | +static void CollectNonOptionalPropertyInterface(checker::ETSChecker *checker, const ETSObjectType *objType, |
| 3238 | - std::unordered_map<util::StringView, ETSObjectType *> &props) const | 3238 | + std::unordered_map<util::StringView, ETSObjectType *> &props) |
| 3239 | { | 3239 | { |
| 3240 | - ETSChecker *checker = GetETSChecker(); | ||
| 3241 | // Note: all the properties of an interface will be lowered as accessor before checker. | 3240 | // Note: all the properties of an interface will be lowered as accessor before checker. |
| 3242 | auto const &methodMap = objType->InstanceMethods(); | 3241 | auto const &methodMap = objType->InstanceMethods(); |
| 3243 | for (const auto &[propName, var] : methodMap) { | 3242 | for (const auto &[propName, var] : methodMap) { |
| @@ -3252,14 +3251,41 @@ void ETSAnalyzer::CollectNonOptionalProperty(const ETSObjectType *objType, | |||
| 3252 | } | 3251 | } |
| 3253 | 3252 | ||
| 3254 | if (var->Declaration()->Node()->IsOptionalDeclaration()) { | 3253 | if (var->Declaration()->Node()->IsOptionalDeclaration()) { |
| 3255 | - // non-optional properties | 3254 | + // optional properties |
| 3256 | continue; | 3255 | continue; |
| 3257 | } | 3256 | } |
| 3258 | props.insert({propName, const_cast<ETSObjectType *>(objType)}); | 3257 | props.insert({propName, const_cast<ETSObjectType *>(objType)}); |
| 3259 | } | 3258 | } |
| 3259 | +} | ||
| 3260 | 3260 | ||
| 3261 | - for (auto const *superInterface : objType->Interfaces()) { | 3261 | +static void CollectLateInitPropertyClass(const ETSObjectType *objType, |
| 3262 | - CollectNonOptionalProperty(superInterface, props); | 3262 | + std::unordered_map<util::StringView, ETSObjectType *> &props) |
| 3263 | +{ | ||
| 3264 | + auto const &fields = objType->InstanceFields(); | ||
| 3265 | + for (const auto &[propName, var] : fields) { | ||
| 3266 | + if (!var->Declaration()->Node()->IsDefinite()) { | ||
| 3267 | + continue; | ||
| 3268 | + } | ||
| 3269 | + props.insert({propName, const_cast<ETSObjectType *>(objType)}); | ||
| 3270 | + } | ||
| 3271 | +} | ||
| 3272 | + | ||
| 3273 | +void ETSAnalyzer::CollectNonOptionalProperty(const ETSObjectType *objType, | ||
| 3274 | + std::unordered_map<util::StringView, ETSObjectType *> &props) const | ||
| 3275 | +{ | ||
| 3276 | + ETSChecker *checker = GetETSChecker(); | ||
| 3277 | + if (objType->HasObjectFlag(ETSObjectFlags::INTERFACE)) { | ||
| 3278 | + CollectNonOptionalPropertyInterface(checker, objType, props); | ||
| 3279 | + for (auto const *superInterface : objType->Interfaces()) { | ||
| 3280 | + CollectNonOptionalProperty(superInterface, props); | ||
| 3281 | + } | ||
| 3282 | + } | ||
| 3283 | + | ||
| 3284 | + if (objType->HasObjectFlag(ETSObjectFlags::CLASS)) { | ||
| 3285 | + CollectLateInitPropertyClass(objType, props); | ||
| 3286 | + if (objType->SuperType() != nullptr) { | ||
| 3287 | + CollectNonOptionalProperty(objType->SuperType(), props); | ||
| 3288 | + } | ||
| 3263 | } | 3289 | } |
| 3264 | } | 3290 | } |
| 3265 | 3291 | ||
| @@ -3421,9 +3447,8 @@ void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, | |||
| 3421 | } | 3447 | } |
| 3422 | 3448 | ||
| 3423 | std::unordered_map<util::StringView, ETSObjectType *> propertyWithNonOptionalType; | 3449 | std::unordered_map<util::StringView, ETSObjectType *> propertyWithNonOptionalType; |
| 3424 | - if (objType->HasObjectFlag(ETSObjectFlags::INTERFACE)) { | 3450 | + |
| 3425 | - CollectNonOptionalProperty(objType, propertyWithNonOptionalType); | 3451 | + CollectNonOptionalProperty(objType, propertyWithNonOptionalType); |
| 3426 | - } | ||
| 3427 | 3452 | ||
| 3428 | CheckObjectExprPropsHelper(checker, expr, objType, searchFlags, propertyWithNonOptionalType); | 3453 | CheckObjectExprPropsHelper(checker, expr, objType, searchFlags, propertyWithNonOptionalType); |
| 3429 | 3454 | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +class CC { | ||
| 18 | + calendar !: number; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +let a : CC = {} | ||
| 22 | + | ||
| 23 | +/* @@? 21:14 Error Semantic error ESE0400: Non-optional property 'calendar' in type 'CC' is missing in object literal. */ | ||
| @@ -0,0 +1,26 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +class A { | ||
| 18 | + a!: number | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +class B extends A { | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +let a : B = {} | ||
| 25 | + | ||
| 26 | +/* @@? 24:13 Error Semantic error ESE0401: Non-optional property 'a' in super type 'A' of type 'B' is missing in object literal. */ | ||
| @@ -0,0 +1,26 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + * you may not use this file except in compliance with the License. | ||
| 5 | + * You may obtain a copy of the License at | ||
| 6 | + * | ||
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + * | ||
| 9 | + * Unless required by applicable law or agreed to in writing, software | ||
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + * See the License for the specific language governing permissions and | ||
| 13 | + * limitations under the License. | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | +interface A { | ||
| 18 | + a!: number | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +function main() { | ||
| 22 | + let bba : A = { } | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +/* @@? 18:6 Error Syntax error ESY162966: Definite assignment assertions '!' are not allowed in interface properties. */ | ||
| 26 | +/* @@? 22:19 Error Semantic error ESE0400: Non-optional property 'a' in type 'A' is missing in object literal. */ | ||
Mets2panda/test/runtime/ets/fields_with_late_initialization/class_late_initialization_with_object_literal_error.ets+2-2
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | - * Copyright (c) 2025 Huawei Device Co., Ltd. | 2 | + * Copyright (c) 2026 Huawei Device Co., Ltd. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. | 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at | 5 | * You may obtain a copy of the License at |
| @@ -19,7 +19,7 @@ class A { | |||
| 19 | 19 | ||
| 20 | function main(): void { | 20 | function main(): void { |
| 21 | try { | 21 | try { |
| 22 | - let a: A = {} | 22 | + let a: A = {f: "aa"} |
| 23 | arktest.assertEQ(a.f, "aa"); | 23 | arktest.assertEQ(a.f, "aa"); |
| 24 | } catch (e) { | 24 | } catch (e) { |
| 25 | arktest.assertTrue(e instanceof NullPointerError) | 25 | arktest.assertTrue(e instanceof NullPointerError) |
| @@ -0,0 +1,28 @@ | |||
| 1 | +/* | ||
| 2 | + | ||
| 3 | + * Copyright (c) 2026 Huawei Device Co., Ltd. | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +class A { | ||
| 19 | + a!: number | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +class B extends A { | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +function main() { | ||
| 26 | + let bba : B = { a: 10} | ||
| 27 | + arktest.assertEQ(bba.a, 10) | ||
| 28 | +} | ||
What about non-direct superinterfaces? These should be traversed as well, right?