• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "lsp_api_test.h"
17 
18 #include <gtest/gtest.h>
19 #include <cstddef>
20 
21 #include "ir/astNode.h"
22 #include "lsp/include/internal_api.h"
23 #include "public/es2panda_lib.h"
24 
25 namespace {
26 
27 using ark::es2panda::lsp::Initializer;
28 
TEST_F(LSPAPITests,GetPrecedingToken1)29 TEST_F(LSPAPITests, GetPrecedingToken1)
30 {
31     using ark::es2panda::ir::AstNode;
32 
33     LSPAPI const *lspApi = GetImpl();
34     Initializer initializer = Initializer();
35     es2panda_Context *context = initializer.CreateContext(
36 
37         "precedingtoken_literal.ets", ES2PANDA_STATE_CHECKED,
38         "let number_literal: number = 1234;\nlet string_literal: string = \"hello\";\nconst str_property = "
39         "\"foo\";\n");
40     ASSERT_EQ(ContextState(context), ES2PANDA_STATE_CHECKED);
41     auto ast = GetAstFromContext<AstNode>(context);
42 
43     size_t const numberLiteralOffset = 31;  // 31: position of '3' in '1234'
44     size_t const stringLiteralOffset = 96;  // 96: position of first 'o' in 'foo'
45     auto numberLiteral = ast->FindChild([](AstNode *node) { return node->IsExpressionStatement(); })
46                              ->AsExpressionStatement()
47                              ->GetExpression()
48                              ->AsAssignmentExpression()
49                              ->Right()
50                              ->AsNumberLiteral();
51     auto result = reinterpret_cast<AstNode *>(lspApi->getPrecedingToken(context, numberLiteralOffset));
52     ASSERT_EQ(result->DumpJSON(), numberLiteral->DumpJSON());
53     ASSERT_EQ(result->Start().index, numberLiteral->Start().index);
54     ASSERT_EQ(result->End().index, numberLiteral->End().index);
55     auto stringLiteral = ast->FindChild(
56         [](AstNode *node) { return node->IsStringLiteral() && node->AsStringLiteral()->ToString() == "foo"; });
57     result = reinterpret_cast<AstNode *>(lspApi->getPrecedingToken(context, stringLiteralOffset));
58     ASSERT_EQ(result->DumpJSON(), stringLiteral->DumpJSON());
59     ASSERT_EQ(result->Start().index, stringLiteral->Start().index);
60     ASSERT_EQ(result->End().index, stringLiteral->End().index);
61     initializer.DestroyContext(context);
62 }
63 
TEST_F(LSPAPITests,GetPrecedingToken2)64 TEST_F(LSPAPITests, GetPrecedingToken2)
65 {
66     using ark::es2panda::ir::AstNode;
67 
68     LSPAPI const *lspApi = GetImpl();
69     Initializer initializer = Initializer();
70     es2panda_Context *context = initializer.CreateContext(
71         "precedingtoken_function.ets", ES2PANDA_STATE_CHECKED,
72         "    \n\n\n\nfunction f() {\n    le\n    let a = 123;\n}\n\n\n\nconst s = \"hello\";\n\n\n");
73     auto ast = GetAstFromContext<AstNode>(context);
74 
75     size_t const startOfFile = 0;            // 0: position of start of file
76     size_t const secondSpaceBeforeLe = 25;   // 25: position of second space before 'le'
77     size_t const endOfLe = 29;               // 29: position of the end of 'le' identifier
78     size_t const secondSpaceBeforeLet = 32;  // 32: position of second space before 'let'
79     size_t const startOfLine10 = 50;         // 50: position of start of line 10
80     size_t const startOfLine14 = 72;         // 72: position of start of line 14
81     ASSERT_EQ(lspApi->getPrecedingToken(context, startOfFile), nullptr);
82     ASSERT_EQ(lspApi->getPrecedingToken(context, secondSpaceBeforeLe), nullptr);
83     auto leIdentifier =
84         ast->FindChild([](AstNode *node) { return node->IsIdentifier() && node->AsIdentifier()->Name() == "le"; });
85     auto result = reinterpret_cast<AstNode *>(lspApi->getPrecedingToken(context, endOfLe));
86     ASSERT_EQ(result->DumpJSON(), leIdentifier->DumpJSON());
87     ASSERT_EQ(result->Start().index, leIdentifier->Start().index);
88     ASSERT_EQ(result->End().index, leIdentifier->End().index);
89     result = reinterpret_cast<AstNode *>(lspApi->getPrecedingToken(context, secondSpaceBeforeLet));
90     ASSERT_EQ(result->DumpJSON(), leIdentifier->DumpJSON());
91     ASSERT_EQ(result->Start().index, leIdentifier->Start().index);
92     ASSERT_EQ(result->End().index, leIdentifier->End().index);
93     auto numberLiteral = ast->FindChild(
94         [](AstNode *node) { return node->IsNumberLiteral() && node->AsNumberLiteral()->Str() == "123"; });
95     result = reinterpret_cast<AstNode *>(lspApi->getPrecedingToken(context, startOfLine10));
96     ASSERT_EQ(result->DumpJSON(), numberLiteral->DumpJSON());
97     ASSERT_EQ(result->Start().index, numberLiteral->Start().index);
98     ASSERT_EQ(result->End().index, numberLiteral->End().index);
99     auto stringLiteral = ast->FindChild([](AstNode *node) { return node->IsClassProperty(); })
100                              ->AsClassProperty()
101                              ->Value()
102                              ->AsStringLiteral();
103     result = reinterpret_cast<AstNode *>(lspApi->getPrecedingToken(context, startOfLine14));
104     ASSERT_EQ(result->DumpJSON(), stringLiteral->DumpJSON());
105     ASSERT_EQ(result->Start().index, stringLiteral->Start().index);
106     ASSERT_EQ(result->End().index, stringLiteral->End().index);
107     initializer.DestroyContext(context);
108 }
109 
110 }  // namespace
111