diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index d4d6da099598b17512956f7616ee438ceaadc2f7..a2d79357e9e17c1761403dbe28594b5de707eb18 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -119,7 +119,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinition *node) { auto *scriptFunc = node->Function(); - if (node->IsNative()) { + if (node->IsNative() && !node->IsConstructor()) { if (scriptFunc->ReturnTypeAnnotation() == nullptr) { checker->LogTypeError("'Native' method should have explicit return type", scriptFunc->Start()); node->SetTsType(checker->GlobalTypeError()); @@ -180,7 +180,7 @@ checker::Type *ETSAnalyzer::Check(ir::MethodDefinition *node) const } if (scriptFunc->ReturnTypeAnnotation() == nullptr && - (node->IsNative() || (node->IsDeclare() && !node->IsConstructor()))) { + ((node->IsNative() || node->IsDeclare()) && !node->IsConstructor())) { checker->LogTypeError("Native and Declare methods should have explicit return type.", scriptFunc->Start()); node->SetTsType(checker->GlobalTypeError()); return node->TsType(); diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index 32624428301bf26e54ec40feb0d419ef9a6f6a79..564e2e25b2f8fcc2b7e22f22d434b7b32794b594 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -113,11 +113,27 @@ void CheckExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *exte } } -void DoBodyTypeChecking(ETSChecker *checker, ir::MethodDefinition *node, ir::ScriptFunction *scriptFunc) +static void CheckMethodBodyForNativeAbstractDeclare(ETSChecker *checker, ir::MethodDefinition *node, + ir::ScriptFunction *scriptFunc) { - if (scriptFunc->HasBody() && (node->IsNative() || node->IsAbstract() || node->IsDeclare())) { + if ((node->IsNative() && !node->IsConstructor()) || node->IsAbstract() || node->IsDeclare()) { checker->LogTypeError("Native, Abstract and Declare methods cannot have body.", scriptFunc->Body()->Start()); } +} + +static void CheckNativeConstructorBody(ETSChecker *checker, ir::MethodDefinition *node, ir::ScriptFunction *scriptFunc) +{ + if (node->IsNative() && node->IsConstructor()) { + checker->LogTypeError("Native constructor declaration cannot have a body.", scriptFunc->Body()->Start()); + } +} + +void DoBodyTypeChecking(ETSChecker *checker, ir::MethodDefinition *node, ir::ScriptFunction *scriptFunc) +{ + if (scriptFunc->HasBody()) { + CheckMethodBodyForNativeAbstractDeclare(checker, node, scriptFunc); + CheckNativeConstructorBody(checker, node, scriptFunc); + } if (!scriptFunc->IsAsyncFunc() && scriptFunc->HasBody() && (!scriptFunc->IsExternal() || scriptFunc->IsExternalOverload())) { diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 73db29f010ef841e91439e0d3331ee2ce50ef3ef..24d318fa7b1a3161f436317e8be1bbc51d5064f5 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1166,6 +1166,10 @@ void ETSChecker::CheckImplicitSuper(ETSObjectType *classType, Signature *ctorSig return; } + if (ctorSig->Function()->IsNative() && ctorSig->Function()->IsConstructor()) { + return; + } + auto &stmts = ctorSig->Function()->Body()->AsBlockStatement()->Statements(); const auto thisCall = std::find_if(stmts.begin(), stmts.end(), [](const ir::Statement *stmt) { return stmt->IsExpressionStatement() && stmt->AsExpressionStatement()->GetExpression()->IsCallExpression() && @@ -1200,6 +1204,10 @@ void ETSChecker::CheckThisOrSuperCallInConstructor(ETSObjectType *classType, Sig return; } + if (ctorSig->Function()->IsNative() && ctorSig->Function()->IsConstructor()) { + return; + } + for (auto it : ctorSig->Function()->Body()->AsBlockStatement()->Statements()) { if (it->IsExpressionStatement() && it->AsExpressionStatement()->GetExpression()->IsCallExpression() && (it->AsExpressionStatement()->GetExpression()->AsCallExpression()->Callee()->IsThisExpression() || diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 2eae2aa8c97f80af5c1d29f1bc0420623b39dc99..24b26ec318e7b91f6c935e49be638c3bab2bf29a 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -461,10 +461,12 @@ ir::AstNode *ETSParser::ParseInnerConstructorDeclaration(ir::ModifierFlags membe if ((GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0) { LogSyntaxError({"Namespaces should not have a constructor"}); } - if ((memberModifiers & (~(ir::ModifierFlags::ACCESS | ir::ModifierFlags::DECLARE))) != 0) { + + if ((memberModifiers & (~(ir::ModifierFlags::ACCESS | ir::ModifierFlags::DECLARE | ir::ModifierFlags::NATIVE))) != + 0) { LogSyntaxError( - {"The modifier for a constructor should be limited to access modifiers(private, internal, protected, " - "public)."}); + {"The modifier for a constructor should be limited to access modifiers (private, internal, protected, " + "public),and 'native' modifiers."}); } auto *memberName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); memberModifiers |= ir::ModifierFlags::CONSTRUCTOR; diff --git a/ets2panda/test/ast/compiler/ets/native_constructor.sts b/ets2panda/test/ast/compiler/ets/native_constructor.sts new file mode 100644 index 0000000000000000000000000000000000000000..8cbbe8fda7dcea8022b3566aac3bdaf3eeb4732f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/native_constructor.sts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 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. + */ + +class Apple{ + x: number + y: number + + + native constructor() + + native constructor(x:number) + + native constructor(x:number,y:number) + + +} \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts b/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts index 8173ddc39b506c3e1677d530023508e66ddb12fc..f16967226f97aa20c3e59094c5c5921277ba1b78 100644 --- a/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts +++ b/ets2panda/test/ast/parser/ets/MultipleParserErrors.sts @@ -168,7 +168,7 @@ function main(): void { /* @@? 18:14 Error SyntaxError: Optional variable is not allowed in for of statements */ /* @@? 28:12 Error SyntaxError: Modifiers of getter and setter are limited to ('abstract', 'static', 'final', 'override'). */ -/* @@? 34:14 Error SyntaxError: The modifier for a constructor should be limited to access modifiers(private, internal, protected, public). */ +/* @@? 34:14 Error SyntaxError: The modifier for a constructor should be limited to access modifiers (private, internal, protected, public),and 'native' modifiers. */ /* @@? 37:33 Error SyntaxError: Only 'throws' can be used with function types */ /* @@? 37:33 Error SyntaxError: Unexpected token 'identification literal'. */ /* @@? 39:14 Error SyntaxError: Unexpected token, expected an identifier. */ diff --git a/ets2panda/test/ast/parser/ets/abstract_class_modidier.sts b/ets2panda/test/ast/parser/ets/abstract_class_modidier.sts index d902f1903c06d5a059b5b23d36b96ab73e475406..6ef9a7af5fd6cc96b0f70f1bfffad48ee393fbc6 100644 --- a/ets2panda/test/ast/parser/ets/abstract_class_modidier.sts +++ b/ets2panda/test/ast/parser/ets/abstract_class_modidier.sts @@ -17,4 +17,4 @@ abstract class A{ abstract /* @@ label */constructor(val: int); }; -/* @@@ label Error SyntaxError: The modifier for a constructor should be limited to access modifiers(private, internal, protected, public). */ +/* @@@ label Error SyntaxError: The modifier for a constructor should be limited to access modifiers (private, internal, protected, public),and 'native' modifiers. */ diff --git a/ets2panda/test/ast/parser/ets/async_ctor.sts b/ets2panda/test/ast/parser/ets/async_ctor.sts index 93015263a3fcc1c477273b963e588857e6cfb9d0..5ed10bbae0c97a865310f9247fc8e4ebafa392f6 100644 --- a/ets2panda/test/ast/parser/ets/async_ctor.sts +++ b/ets2panda/test/ast/parser/ets/async_ctor.sts @@ -17,4 +17,4 @@ class Test { async /* @@ label */constructor() {} } -/* @@@ label Error SyntaxError: The modifier for a constructor should be limited to access modifiers(private, internal, protected, public). */ +/* @@@ label Error SyntaxError: The modifier for a constructor should be limited to access modifiers (private, internal, protected, public),and 'native' modifiers. */ diff --git a/ets2panda/test/ast/parser/ets/declare_class_neg.sts b/ets2panda/test/ast/parser/ets/declare_class_neg.sts new file mode 100644 index 0000000000000000000000000000000000000000..6fb9b2f40bbeb4c4e0b7d68c9b90796b1db907af --- /dev/null +++ b/ets2panda/test/ast/parser/ets/declare_class_neg.sts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 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. + */ + +declare class A { + declare constructor() +} +class B { + declare constructor() +} +/* @@? 17:11 Error SyntaxError: Field type annotation expected */ +/* @@? 20:11 Error SyntaxError: Field type annotation expected */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/native_constructor_empty_body.sts b/ets2panda/test/ast/parser/ets/native_constructor_empty_body.sts new file mode 100644 index 0000000000000000000000000000000000000000..73205eac6d27c2687b5cccf05f9edb8c81c0f3d6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/native_constructor_empty_body.sts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 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. + */ + +class Apple{ + x: number + y: number + + + native constructor(){ + + } + native constructor(x:number){ + + } + + native constructor(x:number,y:number){ + } + + +} +/* @@? 21:23 Error TypeError: Native constructor declaration cannot have a body. */ +/* @@? 24:31 Error TypeError: Native constructor declaration cannot have a body. */ +/* @@? 28:40 Error TypeError: Native constructor declaration cannot have a body. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/native_constructor_non_empty_body.sts b/ets2panda/test/ast/parser/ets/native_constructor_non_empty_body.sts new file mode 100644 index 0000000000000000000000000000000000000000..46da6f60bff84abe5843fd81dfe931a4bd9f9aed --- /dev/null +++ b/ets2panda/test/ast/parser/ets/native_constructor_non_empty_body.sts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 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. + */ + +class Apple{ + x: number + y: number + + native constructor(x:number){ + this.x=x + } + + native constructor(x:number,y:number){ + this.x=x + this.y=y + } +} +/* @@? 20:31 Error TypeError: Native constructor declaration cannot have a body. */ +/* @@? 24:40 Error TypeError: Native constructor declaration cannot have a body. */ \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/declare_class.sts b/ets2panda/test/runtime/ets/declare_class.sts new file mode 100644 index 0000000000000000000000000000000000000000..d9259114cc2a183ef4de9ec8efed552016739d3f --- /dev/null +++ b/ets2panda/test/runtime/ets/declare_class.sts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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. + */ + +declare class A{ + constructor() +} + +function main(): void { +} \ No newline at end of file