diff --git a/ets2panda/bindings/src/common/types.ts b/ets2panda/bindings/src/common/types.ts index fdfcd1d480c211d8c29cc1a9f3ca72dd586210c2..7f5cf55f9580fb836ea0c1886ea9cedc9606fa53 100644 --- a/ets2panda/bindings/src/common/types.ts +++ b/ets2panda/bindings/src/common/types.ts @@ -233,22 +233,57 @@ export interface TextDocumentChangeInfo { } export enum AstNodeType { + ANNOTATION_DECLARATION = 1, + ANNOTATION_USAGE = 2, + AWAIT_EXPRESSION = 4, + BIGINT_LITERAL = 5, + BOOLEAN_LITERAL = 8, + BREAK_STATEMENT = 9, + CALL_EXPRESSION = 10, + CATCH_CLAUSE = 11, + CHAR_LITERAL = 13, CLASS_DEFINITION = 14, + CLASS_DECLARATION = 15, CLASS_PROPERTY = 17, + CLASS_STATIC_BLOCK = 18, + EMPTY_STATEMENT = 25, EXPORT_DEFAULT_DECLARATION = 27, EXPORT_NAMED_DECLARATION = 28, EXPORT_SPECIFIER = 29, + EXPRESSION_STATEMENT = 30, + FUNCTION_EXPRESSION = 35, IDENTIFIER = 36, + IMPORT_DECLARATION = 39, + IMPORT_DEFAULT_SPECIFIER = 41, + IMPORT_NAMESPACE_SPECIFIER = 42, + IMPORT_SPECIFIER = 43, MEMBER_EXPRESSION = 45, METHOD_DEFINITION = 47, PROPERTY = 56, + REEXPORT_STATEMENT = 58, + RETURN_STATEMENT = 59, + SCRIPT_FUNCTION = 60, + ETS_STRING_LITERAL_TYPE = 67, ETS_FUNCTION_TYPE = 69, + ETS_TYPE_REFERENCE = 74, + ETS_KEYOF_TYPE = 77, + ETS_NEW_CLASS_INSTANCE_EXPRESSION = 80, + ETS_IMPORT_DECLARATION = 81, + ETS_PARAMETER_EXPRESSION = 82, + SUPER_EXPRESSION = 85, + STRUCT_DECLARATION = 86, TS_ENUM_DECLARATION = 89, TS_ENUM_MEMBER = 90, + TS_TYPE_PARAMETER = 120, + TS_FUNCTION_TYPE = 127, TS_MODULE_DECLARATION = 125, TS_TYPE_ALIAS_DECLARATION = 129, + TS_TYPE_REFERENCE = 130, TS_INTERFACE_DECLARATION = 133, TS_CLASS_IMPLEMENTS = 141, + VARIABLE_DECLARATION = 152, + VARIABLE_DECLARATOR = 153, + SPREAD_ELEMENT = 165, UNKNOWN, } diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts index 85aa4cbbd7a2d93f1f34c2f07bf291f553532934..146f59ff82b7b20b4730d019cd13da6b6d1a3618 100644 --- a/ets2panda/bindings/test/cases.ts +++ b/ets2panda/bindings/test/cases.ts @@ -179,6 +179,150 @@ export const basicCases: TestCases = { } ] as NodeInfo[] ], + '25': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition32.d.ets' + ), + 0, + [ + { + kind: AstNodeType.ANNOTATION_DECLARATION, + name: 'Validate' + } + ] as NodeInfo[] + ], + '26': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition32.d.ets' + ), + 0, + [ + { + kind: AstNodeType.ANNOTATION_USAGE, + name: 'Log' + } + ] as NodeInfo[] + ], + '27': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition33.d.ets' + ), + 0, + [ + { + kind: AstNodeType.AWAIT_EXPRESSION, + name: 'p' + } + ] as NodeInfo[] + ], + '28': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition34.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CLASS_DECLARATION, + name: 'Derived' + } + ] as NodeInfo[] + ], + '29': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition35.d.ets' + ), + 0, + [ + { + kind: AstNodeType.IMPORT_SPECIFIER, + name: 'State' + } + ] as NodeInfo[] + ], + '30': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition35.d.ets' + ), + 0, + [ + { + kind: AstNodeType.IMPORT_DEFAULT_SPECIFIER, + name: 'hilog' + } + ] as NodeInfo[] + ], + '31': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition35.d.ets' + ), + 0, + [ + { + kind: AstNodeType.IMPORT_NAMESPACE_SPECIFIER, + name: 'All' + } + ] as NodeInfo[] + ], + '32': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition36.d.ets' + ), + 0, + [ + { + kind: AstNodeType.PROPERTY, + name: 'prop' + } + ] as NodeInfo[] + ], + '33': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition37.d.ets' + ), + 0, + [ + { + kind: AstNodeType.CALL_EXPRESSION, + name: 'a' + } + ] as NodeInfo[] + ], + '34': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition38.d.ets' + ), + 0, + [ + { + kind: AstNodeType.SUPER_EXPRESSION, + name: 'super' + } + ] as NodeInfo[] + ], + '35': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition39.d.ets' + ), + 0, + [ + { + kind: AstNodeType.REEXPORT_STATEMENT, + name: 'PI' + } + ] as NodeInfo[] + ], + '36': [ + resolveTestPath( + 'test/testcases/.idea/.deveco/getDefinitionAtPosition/declgen/static/getDefinitionAtPosition40.d.ets' + ), + 0, + [ + { + kind: AstNodeType.SCRIPT_FUNCTION, + name: 'test' + } + ] as NodeInfo[] + ] }, getSemanticDiagnostics: { expectedFilePath: resolveTestPath('test/expected/getSemanticDiagnostics.json'), diff --git a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json index ace1dbc19626ee2f4c4a6ac64cd7a73284330422..bedbaebdd606dabedd13244de709cc652c895875 100644 --- a/ets2panda/bindings/test/expected/getDefinitionAtPosition.json +++ b/ets2panda/bindings/test/expected/getDefinitionAtPosition.json @@ -108,5 +108,65 @@ "fileName": "getDefinitionAtPosition30.ets", "start": 714, "length": 9 + }, + "25": { + "fileName": "getDefinitionAtPosition32.ets", + "start": 631, + "length": 8 + }, + "26": { + "fileName": "getDefinitionAtPosition32.ets", + "start": 855, + "length": 3 + }, + "27": { + "fileName": "getDefinitionAtPosition33.ets", + "start": 702, + "length": 1 + }, + "28": { + "fileName": "getDefinitionAtPosition34.ets", + "start": 665, + "length": 7 + }, + "29": { + "fileName": "getDefinitionAtPosition35.ets", + "start": 629, + "length": 5 + }, + "30": { + "fileName": "getDefinitionAtPosition35.ets", + "start": 680, + "length": 5 + }, + "31": { + "fileName": "getDefinitionAtPosition35.ets", + "start": 719, + "length": 3 + }, + "32": { + "fileName": "getDefinitionAtPosition36.ets", + "start": 638, + "length": 4 + }, + "33": { + "fileName": "getDefinitionAtPosition37.ets", + "start": 657, + "length": 1 + }, + "34": { + "fileName": "getDefinitionAtPosition38.ets", + "start": 800, + "length": 5 + }, + "35": { + "fileName": "getDefinitionAtPosition39.ets", + "start": 629, + "length": 2 + }, + "36": { + "fileName": "getDefinitionAtPosition40.ets", + "start": 629, + "length": 4 } } diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition31.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition31.ets new file mode 100644 index 0000000000000000000000000000000000000000..2ed0e747c20196f45ce3ca66cc4bbd0d5a9ba437 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition31.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +type Direction = 'up' | 'down' | 'left' | 'right'; +function move(dir: Direction): void { + let a = 'aaa'; + const b: Direction = 'up'; + let c = true; +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition32.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition32.ets new file mode 100644 index 0000000000000000000000000000000000000000..f8ec2c9f2244facc897f8cb4177fe8210e9bf545 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition32.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +@interface Validate { + +} + +@interface Log { + level: string; +} + +@interface Component1 { + name: string; + version: number; +} + +@interface Deprecated { + +} + +@Component1({name: 'Service', version: 1}) +class Service { + @Validate + @Log({level: 'info'}) + doSomething() { + // ... + } + + @Deprecated + oldMethod() { + // ... + } +} + diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition33.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition33.ets new file mode 100644 index 0000000000000000000000000000000000000000..ee76064b43c49d7249fe816e546f9ebe77fa9f43 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition33.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +function foo1(p: Promise>): void { + let result: string = await p; +} diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition34.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition34.ets new file mode 100644 index 0000000000000000000000000000000000000000..098e949ea089c855a2f87ab83674eed08c756dcc --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition34.ets @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +class Base { + prop1: number = 1; +} + +class Derived extends Base { + prop2: string = "test"; +} + +class StaticClass { + static staticMethod() {} +} + +class PrivateClass { + private privProp: boolean = true; +} + +class EmptyClass {} + +class StaticFoo { + static { + console.log('init'); + } +} + diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition35.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition35.ets new file mode 100644 index 0000000000000000000000000000000000000000..25f7060f9b11d7d253557900e3dad5f7791cf369 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition35.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +import { State} from '@ohos.arkui.stateManagement'; + +import hilog from '@ohos.hilog'; + +import * as All from './getDefinitionAtPosition8'; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition36.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition36.ets new file mode 100644 index 0000000000000000000000000000000000000000..daf1b623baccd6578f47d12e0680e77c1ed7262e --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition36.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +const obj = { + prop: 'value' +}; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition37.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition37.ets new file mode 100644 index 0000000000000000000000000000000000000000..4026ecae0478f497137c796544ae3ddac6387264 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition37.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +function a() { + return 'hello'; +} +a(); \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition38.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition38.ets new file mode 100644 index 0000000000000000000000000000000000000000..9b2ede310e715ee43748340e43c556ac0e80505f --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition38.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +class Parent { + name: string; + constructor(name: string) { + this.name = name; + } +} +class Child extends Parent { + age: number; + constructor(name: string, age: number) { + super(name); + this.age = age; + } +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition39.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition39.ets new file mode 100644 index 0000000000000000000000000000000000000000..c774945efcf029fc669a1478501bd3c3bfa72e83 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition39.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +export { PI } from "std/math"; \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition40.ets b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition40.ets new file mode 100644 index 0000000000000000000000000000000000000000..547f9802ece6a33f716fadbfb67b8cc8bf21e8b1 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getDefinitionAtPosition/getDefinitionAtPosition40.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 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. + */ + +'use static'; + +function test(){} \ No newline at end of file diff --git a/ets2panda/lsp/include/node_matchers.h b/ets2panda/lsp/include/node_matchers.h index a57247b70ccb95171ca54eaa79c0dd868a8d7bbc..0a778cd6aeab6c6252641052a52f264fa8c90fb6 100755 --- a/ets2panda/lsp/include/node_matchers.h +++ b/ets2panda/lsp/include/node_matchers.h @@ -37,10 +37,36 @@ bool MatchTSTypeAliasDeclaration(ir::AstNode *childNode, const NodeInfo *info); bool MatchExportSpecifier(ir::AstNode *childNode, const NodeInfo *info); bool MatchMemberExpression(ir::AstNode *childNode, const NodeInfo *info); bool MatchTSClassImplements(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsStringLiteralType(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsTypeReference(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsKeyofType(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsNewClassInstanceExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsStructDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchSpreadElement(ir::AstNode *childNode, const NodeInfo *info); +bool MatchCallExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTsTypeReference(ir::AstNode *childNode, const NodeInfo *info); +bool MatchScriptFunction(ir::AstNode *childNode, const NodeInfo *info); +bool MatchVariableDeclarator(ir::AstNode *childNode, const NodeInfo *info); +bool MatchVariableDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchClassDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAnnotationDeclaration(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAnnotationUsage(ir::AstNode *childNode, const NodeInfo *info); +bool MatchAwaitExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchBigIntLiteral(ir::AstNode *childNode, const NodeInfo *info); +bool MatchImportSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchImportDefaultSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchImportNamespaceSpecifier(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTSTypeParameter(ir::AstNode *childNode, const NodeInfo *info); +bool MatchSwitchStatement(ir::AstNode *childNode, const NodeInfo *info); +bool MatchEtsParameterExpression(ir::AstNode *childNode, const NodeInfo *info); +bool MatchTsNonNullExpression(ir::AstNode *childNode, const NodeInfo *info); ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo *info); ir::AstNode *ExtractTSClassImplementsIdentifier(ir::AstNode *node, const NodeInfo *info); ir::AstNode *ExtractIdentifierFromNode(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractETSStringLiteralTypeIdentifier(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractETSKeyofTypeIdentifier(ir::AstNode *node, const NodeInfo *info); +ir::AstNode *ExtractCallExpressionIdentifier(ir::AstNode *node, const NodeInfo *info); extern const std::unordered_map nodeMatchers; } // namespace ark::es2panda::lsp #endif // NODE_MATCHERS_H \ No newline at end of file diff --git a/ets2panda/lsp/src/node_matchers.cpp b/ets2panda/lsp/src/node_matchers.cpp old mode 100755 new mode 100644 index f50d62cd0e3e727cb8dc3ee643afda0eb70a033f..1114828e89a48da945e95c892ca9f47cc195e566 --- a/ets2panda/lsp/src/node_matchers.cpp +++ b/ets2panda/lsp/src/node_matchers.cpp @@ -18,6 +18,8 @@ #include "public/es2panda_lib.h" #include "public/public.h" #include "ir/ets/etsReExportDeclaration.h" +#include "ir/statements/annotationDeclaration.h" +#include "ir/statements/annotationUsage.h" namespace ark::es2panda::lsp { @@ -84,6 +86,10 @@ bool MatchExportSpecifier(ir::AstNode *childNode, const NodeInfo *info) importSpecifier->AsImportSpecifier()->Local()->Name().Mutf8() == info->name) { return true; } + if (importSpecifier->IsImportSpecifier() && + importSpecifier->AsImportSpecifier()->Imported()->Name().Mutf8() == info->name) { + return true; + } } return false; } @@ -102,6 +108,44 @@ bool MatchTSClassImplements(ir::AstNode *childNode, const NodeInfo *info) return std::string(dd->GetIdent()->Name()) == info->name; } +bool MatchCallExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (childNode->IsCallExpression()) { + auto callExpr = childNode->AsCallExpression(); + auto callee = callExpr->Callee(); + if (callee->IsIdentifier()) { + return std::string(callee->AsIdentifier()->Name()) == info->name; + } + if (callee->IsSuperExpression() && info->name == "super") { + return true; + } + if (callee->IsMemberExpression()) { + return callee->AsMemberExpression()->Property()->ToString() == info->name; + } + } + return false; +} + +bool MatchTsTypeReference(ir::AstNode *childNode, const NodeInfo *info) +{ + if (childNode->IsETSTypeReference()) { + auto typeRef = childNode->AsETSTypeReference(); + auto part = typeRef->Part(); + if (part != nullptr && part->Name()->IsIdentifier()) { + auto identifier = part->Name()->AsIdentifier(); + if (std::string(identifier->Name()) == info->name) { + return true; + } + } + } + return false; +} + +bool MatchScriptFunction(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsScriptFunction() && std::string(childNode->AsScriptFunction()->Id()->Name()) == info->name; +} + ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo *info) { if (!node->IsETSReExportDeclaration()) { @@ -121,6 +165,9 @@ ir::AstNode *ExtractExportSpecifierIdentifier(ir::AstNode *node, const NodeInfo if (importSpecifier->AsImportSpecifier()->Local()->Name().Mutf8() == info->name) { return importSpecifier->AsImportSpecifier()->Local(); } + if (importSpecifier->AsImportSpecifier()->Imported()->Name().Mutf8() == info->name) { + return importSpecifier->AsImportSpecifier()->Imported(); + } } return node; @@ -149,6 +196,284 @@ ir::AstNode *ExtractTSClassImplementsIdentifier(ir::AstNode *node, const NodeInf return node; } +bool getNodeNameIsStringLiteralType(ir::AstNode *childNode, const std::string &nodeName) +{ + if (childNode->Parent() == nullptr) { + return false; + } + auto parentNode = reinterpret_cast(childNode->Parent()); + if (parentNode->IsClassProperty()) { + return std::string(parentNode->AsClassProperty()->Id()->Name()) == nodeName; + } else if (parentNode->IsIdentifier()) { + return std::string(parentNode->AsIdentifier()->Name()) == nodeName; + } else if (parentNode->IsETSUnionType()) { + auto unionTypeParentAst = reinterpret_cast(parentNode->Parent()); + if (unionTypeParentAst->IsTSTypeAliasDeclaration()) { + return std::string(unionTypeParentAst->AsTSTypeAliasDeclaration()->Id()->Name()) == nodeName; + } + } else if (parentNode->IsETSParameterExpression()) { + return std::string(parentNode->AsETSParameterExpression()->Name()) == nodeName; + } else if (parentNode->IsTSTypeAliasDeclaration()) { + return std::string(parentNode->AsTSTypeAliasDeclaration()->Id()->Name()) == nodeName; + } + return false; +} + +bool MatchEtsStringLiteralType(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSStringLiteralType()) { + return false; + } + if (getNodeNameIsStringLiteralType(childNode, std::string(info->name))) { + return true; + } + return false; +} + +ir::AstNode *ExtractETSStringLiteralTypeIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsETSStringLiteralType()) { + return nullptr; + } + if (getNodeNameIsStringLiteralType(node, std::string(info->name))) { + return node->Parent(); + } + return nullptr; +} + +bool MatchEtsTypeReference(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSTypeReference()) { + return false; + } + return std::string(childNode->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; +} + +bool MatchEtsKeyofType(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSKeyofType()) { + return false; + } + + auto typeRef = childNode->AsETSKeyofType()->GetTypeRef(); + if (typeRef == nullptr) { + return false; + } + return typeRef->IsETSTypeReference() && + std::string(typeRef->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; +} + +ir::AstNode *ExtractETSKeyofTypeIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (!node->IsETSKeyofType()) { + return nullptr; + } + auto typeRef = node->AsETSKeyofType()->GetTypeRef(); + if (typeRef == nullptr) { + return nullptr; + } + bool result = typeRef->IsETSTypeReference() && + std::string(typeRef->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; + if (result) { + return node->Parent(); + } + return nullptr; +} + +bool MatchEtsNewClassInstanceExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSNewClassInstanceExpression()) { + return false; + } + + auto typeRef = childNode->AsETSNewClassInstanceExpression()->GetTypeRef(); + if (typeRef == nullptr) { + return false; + } + return typeRef->IsETSTypeReference() && + std::string(typeRef->AsETSTypeReference()->Part()->Name()->ToString()) == info->name; +} + +bool MatchEtsStructDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsETSStructDeclaration()) { + return false; + } + return std::string(childNode->AsETSStructDeclaration()->Definition()->Ident()->Name()) == info->name; +} + +bool MatchSpreadElement(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsSpreadElement()) { + return false; + } + auto argument = childNode->AsSpreadElement()->Argument(); + if (argument == nullptr) { + return false; + } + + if (argument->IsIdentifier()) { + return std::string(argument->AsIdentifier()->Name()) == info->name; + } else if (argument->IsMemberExpression()) { + return std::string(argument->AsMemberExpression()->Property()->ToString()) == info->name; + } + + return false; +} + +ir::AstNode *ExtractCallExpressionIdentifier(ir::AstNode *node, const NodeInfo *info) +{ + if (node->IsCallExpression()) { + auto callExpr = node->AsCallExpression(); + auto callee = callExpr->Callee(); + if (callee->IsIdentifier() && std::string(callee->AsIdentifier()->Name()) == info->name) { + return callee->AsIdentifier(); + } + if (callee->IsSuperExpression() && info->name == "super") { + return callee->AsSuperExpression(); + } + if (callee->IsMemberExpression() && callee->AsMemberExpression()->Property()->ToString() == info->name) { + return callee->AsMemberExpression()->Property()->AsIdentifier(); + } + } + return node; +} + +bool MatchVariableDeclarator(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsVariableDeclarator() && + std::string(childNode->AsVariableDeclarator()->Id()->AsIdentifier()->Name()) == info->name; +} + +bool MatchVariableDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsVariableDeclaration() && + std::string(childNode->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier()->Name()) == + info->name; +} + +bool MatchClassDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsClassDeclaration() && + std::string(childNode->AsClassDeclaration()->Definition()->Ident()->Name()) == info->name; +} + +bool MatchAnnotationDeclaration(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsAnnotationDeclaration() && + std::string(childNode->AsAnnotationDeclaration()->GetBaseName()->Name()) == info->name; +} + +bool MatchAnnotationUsage(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsAnnotationUsage() && + std::string(childNode->AsAnnotationUsage()->GetBaseName()->Name()) == info->name; +} + +bool MatchAwaitExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsAwaitExpression()) { + return false; + } + auto awaitExpr = childNode->AsAwaitExpression(); + if (awaitExpr && awaitExpr->Argument() && awaitExpr->Argument()->IsIdentifier()) { + auto identifier = awaitExpr->Argument()->AsIdentifier(); + return identifier && std::string(identifier->Name()) == info->name; + } + return false; +} + +bool MatchBigIntLiteral(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsBigIntLiteral()) { + return false; + } + std::string bigIntLiteral = std::string(childNode->AsBigIntLiteral()->Str()); + if (childNode->Parent()->IsUnaryExpression()) { + bigIntLiteral.insert(0, lexer::TokenToString(childNode->Parent()->AsUnaryExpression()->OperatorType())); + return bigIntLiteral == info->name; + } + return bigIntLiteral == info->name; +} + +ir::AstNode *ExtractAwaitExpressionIdentifier(ir::AstNode *node, const NodeInfo *) +{ + if (!node->IsAwaitExpression()) { + return node; + } + + if (node->AsAwaitExpression()->Argument() && node->AsAwaitExpression()->Argument()->IsIdentifier()) { + return const_cast(node->AsAwaitExpression()->Argument()->AsIdentifier()); + } + return node; +} + +bool MatchImportSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsImportSpecifier() && + std::string(childNode->AsImportSpecifier()->Imported()->Name()) == info->name; +} + +bool MatchImportDefaultSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsImportDefaultSpecifier() && + std::string(childNode->AsImportDefaultSpecifier()->Local()->Name()) == info->name; +} + +bool MatchImportNamespaceSpecifier(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsImportNamespaceSpecifier() && + std::string(childNode->AsImportNamespaceSpecifier()->Local()->Name()) == info->name; +} + +bool MatchTSTypeParameter(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsTSTypeParameter() && std::string(childNode->AsTSTypeParameter()->Name()->Name()) == info->name; +} + +bool MatchEtsParameterExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + return childNode->IsETSParameterExpression() && + std::string(childNode->AsETSParameterExpression()->Ident()->Name()) == info->name; +} + +bool MatchSwitchStatement(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsSwitchStatement()) { + return false; + } + auto discriminant = childNode->AsSwitchStatement()->Discriminant(); + if (discriminant == nullptr) { + return false; + } + if (discriminant->IsIdentifier()) { + return std::string(discriminant->AsIdentifier()->Name()) == info->name; + } + if (discriminant->IsMemberExpression()) { + return std::string(discriminant->AsMemberExpression()->Object()->AsIdentifier()->Name()) == info->name; + } + return false; +} + +bool MatchTsNonNullExpression(ir::AstNode *childNode, const NodeInfo *info) +{ + if (!childNode->IsTSNonNullExpression()) { + return false; + } + auto expression = childNode->AsTSNonNullExpression()->Expr(); + if (expression == nullptr) { + return false; + } + if (expression->IsIdentifier()) { + return std::string(expression->AsIdentifier()->Name()) == info->name; + } + if (expression->IsMemberExpression()) { + return std::string(expression->AsMemberExpression()->Object()->AsIdentifier()->Name()) == info->name || + std::string(expression->AsMemberExpression()->Property()->AsIdentifier()->Name()) == info->name; + } + return false; +} + const std::unordered_map nodeExtractors = { {ir::AstNodeType::CLASS_DEFINITION, [](ir::AstNode *node, const NodeInfo *) { @@ -189,7 +514,64 @@ const std::unordered_map nodeExtractors = { return node->IsMemberExpression() ? node->AsMemberExpression()->Property()->AsIdentifier() : node; }}, {ir::AstNodeType::TS_CLASS_IMPLEMENTS, - [](ir::AstNode *node, const NodeInfo *info) { return ExtractTSClassImplementsIdentifier(node, info); }}}; + [](ir::AstNode *node, const NodeInfo *info) { return ExtractTSClassImplementsIdentifier(node, info); }}, + {ir::AstNodeType::ETS_STRING_LITERAL_TYPE, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractETSStringLiteralTypeIdentifier(node, info); }}, + {ir::AstNodeType::ETS_KEYOF_TYPE, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractETSKeyofTypeIdentifier(node, info); }}, + {ir::AstNodeType::REEXPORT_STATEMENT, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractExportSpecifierIdentifier(node, info); }}, + {ir::AstNodeType::CALL_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractCallExpressionIdentifier(node, info); }}, + {ir::AstNodeType::SUPER_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractCallExpressionIdentifier(node, info); }}, + {ir::AstNodeType::TS_TYPE_REFERENCE, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsETSTypeReference() ? node->AsETSTypeReference()->Part()->Name()->AsIdentifier() : node; + }}, + {ir::AstNodeType::SCRIPT_FUNCTION, [](ir::AstNode *node, const NodeInfo *) { + return node->IsScriptFunction() ? node->AsScriptFunction()->Id() : node; + }}, + {ir::AstNodeType::VARIABLE_DECLARATOR, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsVariableDeclarator() ? node->AsVariableDeclarator()->Id()->AsIdentifier() : node; + }}, + {ir::AstNodeType::VARIABLE_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsVariableDeclaration() ? node->AsVariableDeclaration()->Declarators()[0]->Id()->AsIdentifier() + : node; + }}, + {ir::AstNodeType::CLASS_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsClassDeclaration() ? node->AsClassDeclaration()->Definition()->Ident() : node; + }}, + {ir::AstNodeType::ANNOTATION_DECLARATION, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsAnnotationDeclaration() ? node->AsAnnotationDeclaration()->GetBaseName() : node; + }}, + {ir::AstNodeType::ANNOTATION_USAGE, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsAnnotationUsage() ? node->AsAnnotationUsage()->GetBaseName() : node; + }}, + {ir::AstNodeType::AWAIT_EXPRESSION, + [](ir::AstNode *node, const NodeInfo *info) { return ExtractAwaitExpressionIdentifier(node, info); }}, + {ir::AstNodeType::BIGINT_LITERAL, + [](ir::AstNode *node, const NodeInfo *) { return node->IsBigIntLiteral() ? node->AsBigIntLiteral() : node; }}, + {ir::AstNodeType::IMPORT_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsImportSpecifier() ? node->AsImportSpecifier()->Imported() : node; + }}, + {ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsImportDefaultSpecifier() ? node->AsImportDefaultSpecifier()->Local() : node; + }}, + {ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER, + [](ir::AstNode *node, const NodeInfo *) { + return node->IsImportNamespaceSpecifier() ? node->AsImportNamespaceSpecifier()->Local() : node; + }}, + {ir::AstNodeType::TS_TYPE_PARAMETER, [](ir::AstNode *node, const NodeInfo *) { + return node->IsTSTypeParameter() ? node->AsTSTypeParameter()->Name() : node; + }}}; ir::AstNode *ExtractIdentifierFromNode(ir::AstNode *node, const NodeInfo *info) { @@ -215,5 +597,30 @@ const std::unordered_map nodeMatchers = { {ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION, MatchTSTypeAliasDeclaration}, {ir::AstNodeType::EXPORT_SPECIFIER, MatchExportSpecifier}, {ir::AstNodeType::MEMBER_EXPRESSION, MatchMemberExpression}, - {ir::AstNodeType::TS_CLASS_IMPLEMENTS, MatchTSClassImplements}}; + {ir::AstNodeType::TS_CLASS_IMPLEMENTS, MatchTSClassImplements}, + {ir::AstNodeType::ETS_STRING_LITERAL_TYPE, MatchEtsStringLiteralType}, + {ir::AstNodeType::ETS_TYPE_REFERENCE, MatchEtsTypeReference}, + {ir::AstNodeType::ETS_KEYOF_TYPE, MatchEtsKeyofType}, + {ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION, MatchEtsNewClassInstanceExpression}, + {ir::AstNodeType::STRUCT_DECLARATION, MatchEtsStructDeclaration}, + {ir::AstNodeType::SPREAD_ELEMENT, MatchSpreadElement}, + {ir::AstNodeType::REEXPORT_STATEMENT, MatchExportSpecifier}, + {ir::AstNodeType::CALL_EXPRESSION, MatchCallExpression}, + {ir::AstNodeType::SUPER_EXPRESSION, MatchCallExpression}, + {ir::AstNodeType::TS_TYPE_REFERENCE, MatchTsTypeReference}, + {ir::AstNodeType::SCRIPT_FUNCTION, MatchScriptFunction}, + {ir::AstNodeType::VARIABLE_DECLARATOR, MatchVariableDeclarator}, + {ir::AstNodeType::VARIABLE_DECLARATION, MatchVariableDeclaration}, + {ir::AstNodeType::CLASS_DECLARATION, MatchClassDeclaration}, + {ir::AstNodeType::ANNOTATION_DECLARATION, MatchAnnotationDeclaration}, + {ir::AstNodeType::ANNOTATION_USAGE, MatchAnnotationUsage}, + {ir::AstNodeType::AWAIT_EXPRESSION, MatchAwaitExpression}, + {ir::AstNodeType::BIGINT_LITERAL, MatchBigIntLiteral}, + {ir::AstNodeType::IMPORT_SPECIFIER, MatchImportSpecifier}, + {ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER, MatchImportDefaultSpecifier}, + {ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER, MatchImportNamespaceSpecifier}, + {ir::AstNodeType::TS_TYPE_PARAMETER, MatchTSTypeParameter}, + {ir::AstNodeType::ETS_PARAMETER_EXPRESSION, MatchEtsParameterExpression}, + {ir::AstNodeType::SWITCH_STATEMENT, MatchSwitchStatement}, + {ir::AstNodeType::TS_NON_NULL_EXPRESSION, MatchTsNonNullExpression}}; } // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index d896777b56de0f2445b854e3ac8d146968e72ef5..f3383aa43cd631629a1d432be41007a7b85c011f 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -381,3 +381,83 @@ ets2panda_add_gtest(lsp_api_get_node_export_test CPP_SOURCES ets2panda_add_gtest(lsp_api_get_node_ts_class_Implements_test CPP_SOURCES get_node_ts_class_Implements_test.cpp ) + +ets2panda_add_gtest(lsp_api_get_node_etsstring_literal_test CPP_SOURCES + get_node_string_literal_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_type_reference_test CPP_SOURCES + get_node_type_reference_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_keyof_type_test CPP_SOURCES + get_node_etskeyof_type_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_newclass_instance_test CPP_SOURCES + get_node_newclass_instance_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_etsstruct_declaration_test CPP_SOURCES + get_node_etsstruct_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_spread_element_test CPP_SOURCES + get_node_spread_element_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_ts_type_reference_test CPP_SOURCES + get_node_ts_type_reference_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_script_function_test CPP_SOURCES + get_node_script_function_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_declaration_test CPP_SOURCES + get_node_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_declarator_test CPP_SOURCES + get_node_declarator_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_class_declaration_test CPP_SOURCES + get_node_class_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_annotation_declaration_test CPP_SOURCES + get_node_annotation_declaration_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_annotation_usage_test CPP_SOURCES + get_node_annotation_usage_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_await_expression_test CPP_SOURCES + get_node_await_expression_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_bigInt_literal_test CPP_SOURCES + get_node_bigInt_literal_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_import_test CPP_SOURCES + get_node_import_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_ts_type_param_test CPP_SOURCES + get_node_ts_type_param_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_ets_parameter_expression CPP_SOURCES + get_node_ets_parameter_expression_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_switch_statement CPP_SOURCES + get_node_switch_statement_test.cpp +) + +ets2panda_add_gtest(lsp_api_get_node_ts_nonnull_expression CPP_SOURCES + get_node_ts_nonnull_expression_test.cpp +) \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ffb99775216ac6b0e4488d8d12b8a069d8bb0142 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_annotation_declaration_test.cpp @@ -0,0 +1,155 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetAnnotationDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + @interface Validate { + } + + @interface Log { + level: string; + } + + @interface Component { + name: string; + version: number; + } + + @interface Deprecated { + } + + @Component({name: "Service", version: 1}) + class Service { + @Validate + @Log({level: 'info'}) + doSomething() { + // ... + } + + @Deprecated + oldMethod() { + // ... + } + } + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetAnnotationDeclarationTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetAnnotationDeclarationTests, GetSimpleAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Validate"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetAnnotationDeclarationWithProperties) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Log"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetComplexAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Component"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetAnotherSimpleAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Deprecated"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationDeclarationTests, GetNonExistentAnnotationDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "NonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp b/ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..735daf2c26dee5b88b5f9ed10c8dd9252dad8b03 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_annotation_usage_test.cpp @@ -0,0 +1,159 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetAnnotationUsageTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + @interface Injectable { + } + + @interface Component { + name: string; + } + + @interface Log { + level: string; + } + + @interface Deprecated { + } + + @Injectable + class DatabaseService { + connect() { + return "Connected to DB"; + } + } + + @Component({name: "test"}) + class TestComponent { + @Log({level: "info"}) + doSomething() { + // ... + } + + @Deprecated + oldMethod() { + // ... + } + } + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetAnnotationUsageTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetAnnotationUsageTests, GetClassAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Injectable"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetClassAnnotationUsageWithProperties) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Component"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetMethodAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Log"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetAnotherMethodAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "Deprecated"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(annotationName), std::string::npos); +} + +TEST_F(LspGetAnnotationUsageTests, GetNonExistentAnnotationUsage) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string annotationName = "NonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {annotationName, ark::es2panda::ir::AstNodeType::ANNOTATION_USAGE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_await_expression_test.cpp b/ets2panda/test/unit/lsp/get_node_await_expression_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a2171788f5bcd45d995d3e063c70992e490068ab --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_await_expression_test.cpp @@ -0,0 +1,107 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetAwaitExpressionTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +async function foo1(p: Promise>): Promise { + let result: string = await p; +} + +async function foo2(): Promise { + let x: Promise = Promise.resolve(10.0); + let result2: number = await x; +} + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetAwaitExpressionTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetAwaitExpressionTests, GetAnyAwaitExpression) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "p"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::AWAIT_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("p"), std::string::npos); +} + +TEST_F(LspGetAwaitExpressionTests, GetAwaitExpressionByAnotherParameterName) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string paramName = "x"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {paramName, ark::es2panda::ir::AstNodeType::AWAIT_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(paramName), std::string::npos); +} + +TEST_F(LspGetAwaitExpressionTests, GetNonExistentAwaitExpression) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string paramName = "nonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {paramName, ark::es2panda::ir::AstNodeType::AWAIT_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp b/ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..685a952ceb8b311a00b451d2ca2e7b444723fc70 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_bigInt_literal_test.cpp @@ -0,0 +1,116 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetBigIntLiteralTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +let a = 153n; // bigint literal +let b = 1_153n; // bigint literal +let c = -153n; // negative bigint literal + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetBigIntLiteralTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetBigIntLiteralTests, GetBigIntLiteralByValue153n) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "153"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("153"), std::string::npos); +} + +TEST_F(LspGetBigIntLiteralTests, GetBigIntLiteralByValue1153n) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "1_153"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("1_153"), std::string::npos); +} + +TEST_F(LspGetBigIntLiteralTests, GetBigIntLiteralByValueNegative153n) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "-153"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find("153"), std::string::npos); +} + +TEST_F(LspGetBigIntLiteralTests, GetNonExistentBigIntLiteral) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string literalValue = "999"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {literalValue, ark::es2panda::ir::AstNodeType::BIGINT_LITERAL}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d0acb330eabc053ba2df82576506ace6bbe4840 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_class_declaration_test.cpp @@ -0,0 +1,158 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetClassDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + class Base { + prop1: number = 1; + } + + class Derived extends Base { + prop2: string = "test"; + } + + class StaticClass { + static staticMethod() {} + } + + class PrivateClass { + private privProp: boolean = true; + } + + class EmptyClass {} + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetClassDeclarationTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetClassDeclarationTests, GetBaseClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "Base"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetDerivedClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "Derived"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetStaticClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "StaticClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetPrivateClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "PrivateClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetEmptyClassDeclaration) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "EmptyClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(className), std::string::npos); +} + +TEST_F(LspGetClassDeclarationTests, GetNonExistentClass) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string className = "NonExistentClass"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {className, ark::es2panda::ir::AstNodeType::CLASS_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_declaration_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..58a548851f8dcce92c27bb29440bd832d36cddee --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_declaration_test.cpp @@ -0,0 +1,117 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +type Direction = 'up' | 'down' | 'left' | 'right'; +function move(dir: Direction): void { + let a = 'aaa'; + const b = 123; + let c = true; +} + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeDeclarationTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeDeclarationTests, GetLetVariableDeclaration1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeDeclarationTests, GetConstVariableDeclaration2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "b"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeDeclarationTests, GetVarVariableDeclaration3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "c"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeDeclarationTests, GetNonExistentVariable4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "nonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::IDENTIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_declarator_test.cpp b/ets2panda/test/unit/lsp/get_node_declarator_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6655f26c6aebc317c5d349833368c7fc342a70db --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_declarator_test.cpp @@ -0,0 +1,118 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspNodeDeclaratorTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( + type Direction = 'up' | 'down' | 'left' | 'right'; + function move(dir: Direction): void { + let a = 'aaa'; + const b = 123; + let c = true; + } + )"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeDeclaratorTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspNodeDeclaratorTests, GetLetVariableDeclarator1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspNodeDeclaratorTests, GetConstVariableDeclarator2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "b"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspNodeDeclaratorTests, GetSecondLetVariableDeclarator3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "c"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspNodeDeclaratorTests, GetNonExistentVariableDeclarator4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "nonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::VARIABLE_DECLARATOR}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + ASSERT_EQ(res.start, static_cast(0)); + ASSERT_EQ(res.length, static_cast(0)); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_ets_parameter_expression_test.cpp b/ets2panda/test/unit/lsp/get_node_ets_parameter_expression_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84bc1e4b7a4852feeb2fa9a7ba6eb2daa76ef9c2 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_ets_parameter_expression_test.cpp @@ -0,0 +1,210 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeEtsParameterExpressionTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +function greetTest(name: string, age: number): void { +} +const addTest = (a: number, b: number): number => a + b; + +class Person { + introduce(firstName: string, lastName: string): string { + return `I am`; + } +} + +interface MathOperation { + calculate(x: number, y: number): number; +} +type BinaryFunction = (left: any, right: any) => boolean; +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeEtsParameterExpressionTest.ets", ES2PANDA_STATE_PARSED, + sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "name"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "age"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "b"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "firstName"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest5) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "lastName"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest6) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "x"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest7) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "y"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest8) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "left"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeEtsParameterExpressionTests, GetEtsParameterExpressionTest9) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "right"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_PARAMETER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_etskeyof_type_test.cpp b/ets2panda/test/unit/lsp/get_node_etskeyof_type_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..67d069b34944655e48c102c61dfce22619a4ea3e --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_etskeyof_type_test.cpp @@ -0,0 +1,105 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeKeyofTypeTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +interface Person { + name: string; +} +type PersonKeys = keyof Person; +class User { + id: number = 0; + name: string = "jonn"; +} +type UserKeys = keyof User; +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeKeyofType.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeKeyofTypeTests, GetKeyOfTypeNonExistentTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "NonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_KEYOF_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeKeyofTypeTests, GetKeyOfTypeTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Person"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_KEYOF_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeKeyofTypeTests, GetKeyOfTypeTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "User"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_KEYOF_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_etsstruct_declaration_test.cpp b/ets2panda/test/unit/lsp/get_node_etsstruct_declaration_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1db1f5d00345e080e3be46faac470469dc992bf1 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_etsstruct_declaration_test.cpp @@ -0,0 +1,101 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeEtsStructDeclarationTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +struct Index {}; +struct Person { + name: string; + age: number; +})"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeStructDeclarationTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeEtsStructDeclarationTests, GetEtsStructDeclarationNonExistentTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "NonExistentStruct"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::STRUCT_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeEtsStructDeclarationTests, GetEtsStructDeclarationTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Index"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::STRUCT_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeEtsStructDeclarationTests, GetStructDeclarationTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Person"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::STRUCT_DECLARATION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_export_test.cpp b/ets2panda/test/unit/lsp/get_node_export_test.cpp index aa3fa2f63f79a745ed247fd734a5609c65d80530..2b9044e935ed73e042028cb4deedac27a8b04478 100644 --- a/ets2panda/test/unit/lsp/get_node_export_test.cpp +++ b/ets2panda/test/unit/lsp/get_node_export_test.cpp @@ -81,4 +81,46 @@ TEST_F(LspGetNodeExportTests, GetExportSpecifierDeclarationAsNameTest1) std::string extractedText(sourceCode_.substr(res.start, res.length)); ASSERT_NE(extractedText.find(moduleName), std::string::npos); } + +TEST_F(LspGetNodeExportTests, GetReexportStatemenetDeclarationTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "PI"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::REEXPORT_STATEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeExportTests, GetReexportStatemenetDeclarationTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "E"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::REEXPORT_STATEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeExportTests, GetReexportStatemenetDeclarationTest4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "CircleE"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::REEXPORT_STATEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} } // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_expression_test.cpp b/ets2panda/test/unit/lsp/get_node_expression_test.cpp index 1f5d6a18dafc1a3042424cb2631197da50aaca84..9a557db09f2f6045f6653cf168f48d726bbf6e68 100644 --- a/ets2panda/test/unit/lsp/get_node_expression_test.cpp +++ b/ets2panda/test/unit/lsp/get_node_expression_test.cpp @@ -102,4 +102,165 @@ TEST_F(LspGetNodeExpressionTests, GetMemberExpression_NotFound) std::string extractedText(sourceCode_.substr(res.start, res.length)); ASSERT_EQ(extractedText.find(nodeName), std::string::npos); } + +TEST_F(LspGetNodeExpressionTests, GetCallExpression_Identifier) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +function a() { + return "hello"; +} +a(); +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetExpression.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::CALL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeExpressionTests, GetCallExpression_SpuerExpression) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class Parent { + name: string; + + constructor(name: string) { + this.name = name; + } +} + +class Child extends Parent { + age: number; + + constructor(name: string, age: number) { + super(name); + this.age = age; + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetExpression.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "super"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::CALL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeExpressionTests, GetSpuerExpression) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class Parent { + name: string; + + constructor(name: string) { + this.name = name; + } +} + +class Child extends Parent { + age: number; + + constructor(name: string, age: number) { + super(name); + this.age = age; + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetExpression.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "super"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SUPER_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeExpressionTests, GetCallExpression_MemberExpression) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class Foo { + bar() {} +} +let foo = new Foo(); +foo.bar(); +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetExpression.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "bar"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::CALL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeExpressionTests, GetCallExpression_NotFound) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class Parent { + name: string; + + constructor(name: string) { + this.name = name; + } +} + +class Child extends Parent { + age: number; + + constructor(name: string, age: number) { + super(name); + this.age = age; + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetExpression.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "nonexistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::CALL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(nodeName), std::string::npos); + initializer.DestroyContext(contexts); +} } // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_import_test.cpp b/ets2panda/test/unit/lsp/get_node_import_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..478389664491ecba324f09eb76626c8f9f980bc1 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_import_test.cpp @@ -0,0 +1,100 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeImportTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"(import { PI } from "std/math"; +import * as All from "std/math"; +import CommonEventManager from '@ohos.commonEventManager'; +export function add(a: number, b: number): number { + return a + b; +})"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeImportTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeImportTests, GetImportSpecifier) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "PI"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::IMPORT_SPECIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeImportTests, GetImportDefaultSpecifier) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "CommonEventManager"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::IMPORT_DEFAULT_SPECIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeImportTests, GetImportNamespaceSpecifier) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "All"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::IMPORT_NAMESPACE_SPECIFIER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_newclass_instance_test.cpp b/ets2panda/test/unit/lsp/get_node_newclass_instance_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a09a64587bbb3890cf7a7183f680ffbd379a6df --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_newclass_instance_test.cpp @@ -0,0 +1,168 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNewClassInstanceTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +class Point { + x: number; + y: number; + + constructor(x: number = 0, y: number = 0) { + this.x = x; + this.y = y; + } +} + +class Circle { + center: Point; + radius: number; + + constructor(center: Point, radius: number) { + this.center = center; + this.radius = radius; + } + + area(): number { + return 4; + } +} +class Box1 { + value: T; + + constructor(value: T) { + this.value = value; + } + + getValue(): T { + return this.value; + } +} +const p1 = new Point(3, 4); +const c1 = new Circle(p1, 5); +const stringBox = new Box1("hello"); + +class A { + constructor(x: number) {} +} +const a = new A(42); +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeNewClassInstance.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNewClassInstanceTests, GetNewClassInstanceNonExistentTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "NonExistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNewClassInstanceTests, GetNewClassInstanceExpressionTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Point"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNewClassInstanceTests, GetNewClassInstanceExpressionTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Circle"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNewClassInstanceTests, GetNewClassInstanceExpressionTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Box1"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNewClassInstanceTests, GetNewClassInstanceExpressionTest4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "A"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_NEW_CLASS_INSTANCE_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_script_function_test.cpp b/ets2panda/test/unit/lsp/get_node_script_function_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..a6b0e4f641a40f328f994a1ceedda1f2438e2e88 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_script_function_test.cpp @@ -0,0 +1,227 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeScriptFunctionTests : public LSPAPITests {}; + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_Simple_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +function test() {} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionSimple.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "test"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_Arrow_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +function add(a: number, b: number): number { return a + b; } +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionArrow.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "add"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_Async_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +async function fetchData(): Promise { + return "data"; +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionAsync.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "fetchData"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_ClassMethod_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class MyClass { + myMethod(): void { + console.log("method"); + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionClassMethod.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "myMethod"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_Getter_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class MyClass { + get value(): number { + return 42; + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionGetter.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "value"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_Setter_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class MyClass { + private _value: number = 0; + + set value(v: number) { + this._value = v; + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionSetter.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "value"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_StaticMethod_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class MyClass { + static staticMethod(): void { + console.log("static method"); + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionStaticMethod.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "staticMethod"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeScriptFunctionTests, GetScriptFunction_NotFound_TEST) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +class MyClass { + static staticMethod(): void { + console.log("static method"); + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("ScriptFunctionNotFound.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "nonexistent"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SCRIPT_FUNCTION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(nodeName), std::string::npos); + initializer.DestroyContext(contexts); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_spread_element_test.cpp b/ets2panda/test/unit/lsp/get_node_spread_element_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9f6c3429bb72549b8ba057d1ca94daae6938181 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_spread_element_test.cpp @@ -0,0 +1,171 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeSpreadElementTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +const numbers = [1, 2, 3]; +const moreNumbers = [0, ...numbers, 4, 5]; +const part1 = [1, 2]; +const part2 = [3, 4]; +const combined = [...part1, ...part2, 5]; +const original = [10, 20, 30]; +const copy = [...original]; + +class Test { + sum(...numbers: number[]): number { + return 0; + } + args = [1.5, 2.5, 3.0]; + result = this.sum(...this.args); + testNums = [1, 2, 3]; + moreTestNums = [0, ...this.testNums, 4, 5]; +} + +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeSpreadElementTest.ets", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementExistentTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "NonExistentSpreadElement"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "numbers"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "part1"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "part2"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementTest4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "original"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementTest5) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "args"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeSpreadElementTests, GetSpreadElementTest6) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "testNums"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::SPREAD_ELEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_string_literal_test.cpp b/ets2panda/test/unit/lsp/get_node_string_literal_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3e8c14f86cb952455ef56b40b1f971d8756c6081 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_string_literal_test.cpp @@ -0,0 +1,167 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeStringLiteralTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +namespace A { + let a: 'string'; + type Status = "active" | "inactive" | "pending"; +} +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeStringLiteralTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeStringLiteralTests, GetStringLiteralTypeTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "a"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::ETS_STRING_LITERAL_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); +} + +TEST_F(LspGetNodeStringLiteralTests, GetStringLiteralTypeTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Status"; + const std::string value = "active"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::ETS_STRING_LITERAL_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(value), std::string::npos); +} + +TEST_F(LspGetNodeStringLiteralTests, GetStringLiteralTypeTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Status"; + const std::string value = "inactive"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::ETS_STRING_LITERAL_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(value), std::string::npos); +} + +TEST_F(LspGetNodeStringLiteralTests, GetStringLiteralTypeTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Status"; + const std::string value = "pending"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::ETS_STRING_LITERAL_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(value), std::string::npos); +} + +TEST_F(LspGetNodeStringLiteralTests, GetStringLiteralTypeTest4) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +namespace A { + type Ark = "active1"; +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetNodeStringLiteralTest4.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Ark"; + const std::string value = "active1"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::ETS_STRING_LITERAL_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeStringLiteralTests, GetStringLiteralTypeTest5) +{ + Initializer initializer = Initializer(); + const std::string sourceCode = R"( +namespace A { + function expectOne(arg: "1"): void { + let b: '2'; + } +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("GetNodeStringLiteralTest5.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "arg"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::ETS_STRING_LITERAL_TYPE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + initializer.DestroyContext(contexts); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_switch_statement_test.cpp b/ets2panda/test/unit/lsp/get_node_switch_statement_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..56418a19cbcccc7611befd69dbd245492bad552d --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_switch_statement_test.cpp @@ -0,0 +1,101 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeSwitchStatementTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +class A { + getDayType(day: string): string { + switch (day) { + case "Monday": + default: + return "Unknown"; + } + } + processItems(items: string[]): void { + for (let i = 0; i < items.length; i++) { + switch (items[i]) { + case "halt": + return; + default: + } + } + } +} +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeSwitchStatementTest.ts", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeSwitchStatementTests, GetSwitchStatementTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "day"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::SWITCH_STATEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeSwitchStatementTests, GetSwitchStatementTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "items"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::SWITCH_STATEMENT}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_ts_nonnull_expression_test.cpp b/ets2panda/test/unit/lsp/get_node_ts_nonnull_expression_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7941665a12e1f4defe54c6fb9054e325cb2176af --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_ts_nonnull_expression_test.cpp @@ -0,0 +1,140 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeTsNonNullExpressionTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +let x: string | null = null; +x!; +function processString(str: string | null): number { + return str!.length; +} + +function logMessage(msg: string | undefined): void { + let result = msg!.toLowerCase(); +} +interface User { + profile: "name"; +} +function getUserCity(user: User): string { + return user.profile!; +} +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeNonNullExpressionTest.ts", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeTsNonNullExpressionTests, GetNonNullExpressionTest) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "x"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_NON_NULL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTsNonNullExpressionTests, GetNonNullExpressionTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "str"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_NON_NULL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTsNonNullExpressionTests, GetNonNullExpressionTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "msg"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_NON_NULL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTsNonNullExpressionTests, GetNonNullExpressionTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "profile"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_NON_NULL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTsNonNullExpressionTests, GetNonNullExpressionTest4) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "user"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_NON_NULL_EXPRESSION}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_ts_type_param_test.cpp b/ets2panda/test/unit/lsp/get_node_ts_type_param_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..238c612b02b2d843a97258a72c9238f40d718669 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_ts_type_param_test.cpp @@ -0,0 +1,70 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeTypeParamTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"(function identity(arg: T): T { +return arg; +} +const result1 = identity("hello");)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = initializer.CreateContext("GetNodeTsTypeParamTest.ts", ES2PANDA_STATE_CHECKED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeTypeParamTests, GetTSTypeParameter) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "T"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::TS_TYPE_PARAMETER}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_ts_type_reference_test.cpp b/ets2panda/test/unit/lsp/get_node_ts_type_reference_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..cad83d55cbf9269c1923732eed822ded17a9b83d --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_ts_type_reference_test.cpp @@ -0,0 +1,230 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeTSTypeReferenceTests : public LSPAPITests {}; + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST1) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: string; +} +let animal: Animal = { name: "Generic Animal" }; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest1.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Animal"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST2) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +let name: string = "test"; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest2.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "string"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST3) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: string; +} +interface Dog extends Animal { + breed: string; +} +let dog: Dog = { name: "Buddy", breed: "Golden Retriever" }; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest3.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Dog"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST4) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: string; +} +let animals: Animal[] = [{ name: "Cat" }, { name: "Dog" }]; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest4.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Animal"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST5) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: string; +} +function feedAnimal(animal: Animal): void { + console.log("Feeding " + animal.name); +} +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest5.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Animal"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST6) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: T; +} +let animal: Animal = { name: "Generic Animal" }; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest6.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Animal"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST7) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: string; +} +type Pet = Animal; +let pet: Pet = { name: "My Pet" }; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest7.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "Pet"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(nodeName), std::string::npos); + ASSERT_EQ(nodeName, extractedText); + initializer.DestroyContext(contexts); +} + +TEST_F(LspGetNodeTSTypeReferenceTests, GetTSTypeReference_TEST8) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +interface Animal { + name: string; +} +type Pet = Animal; +let pet: Pet = { name: "My Pet" }; +)"; + es2panda_Context *contexts = + initializer.CreateContext("TSTypeReferenceTest8.ets", ES2PANDA_STATE_PARSED, sourceCode.c_str()); + LSPAPI const *lspApi = GetImpl(); + const std::string nodeName = "NotExistingType"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {nodeName, ark::es2panda::ir::AstNodeType::TS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts, nodeInfoPtrs); + std::string extractedText(sourceCode.substr(res.start, res.length)); + ASSERT_EQ(extractedText.find(nodeName), std::string::npos); + initializer.DestroyContext(contexts); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/get_node_type_reference_test.cpp b/ets2panda/test/unit/lsp/get_node_type_reference_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6e44bcbc8eb97343373442af861f30d2948c055 --- /dev/null +++ b/ets2panda/test/unit/lsp/get_node_type_reference_test.cpp @@ -0,0 +1,113 @@ +/** + * Copyright (c) 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. + */ + +#include "ir/astNode.h" +#include "lsp/include/api.h" +#include "lsp_api_test.h" +#include "public/es2panda_lib.h" +#include "public/public.h" +#include "ir/ets/etsReExportDeclaration.h" +#include + +namespace { +using ark::es2panda::lsp::Initializer; + +class LspGetNodeTypeReferenceTests : public LSPAPITests { +protected: + static void SetUpTestSuite() + { + initializer_ = new Initializer(); + sourceCode_ = R"( +class Person { + name: string; + age: number; + + constructor(name: string, age: number) { + this.name = name; + this.age = age; + } +} +let user: Person = new Person("Alice", 30); +class Person1 { + name = "Jonn" +} +function printPerson(p: Person1): void { +} +type UserList = Array; +)"; + GenerateContexts(*initializer_); + } + + static void TearDownTestSuite() + { + initializer_->DestroyContext(contexts_); + delete initializer_; + initializer_ = nullptr; + sourceCode_ = ""; + } + static void GenerateContexts(Initializer &initializer) + { + contexts_ = + initializer.CreateContext("GetNodeTypeReferenceTest.ets", ES2PANDA_STATE_PARSED, sourceCode_.c_str()); + } + // NOLINTBEGIN(fuchsia-statically-constructed-objects, cert-err58-cpp) + static inline es2panda_Context *contexts_ = nullptr; + static inline Initializer *initializer_ = nullptr; + static inline std::string sourceCode_ = ""; + // NOLINTEND(fuchsia-statically-constructed-objects, cert-err58-cpp) +}; + +TEST_F(LspGetNodeTypeReferenceTests, GetTypeReferenceTest1) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Person"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTypeReferenceTests, GetTypeReferenceTest2) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Person1"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} + +TEST_F(LspGetNodeTypeReferenceTests, GetTypeReferenceTest3) +{ + LSPAPI const *lspApi = GetImpl(); + const std::string moduleName = "Array"; + std::vector nodeInfos; + nodeInfos.emplace_back(NodeInfo {moduleName, ark::es2panda::ir::AstNodeType::ETS_TYPE_REFERENCE}); + std::vector nodeInfoPtrs; + nodeInfoPtrs.push_back(&nodeInfos[0]); + + auto res = lspApi->getDefinitionDataFromNode(contexts_, nodeInfoPtrs); + std::string extractedText(sourceCode_.substr(res.start, res.length)); + ASSERT_NE(extractedText.find(moduleName), std::string::npos); +} +} // namespace \ No newline at end of file