已关闭
Fix function types and lambda exp with receiver #10491
Fix function types and lambda exp with receiver #10491
已关闭
Fouckttt创建于 4月19日关闭于 6月22日
共 19 个文件变更+550-46
@@ -3198,7 +3198,7 @@ std::vector<ResolveResult *> ETSChecker::ResolveMemberReference(const ir::Member
3198 LogError(diagnostic::EXTENSION_ACCESSOR_INVALID_CALL, {}, memberExpr->Start());3198 LogError(diagnostic::EXTENSION_ACCESSOR_INVALID_CALL, {}, memberExpr->Start());
3199 return resolveRes;3199 return resolveRes;
3200 }3200 }
3201- if (resolvedKind == ResolvedKind::EXTENSION_FUNCTION && !globalFunctionVar->TsType()->IsETSArrowType() &&3201+ if (prop == nullptr && resolvedKind == ResolvedKind::EXTENSION_FUNCTION &&
3202 !memberExpr->Parent()->IsCallExpression()) {3202 !memberExpr->Parent()->IsCallExpression()) {
3203 LogError(diagnostic::PROPERTY_NONEXISTENT,3203 LogError(diagnostic::PROPERTY_NONEXISTENT,
3204 {memberExpr->Property()->AsIdentifier()->Name(), memberExpr->ObjType()},3204 {memberExpr->Property()->AsIdentifier()->Name(), memberExpr->ObjType()},
@@ -353,7 +353,8 @@ bool Type::IsETSRelaxedAnyType() const
353 TypeFlag::ETS_TYPE_PARAMETER | TypeFlag::ETS_NONNULLISH | TypeFlag::ETS_REQUIRED_TYPE_PARAMETER |353 TypeFlag::ETS_TYPE_PARAMETER | TypeFlag::ETS_NONNULLISH | TypeFlag::ETS_REQUIRED_TYPE_PARAMETER |
354 TypeFlag::ETS_ANY | TypeFlag::ETS_NEVER | TypeFlag::ETS_UNION | TypeFlag::ETS_ARRAY | TypeFlag::FUNCTION |354 TypeFlag::ETS_ANY | TypeFlag::ETS_NEVER | TypeFlag::ETS_UNION | TypeFlag::ETS_ARRAY | TypeFlag::FUNCTION |
355 TypeFlag::ETS_PARTIAL_TYPE_PARAMETER | TypeFlag::ETS_TUPLE | TypeFlag::ETS_ENUM | TypeFlag::ETS_READONLY |355 TypeFlag::ETS_PARTIAL_TYPE_PARAMETER | TypeFlag::ETS_TUPLE | TypeFlag::ETS_ENUM | TypeFlag::ETS_READONLY |
356- TypeFlag::ETS_AWAITED | TypeFlag::ETS_RETURN_TYPE_UTILITY | TypeFlag::ETS_WILDCARD;356+ TypeFlag::ETS_AWAITED | TypeFlag::ETS_RETURN_TYPE_UTILITY | TypeFlag::ETS_WILDCARD |
357+ TypeFlag::ETS_EXTENSION_FUNC_HELPER;
357 358 
358 // Issues359 // Issues
359 if (type->IsETSTypeAliasType()) { // NOTE(vpukhov): #20561360 if (type->IsETSTypeAliasType()) { // NOTE(vpukhov): #20561
@@ -1193,7 +1193,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor {
1193 1193 
1194 static bool IsStaticMemberExpression(ir::MemberExpression *mexpr)1194 static bool IsStaticMemberExpression(ir::MemberExpression *mexpr)
1195 {1195 {
1196- ES2PANDA_ASSERT(mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS);1196+ ES2PANDA_ASSERT(mexpr->HasMemberKind(ir::MemberExpressionKind::PROPERTY_ACCESS));
1197 1197 
1198 auto *propDeclNode = mexpr->Property()->Variable()->Declaration()->Node();1198 auto *propDeclNode = mexpr->Property()->Variable()->Declaration()->Node();
1199 if (propDeclNode->IsMethodDefinition()) {1199 if (propDeclNode->IsMethodDefinition()) {
@@ -1274,6 +1274,23 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor {
1274 return false;1274 return false;
1275 }1275 }
1276 1276 
1277+ checker::Type *GetMemberPropertyType(ir::MemberExpression *mexpr, varbinder::Variable *propVar)
1278+ {
1279+ ES2PANDA_ASSERT(propVar != nullptr);
1280+ if (HandleDeclarationIfNeeded(mexpr, propVar)) {
1281+ return propVar->Declaration()->Node()->AsTyped()->TsType();
1282+ }
1283+ if (propVar->TsType() != nullptr) {
1284+ return propVar->TsType();
1285+ }
1286+ 
1287+ if (mexpr->Property()->TsType() != nullptr) {
1288+ return mexpr->Property()->TsType();
1289+ }
1290+ 
1291+ return mexpr->TsType();
1292+ }
1293+ 
1277 void SetUnboxedPropType(ir::MemberExpression *mexpr, checker::Type *propType)1294 void SetUnboxedPropType(ir::MemberExpression *mexpr, checker::Type *propType)
1278 {1295 {
1279 /* Special handling for getters/setters. */1296 /* Special handling for getters/setters. */
@@ -1327,21 +1344,14 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor {
1327 // CC-OFFNXT(huge_cyclomatic_complexity, huge_depth[C++], huge_depth, huge_method, G.FUN.01-CPP, G.FUN.05) solid1344 // CC-OFFNXT(huge_cyclomatic_complexity, huge_depth[C++], huge_depth, huge_method, G.FUN.01-CPP, G.FUN.05) solid
1328 void VisitMemberExpression(ir::MemberExpression *mexpr) override1345 void VisitMemberExpression(ir::MemberExpression *mexpr) override
1329 {1346 {
1330- if (mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS ||1347+ if (mexpr->HasMemberKind(ir::MemberExpressionKind::PROPERTY_ACCESS) ||
1331 /* Workaround for memo plugin */1348 /* Workaround for memo plugin */
1332- mexpr->Kind() == ir::MemberExpressionKind::NONE || mexpr->Kind() == ir::MemberExpressionKind::GETTER ||1349+ mexpr->Kind() == ir::MemberExpressionKind::NONE || mexpr->HasMemberKind(ir::MemberExpressionKind::GETTER) ||
1333- mexpr->Kind() == ir::MemberExpressionKind::SETTER) {1350+ mexpr->HasMemberKind(ir::MemberExpressionKind::SETTER)) {
1334 if (auto propVar = mexpr->Property()->Variable(); propVar != nullptr) {1351 if (auto propVar = mexpr->Property()->Variable(); propVar != nullptr) {
1335- checker::Type *propType = nullptr;1352+ if (auto *propType = GetMemberPropertyType(mexpr, propVar); propType != nullptr) {
1336- if (HandleDeclarationIfNeeded(mexpr, propVar)) {1353+ SetUnboxedPropType(mexpr, propType);
1337- propType = propVar->Declaration()->Node()->AsTyped()->TsType();
1338- } else if (propVar->TsType() != nullptr) {
1339- propType = propVar->TsType();
1340- } else {
1341- propType = mexpr->Property()->TsType();
1342 }1354 }
1343- ES2PANDA_ASSERT(propType != nullptr);
1344- SetUnboxedPropType(mexpr, propType);
1345 } else if (mexpr->Object()->TsType()->IsETSUnionType()) {1355 } else if (mexpr->Object()->TsType()->IsETSUnionType()) {
1346 auto memberType = AdjustUnionMemberType(mexpr);1356 auto memberType = AdjustUnionMemberType(mexpr);
1347 if (memberType != nullptr) {1357 if (memberType != nullptr) {
@@ -1356,7 +1366,7 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor {
1356 // NOTE(gogabr): need to handle some elementary method calls as intrinsics1366 // NOTE(gogabr): need to handle some elementary method calls as intrinsics
1357 mexpr->SetObject(InsertBoxing(uctx_, mexpr->Object()));1367 mexpr->SetObject(InsertBoxing(uctx_, mexpr->Object()));
1358 }1368 }
1359- } else if (mexpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS) {1369+ } else if (mexpr->HasMemberKind(ir::MemberExpressionKind::ELEMENT_ACCESS)) {
1360 /* Getters are already handled in a lowering, we need a primtive as an index */1370 /* Getters are already handled in a lowering, we need a primtive as an index */
1361 if (TypeIsBoxedPrimitive(mexpr->Property()->TsType())) {1371 if (TypeIsBoxedPrimitive(mexpr->Property()->TsType())) {
1362 mexpr->SetProperty(InsertUnboxing(uctx_, mexpr->Property()));1372 mexpr->SetProperty(InsertUnboxing(uctx_, mexpr->Property()));
@@ -152,6 +152,70 @@ checker::Type *MemberExpression::Check(checker::TSChecker *checker)
152 return checker->GetAnalyzer()->Check(this);152 return checker->GetAnalyzer()->Check(this);
153}153}
154 154 
155+namespace {
156+ 
157+using ResolveObjectMemberResult = std::pair<checker::Type *, varbinder::LocalVariable *>;
158+ 
159+bool IsMemberExpressionCall(const MemberExpression *memberExpr)
160+{
161+ return memberExpr->Parent()->IsCallExpression() && memberExpr->Parent()->AsCallExpression()->Callee() == memberExpr;
162+}
163+ 
164+ResolveObjectMemberResult ResolvePropertyMember(const MemberExpression *memberExpr, checker::ETSChecker *checker,
165+ varbinder::Variable *variable)
166+{
167+ auto *var = variable->AsLocalVariable();
168+ checker->ValidatePropertyAccess(var, memberExpr->ObjType(), memberExpr->Property());
169+ return {checker->GetTypeOfVariable(var), var};
170+}
171+ 
172+ResolveObjectMemberResult ResolveExtensionAccessorMember(const MemberExpression *memberExpr,
173+ varbinder::Variable *variable)
174+{
175+ const_cast<MemberExpression *>(memberExpr)->AddMemberKind(ir::MemberExpressionKind::EXTENSION_ACCESSOR);
176+ return {variable->TsType(), nullptr};
177+}
178+ 
179+ResolveObjectMemberResult ResolveSingleObjectMemberResult(const MemberExpression *memberExpr,
180+ checker::ETSChecker *checker,
181+ checker::ResolveResult *resolveRes)
182+{
183+ if (resolveRes->Kind() == checker::ResolvedKind::PROPERTY) {
184+ return ResolvePropertyMember(memberExpr, checker, resolveRes->Variable());
185+ }
186+ 
187+ if (resolveRes->Kind() == checker::ResolvedKind::EXTENSION_ACCESSOR) {
188+ return ResolveExtensionAccessorMember(memberExpr, resolveRes->Variable());
189+ }
190+ 
191+ return {checker->GetTypeOfVariable(resolveRes->Variable()), nullptr};
192+}
193+ 
194+ResolveObjectMemberResult ResolvePropertyAndExtensionMember(const MemberExpression *memberExpr,
195+ checker::ETSChecker *checker,
196+ const std::vector<checker::ResolveResult *> &resolveRes)
197+{
198+ auto *classMethodType = checker->GetTypeOfVariable(resolveRes[1]->Variable());
199+ auto *extensionMethodType = checker->GetTypeOfVariable(resolveRes[0]->Variable());
200+ const bool isCall = IsMemberExpressionCall(memberExpr);
201+ if (classMethodType->IsETSArrowType()) {
202+ if (isCall) {
203+ return ResolveExtensionAccessorMember(memberExpr, resolveRes[0]->Variable());
204+ }
205+ return ResolvePropertyMember(memberExpr, checker, resolveRes[1]->Variable());
206+ }
207+ 
208+ auto *resolvedType = extensionMethodType;
209+ if (classMethodType->IsETSFunctionType()) {
210+ ES2PANDA_ASSERT(extensionMethodType->IsETSFunctionType());
211+ resolvedType = checker->CreateETSExtensionFuncHelperType(classMethodType->AsETSFunctionType(),
212+ extensionMethodType->AsETSFunctionType());
213+ }
214+ return {resolvedType, nullptr};
215+}
216+ 
217+} // namespace
218+ 
155bool MemberExpression::CheckRequiredCallError(checker::ETSChecker *checker,219bool MemberExpression::CheckRequiredCallError(checker::ETSChecker *checker,
156 const std::vector<checker::ResolveResult *> &resolveRes) const220 const std::vector<checker::ResolveResult *> &resolveRes) const
157{221{
@@ -183,36 +247,10 @@ std::pair<checker::Type *, varbinder::LocalVariable *> MemberExpression::Resolve
183 return {nullptr, nullptr};247 return {nullptr, nullptr};
184 }248 }
185 case 1U: {249 case 1U: {
186- if (resolveRes[0]->Kind() == checker::ResolvedKind::PROPERTY) {250+ return ResolveSingleObjectMemberResult(this, checker, resolveRes[0]);
187- auto var = resolveRes[0]->Variable()->AsLocalVariable();
188- checker->ValidatePropertyAccess(var, objType_, property_);
189- return {checker->GetTypeOfVariable(var), var};
190- }
191- 
192- if (resolveRes[0]->Kind() == checker::ResolvedKind::EXTENSION_ACCESSOR) {
193- auto *callee = const_cast<ir::Expression *>(this->AsExpression());
194- callee->AsMemberExpression()->AddMemberKind(ir::MemberExpressionKind::EXTENSION_ACCESSOR);
195- return {resolveRes[0]->Variable()->TsType(), nullptr};
196- }
197- 
198- return {checker->GetTypeOfVariable(resolveRes[0]->Variable()), nullptr};
199 }251 }
200 case 2U: {252 case 2U: {
201- auto classMethodType = checker->GetTypeOfVariable(resolveRes[1]->Variable());253+ return ResolvePropertyAndExtensionMember(this, checker, resolveRes);
202- auto extensionMethodType = checker->GetTypeOfVariable(resolveRes[0]->Variable());
203- auto *resolvedType = extensionMethodType;
204- if (classMethodType->IsETSArrowType()) {
205- auto *callee = const_cast<ir::Expression *>(this->AsExpression());
206- callee->AsMemberExpression()->AddMemberKind(ir::MemberExpressionKind::EXTENSION_ACCESSOR);
207- return {resolveRes[0]->Variable()->TsType(), nullptr};
208- }
209- 
210- if (classMethodType->IsETSFunctionType()) {
211- ES2PANDA_ASSERT(extensionMethodType->IsETSFunctionType());
212- resolvedType = checker->CreateETSExtensionFuncHelperType(classMethodType->AsETSFunctionType(),
213- extensionMethodType->AsETSFunctionType());
214- }
215- return {resolvedType, nullptr};
216 }254 }
217 default: {255 default: {
218 ES2PANDA_UNREACHABLE();256 ES2PANDA_UNREACHABLE();
@@ -255,7 +293,7 @@ void MemberExpression::CollectUnionSignatures(checker::ETSChecker *checker, chec
255 }293 }
256}294}
257 295 
258-static bool haveDifferentSignatures(checker::ETSChecker *checker,296+static bool HaveDifferentSignatures(checker::ETSChecker *checker,
259 const MemberExpression::ComponentTypeMemberAccessors &typeSignatures)297 const MemberExpression::ComponentTypeMemberAccessors &typeSignatures)
260{298{
261 if (typeSignatures.size() < 2U || !std::holds_alternative<checker::Signature *>(typeSignatures[0].second)) {299 if (typeSignatures.size() < 2U || !std::holds_alternative<checker::Signature *>(typeSignatures[0].second)) {
@@ -355,7 +393,7 @@ checker::Type *MemberExpression::TraverseUnionMember(checker::ETSChecker *checke
355 commonPropType = checker->GlobalTypeError();393 commonPropType = checker->GlobalTypeError();
356 }394 }
357 }395 }
358- if (haveDifferentSignatures(checker, this->GetComponentTypeMemberAccessors())) {396+ if (HaveDifferentSignatures(checker, this->GetComponentTypeMemberAccessors())) {
359 checker->LogError(diagnostic::MEMBER_TYPE_MISMATCH_ACROSS_UNION, {}, Start());397 checker->LogError(diagnostic::MEMBER_TYPE_MISMATCH_ACROSS_UNION, {}, Start());
360 commonPropType = checker->GlobalTypeError();398 commonPropType = checker->GlobalTypeError();
361 }399 }
@@ -0,0 +1,31 @@
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+class A {
17+ f(): int {
18+ return 1
19+ }
20+}
21+ 
22+let f = (this: A): int => {
23+ return 42
24+}
25+ 
26+function main() {
27+ let a = new A()
28+ let fn: () => int = a.f
gogabr
gogabrgogabr4月23日

This is clearly not the expected behaviour. Expression a.f either refers to the method A.f or to the global variable f. Depending on that resolution, it either has one or the other type, but the type of the expression is not their union.

likedislike
gogabr
gogabr
4月23日 评论:
gogabr
gogabr
4月23日 评论:
Fouckttt
Fouckttt
4月23日 评论:
Fouckttt
Fouckttt
4月24日 评论:
gogabr
gogabr
4月24日 评论:
Fouckttt
Fouckttt
4月25日 评论:
Fouckttt
Fouckttt
4月25日 评论:
29+}
30+ 
31+/* @@? 28:25 Error Semantic error ESE0318: Type '(() => Int) | ((p1: A) => Int)' cannot be assigned to type '(() => Int)' */
@@ -0,0 +1,30 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+let g = (this: A): boolean => {
20+ return true
21+}
22+ 
23+let f: FA = (this: A): Function => {
24+ this.g()
25+ return () => {
26+ return 1
27+ }
28+ let a = new A()
29+ a.g()
30+}
@@ -0,0 +1,35 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+function main() {
20+ let g = (this: A): boolean => {
21+ return true
22+ }
23+ let f: FA = (this: A): Function => {
24+ this.g()
25+ return () => {
26+ return 1
27+ }
28+ let a = new A()
29+ a.g()
30+ }
31+}
32+ 
33+ 
34+/* @@? 28:9 Warning Warning W0026: Unreachable statement. */
35+/* @@? 29:9 Warning Warning W0026: Unreachable statement. */
@@ -0,0 +1,34 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+function main() {
20+ let g = (this: A): boolean => {
21+ return true
22+ }
23+ let f: FA = (this: A): Function => {
24+ return () => {
25+ return 1
26+ }
27+ let a = new A()
28+ a.g()
29+ }
30+}
31+ 
32+ 
33+/* @@? 27:9 Warning Warning W0026: Unreachable statement. */
34+/* @@? 28:9 Warning Warning W0026: Unreachable statement. */
@@ -0,0 +1,28 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+function main() {
20+ let a: A = new A()
21+ let f: FA = (this: A): Function => {
22+ return this.f
23+ }
24+ a.f()
25+}
26+ 
27+ 
28+/* @@? 22:21 Error Semantic error ESE0087: Property 'f' does not exist on type 'A' */
@@ -0,0 +1,27 @@
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+interface I {}
17+type FI = (this: I) => Function
18+ 
19+function main() {
20+ let i: I = {}
21+ let f: FI = (this: I): Function => {
22+ return this.f
23+ }
24+}
gogabr
gogabrgogabr4月21日

What additional value does this test bring compared to this_parameter_case04?

likedislike
Fouckttt
Fouckttt
4月22日 评论:
25+ 
26+ 
27+/* @@? 22:21 Error Semantic error ESE0087: Property 'f' does not exist on type 'I' */
@@ -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+class A {}
17+type FA = (this: A) => Function
18+ 
19+let a: A = new A()
20+ 
21+function foo(this: A) {
22+ return this.foo
23+}
24+ 
25+ 
26+/* @@? 22:17 Error Semantic error ESE0087: Property 'foo' does not exist on type 'A' */
@@ -0,0 +1,29 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+let a: A = new A()
20+let f = (this: A) => {
21+ return 1
22+}
23+ 
24+function foo(this: A) {
25+ return this.f
26+}
27+ 
28+ 
29+/* @@? 25:17 Error Semantic error ESE0087: Property 'f' does not exist on type 'A' */
@@ -0,0 +1,27 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+let a: A = new A()
20+ 
21+function f(this: A) {
22+ return 1
23+}
24+ 
25+function foo(this: A) {
26+ return this.f()
27+}
@@ -0,0 +1,30 @@
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+class A {}
17+type FA = (this: A) => Function
18+ 
19+let a: A = new A()
20+ 
21+function f(this: A) {
22+ return 1
23+}
24+ 
25+function foo(this: A) {
26+ return this.f
27+}
28+ 
29+ 
30+/* @@? 26:17 Error Semantic error ESE0087: Property 'f' does not exist on type 'A' */
@@ -0,0 +1,27 @@
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+class A {
17+ f: () => int = () => 0
18+}
19+ 
20+let f = (this: A): int => {
21+ return 42
22+}
23+ 
24+function main() {
25+ let a = new A()
26+ arktest.assertEQ(a.f(), 42)
27+}
@@ -0,0 +1,31 @@
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+class A {
17+ val: int = 10
18+ f: () => int = () => 0
19+}
20+ 
21+let f = (this: A): int => {
22+ return this.val + 100
23+}
24+ 
25+function main(): void {
26+ let a = new A()
27+ arktest.assertEQ(a.f(), 110)
28+ a.f = () => a.val
29+ let fn = a.f
30+ arktest.assertEQ(fn(), 10)
31+}
@@ -0,0 +1,37 @@
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+class A {
17+ _value: int = 10
18+}
19+ 
20+get value(this: A): int {
21+ return this._value
22+}
23+ 
24+set value(this: A, v: int) {
25+ this._value = v
26+}
27+ 
28+function main(): void {
29+ let a = new A()
30+ arktest.assertEQ(a.value, 10)
31+ a.value = 20
32+ arktest.assertEQ(a.value, 20)
33+ a.value++
34+ arktest.assertEQ(a.value, 21)
35+ ++a.value
36+ arktest.assertEQ(a.value, 22)
37+}
@@ -0,0 +1,33 @@
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+class A {
17+ _value: int = 10
18+}
19+ 
20+get value(this: A): int {
21+ return this._value
22+}
23+ 
24+set value(this: A, v: int) {
25+ this._value = v
26+}
27+ 
28+function main(): void {
29+ let a = new A()
30+ arktest.assertEQ(a.value, 10)
31+ a.value = 20
32+ arktest.assertEQ(a.value, 20)
33+}
@@ -0,0 +1,30 @@
1+/*
fanglou
fangloufanglou4月24日

The case can be placed in the runtime test.

likedislike
Fouckttt
Fouckttt
4月25日 评论:
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+class A {
17+ f(x: int): int {
18+ return x
19+ }
20+}
21+ 
22+function f(this: A): int {
23+ return 42
24+}
25+ 
26+function main() {
27+ let a = new A()
28+ arktest.assertEQ(a.f(), 42)
29+ arktest.assertEQ(a.f(1), 1)
30+}