update test file
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
|
||||
project(test_ast)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
message(STATUS "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
|
||||
message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
|
||||
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
if (DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
message(STATUS ">>> CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
if (DEFINED VCPKG_TARGET_TRIPLET)
|
||||
message(STATUS ">>> VCPKG_TARGET_TRIPLET: ${VCPKG_TARGET_TRIPLET}")
|
||||
endif()
|
||||
|
||||
# 设置默认构建类型
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"Release"
|
||||
CACHE STRING "Build type" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
|
||||
"MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
# MinGW/MSYS2 静态链接
|
||||
if(MINGW)
|
||||
add_link_options(-static -static-libgcc -static-libstdc++)
|
||||
elseif(UNIX AND NOT APPLE) # Linux 静态链接
|
||||
add_link_options(-static-libgcc -static-libstdc++)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib" ".dll.a")
|
||||
else()
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so")
|
||||
endif()
|
||||
|
||||
find_package(glaze CONFIG REQUIRED)
|
||||
find_package(spdlog CONFIG REQUIRED)
|
||||
find_package(fmt CONFIG REQUIRED)
|
||||
find_package(Taskflow REQUIRED)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
if(DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
find_package(unofficial-tree-sitter CONFIG REQUIRED)
|
||||
set(TREESITTER_TARGET unofficial::tree-sitter::tree-sitter)
|
||||
else()
|
||||
# find_package(PkgConfig REQUIRED)
|
||||
# pkg_check_modules(TREESITTER tree-sitter)
|
||||
find_library(TREESITTER_LIBRARY tree-sitter) # use ${TREESITTER_LIBRARY}
|
||||
set(TREESITTER_TARGET ${TREESITTER_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET spdlog::spdlog_header_only)
|
||||
message(WARNING "spdlog header-only target not found, using shared library")
|
||||
endif()
|
||||
if(NOT TARGET fmt::fmt-header-only)
|
||||
message(WARNING "fmt header-only target not found, using shared library")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
set(SOURCES
|
||||
./test.cpp
|
||||
./debug_printer.cpp
|
||||
../../src/language/ast/deserializer.cpp
|
||||
../../src/language/ast/detail.cpp
|
||||
../../src/language/ast/tree_sitter_utils.cpp
|
||||
../../src/utils/string.cpp
|
||||
../../src/tree-sitter/parser.c)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE src)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE SPDLOG_HEADER_ONLY
|
||||
FMT_HEADER_ONLY)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
glaze::glaze
|
||||
Taskflow::Taskflow
|
||||
spdlog::spdlog_header_only
|
||||
fmt::fmt-header-only
|
||||
${TREESITTER_TARGET} # 使用变量,避免条件判断
|
||||
$<$<PLATFORM_ID:Linux>:Threads::Threads> # 使用生成器表达式
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall -Wextra -Wpedantic
|
||||
$<$<CONFIG:Debug>:-g -O0>
|
||||
$<$<CONFIG:Release>:-O3>
|
||||
)
|
||||
endif()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "../../src/language/ast/types.hpp"
|
||||
#include "../../src/language/ast/deserializer.hpp"
|
||||
|
||||
namespace lsp::language::ast
|
||||
{
|
||||
class DebugPrinter : public ASTVisitor
|
||||
{
|
||||
public:
|
||||
explicit DebugPrinter(std::ostream& os = std::cout, int indent_size = 2) :
|
||||
os_(os), indent_size_(indent_size), current_indent_(0) {}
|
||||
|
||||
void Print(const ASTNode* node);
|
||||
void PrintStatements(const std::vector<StatementPtr>& statements);
|
||||
void PrintParseResult(const ParseResult& result);
|
||||
|
||||
void VisitUnitDefinition(UnitDefinition& node) override;
|
||||
void VisitClassDefinition(ClassDefinition& node) override;
|
||||
void VisitClassMember(ClassMember& node) override;
|
||||
void VisitMethodDeclaration(MethodDeclaration& node) override;
|
||||
void VisitPropertyDeclaration(PropertyDeclaration& node) override;
|
||||
void VisitExternalMethodDefinition(ExternalMethodDefinition& node) override;
|
||||
void VisitIdentifier(Identifier& node) override;
|
||||
void VisitLiteral(Literal& node) override;
|
||||
void VisitBinaryExpression(BinaryExpression& node) override;
|
||||
void VisitComparisonExpression(ComparisonExpression& node) override;
|
||||
void VisitUnaryExpression(UnaryExpression& node) override;
|
||||
void VisitTernaryExpression(TernaryExpression& node) override;
|
||||
void VisitCallExpression(CallExpression& node) override;
|
||||
void VisitAttributeExpression(AttributeExpression& node) override;
|
||||
void VisitSubscriptExpression(SubscriptExpression& node) override;
|
||||
void VisitArrayExpression(ArrayExpression& node) override;
|
||||
void VisitAnonymousFunctionExpression(AnonymousFunctionExpression& node) override;
|
||||
void VisitPrefixIncrementExpression(PrefixIncrementExpression& node) override;
|
||||
void VisitPrefixDecrementExpression(PrefixDecrementExpression& node) override;
|
||||
void VisitPostfixIncrementExpression(PostfixIncrementExpression& node) override;
|
||||
void VisitPostfixDecrementExpression(PostfixDecrementExpression& node) override;
|
||||
void VisitFunctionPointerExpression(FunctionPointerExpression& node) override;
|
||||
void VisitAssignmentExpression(AssignmentExpression& node) override;
|
||||
void VisitExpressionStatement(ExpressionStatement& node) override;
|
||||
void VisitVarStatement(VarStatement& node) override;
|
||||
void VisitStaticStatement(StaticStatement& node) override;
|
||||
void VisitGlobalStatement(GlobalStatement& node) override;
|
||||
void VisitConstStatement(ConstStatement& node) override;
|
||||
void VisitAssignmentStatement(AssignmentStatement& node) override;
|
||||
void VisitBlockStatement(BlockStatement& node) override;
|
||||
void VisitIfStatement(IfStatement& node) override;
|
||||
void VisitForInStatement(ForInStatement& node) override;
|
||||
void VisitForToStatement(ForToStatement& node) override;
|
||||
void VisitWhileStatement(WhileStatement& node) override;
|
||||
void VisitRepeatStatement(RepeatStatement& node) override;
|
||||
void VisitCaseStatement(CaseStatement& node) override;
|
||||
void VisitTryStatement(TryStatement& node) override;
|
||||
void VisitBreakStatement(BreakStatement& node) override;
|
||||
void VisitContinueStatement(ContinueStatement& node) override;
|
||||
void VisitReturnStatement(ReturnStatement& node) override;
|
||||
void VisitUsesStatement(UsesStatement& node) override;
|
||||
void VisitFunctionDefinition(FunctionDefinition& node) override;
|
||||
void VisitFunctionDeclaration(FunctionDeclaration& node) override;
|
||||
void VisitVarDeclaration(VarDeclaration& node) override;
|
||||
void VisitStaticDeclaration(StaticDeclaration& node) override;
|
||||
void VisitGlobalDeclaration(GlobalDeclaration& node) override;
|
||||
void VisitFieldDeclaration(FieldDeclaration& node) override;
|
||||
void VisitUnpackPattern(UnpackPattern& node) override;
|
||||
void VisitTSSQLExpression(TSSQLExpression& node) override;
|
||||
|
||||
private:
|
||||
std::ostream& os_;
|
||||
int indent_size_;
|
||||
int current_indent_;
|
||||
|
||||
void IncreaseIndent() { current_indent_ += indent_size_; }
|
||||
void DecreaseIndent() { current_indent_ -= indent_size_; }
|
||||
void PrintIndent();
|
||||
std::string GetIndent() const;
|
||||
|
||||
void PrintLocation(const Location& loc);
|
||||
void PrintNodeHeader(const std::string& type_name, const Location& loc);
|
||||
void PrintExpression(const Expression* expr);
|
||||
void PrintSignature(const Signature& sig);
|
||||
void PrintParameter(const Parameter& param);
|
||||
void PrintLeftHandSide(const LeftHandSide& lhs);
|
||||
void PrintOperator(BinaryOperator op);
|
||||
void PrintOperator(UnaryOperator op);
|
||||
void PrintOperator(AssignmentOperator op);
|
||||
void PrintLiteralKind(LiteralKind kind);
|
||||
void PrintAccessModifier(AccessModifier modifier);
|
||||
void PrintMethodModifier(MethodModifier modifier);
|
||||
void PrintReferenceModifier(ReferenceModifier modifier);
|
||||
void PrintError(const ParseError& error);
|
||||
};
|
||||
|
||||
std::string DebugString(const ASTNode* node);
|
||||
std::string DebugString(const ParseResult& result);
|
||||
void DebugPrint(const ASTNode* node);
|
||||
void DebugPrint(const ParseResult& result);
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include <tree_sitter/api.h>
|
||||
}
|
||||
|
||||
extern "C" const TSLanguage* tree_sitter_tsf(void);
|
||||
|
||||
#include "../../src/language/ast/deserializer.hpp"
|
||||
#include "./debug_printer.hpp"
|
||||
|
||||
using namespace lsp::language::ast;
|
||||
|
||||
// ==================== 文件读取 ====================
|
||||
|
||||
std::string ReadFile(const std::string& filepath)
|
||||
{
|
||||
std::ifstream file(filepath);
|
||||
if (!file.is_open())
|
||||
{
|
||||
throw std::runtime_error("Cannot open file: " + filepath);
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << file.rdbuf();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// ==================== Tree-Sitter 解析 ====================
|
||||
|
||||
class TreeSitterParser
|
||||
{
|
||||
public:
|
||||
TreeSitterParser()
|
||||
{
|
||||
parser_ = ts_parser_new();
|
||||
if (!parser_)
|
||||
{
|
||||
throw std::runtime_error("Failed to create parser");
|
||||
}
|
||||
|
||||
// 设置语言
|
||||
if (!ts_parser_set_language(parser_, tree_sitter_tsf()))
|
||||
{
|
||||
ts_parser_delete(parser_);
|
||||
throw std::runtime_error("Failed to set language");
|
||||
}
|
||||
}
|
||||
|
||||
~TreeSitterParser()
|
||||
{
|
||||
if (tree_)
|
||||
{
|
||||
ts_tree_delete(tree_);
|
||||
}
|
||||
if (parser_)
|
||||
{
|
||||
ts_parser_delete(parser_);
|
||||
}
|
||||
}
|
||||
|
||||
TSTree* Parse(const std::string& source)
|
||||
{
|
||||
if (tree_)
|
||||
{
|
||||
ts_tree_delete(tree_);
|
||||
tree_ = nullptr;
|
||||
}
|
||||
|
||||
tree_ = ts_parser_parse_string(
|
||||
parser_,
|
||||
nullptr,
|
||||
source.c_str(),
|
||||
source.length());
|
||||
|
||||
if (!tree_)
|
||||
{
|
||||
throw std::runtime_error("Failed to parse source");
|
||||
}
|
||||
|
||||
return tree_;
|
||||
}
|
||||
|
||||
TSNode GetRootNode()
|
||||
{
|
||||
if (!tree_)
|
||||
{
|
||||
throw std::runtime_error("No tree available");
|
||||
}
|
||||
return ts_tree_root_node(tree_);
|
||||
}
|
||||
|
||||
private:
|
||||
TSParser* parser_ = nullptr;
|
||||
TSTree* tree_ = nullptr;
|
||||
};
|
||||
|
||||
// ==================== 主程序 ====================
|
||||
|
||||
void PrintUsage(const char* program_name)
|
||||
{
|
||||
std::cout << "Usage: " << program_name << " <file_path> [options]\n";
|
||||
std::cout << "\nOptions:\n";
|
||||
std::cout << " -v, --verbose Print verbose output\n";
|
||||
std::cout << " -i, --incremental Test incremental parsing\n";
|
||||
std::cout << " -h, --help Show this help message\n";
|
||||
std::cout << "\nExample:\n";
|
||||
std::cout << " " << program_name << " test.tsf\n";
|
||||
std::cout << " " << program_name << " test.tsf -v -s\n";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string filepath;
|
||||
bool verbose = false;
|
||||
bool test_incremental = false;
|
||||
|
||||
// 解析命令行参数
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
if (arg == "-h" || arg == "--help")
|
||||
{
|
||||
PrintUsage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
else if (arg == "-v" || arg == "--verbose")
|
||||
{
|
||||
verbose = true;
|
||||
}
|
||||
else if (arg == "-i" || arg == "--incremental")
|
||||
{
|
||||
test_incremental = true;
|
||||
}
|
||||
else if (filepath.empty())
|
||||
{
|
||||
filepath = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown argument: " << arg << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 读取文件
|
||||
std::cout << "Reading file: " << filepath << "\n";
|
||||
std::string source = ReadFile(filepath);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
std::cout << "File size: " << source.length() << " bytes\n";
|
||||
std::cout << "----------------------------------------\n";
|
||||
std::cout << source << "\n";
|
||||
std::cout << "----------------------------------------\n\n";
|
||||
}
|
||||
|
||||
// 创建 Tree-Sitter 解析器
|
||||
std::cout << "Parsing with Tree-Sitter...\n";
|
||||
TreeSitterParser ts_parser;
|
||||
TSTree* tree = ts_parser.Parse(source);
|
||||
TSNode root = ts_parser.GetRootNode();
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
std::cout << "Root node type: " << ts_node_type(root) << "\n";
|
||||
std::cout << "Root node child count: " << ts_node_child_count(root) << "\n\n";
|
||||
}
|
||||
|
||||
// 创建 AST 反序列化器
|
||||
Deserializer deserializer;
|
||||
|
||||
ParseResult result;
|
||||
|
||||
if (test_incremental)
|
||||
{
|
||||
std::cout << "Using incremental parsing...\n";
|
||||
auto inc_result = deserializer.ParseIncremental(root, source);
|
||||
result = std::move(inc_result.result);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Using full parsing...\n";
|
||||
result = deserializer.Parse(root, source);
|
||||
}
|
||||
|
||||
// 打印解析结果
|
||||
std::cout << "\n";
|
||||
DebugPrint(result);
|
||||
|
||||
// 打印摘要
|
||||
std::cout << "\n========================================\n";
|
||||
std::cout << "Summary:\n";
|
||||
std::cout << " File: " << filepath << "\n";
|
||||
std::cout << " Size: " << source.length() << " bytes\n";
|
||||
std::cout << " AST Nodes: " << result.statements.size() << "\n";
|
||||
std::cout << " Errors: " << result.errors.size() << "\n";
|
||||
|
||||
if (result.HasErrors())
|
||||
{
|
||||
std::cout << " Status: FAILED (with errors)\n";
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " Status: SUCCESS\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << "Error: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
var d, e: boolean;
|
||||
global c, d;
|
||||
static e, f;
|
||||
const a: boolean = false;
|
||||
|
||||
var a, b: boolean := true;
|
||||
static d := "abc";
|
||||
global c := 123456;
|
||||
// e := f1();
|
||||
|
||||
// function f1(a: string; b: boolean = true): integer;
|
||||
// begin
|
||||
// end;
|
||||
|
||||
// function f2(a, b, c);overload;
|
||||
// begin
|
||||
// end;
|
||||
|
||||
// var d := 1;
|
||||
// c := false;
|
||||
// f := fa();
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "../src/protocol/protocol.hpp"
|
||||
#include "../src/protocol/transform/facade.hpp"
|
||||
#include "../../src/protocol/protocol.hpp"
|
||||
#include "../../src/protocol/transform/facade.hpp"
|
||||
|
||||
using namespace lsp::protocol;
|
||||
using namespace lsp;
|
||||
@@ -12,7 +12,8 @@ void print_json(const string& name, const T& obj)
|
||||
if (auto result = glz::write_json(obj); result)
|
||||
{
|
||||
std::cout << name << " = " << *result << std::endl;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error: " << result.error() << "\n";
|
||||
}
|
||||
@@ -31,7 +32,7 @@ void test_basic_conversion()
|
||||
LSPAny any = transform::LSPAny(msg);
|
||||
std::string json;
|
||||
auto ce = glz::write_json(any, json);
|
||||
if(ce)
|
||||
if (ce)
|
||||
std::cout << "Error" << std::endl;
|
||||
std::cout << "Message as JSON: " << json << std::endl;
|
||||
|
||||
@@ -39,10 +40,10 @@ void test_basic_conversion()
|
||||
RequestMessage restored = transform::As<RequestMessage>(any);
|
||||
std::cout << "Restored method: " << restored.method << std::endl;
|
||||
std::cout << "id = ";
|
||||
std::visit([](const auto& value)
|
||||
{
|
||||
std::visit([](const auto& value) {
|
||||
std::cout << value;
|
||||
}, restored.id);
|
||||
},
|
||||
restored.id);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
@@ -51,9 +52,9 @@ void test_vector_conversion()
|
||||
std::cout << "\n=== Testing Vector Conversion ===" << std::endl;
|
||||
|
||||
std::vector<Position> positions = {
|
||||
{10, 5},
|
||||
{20, 15},
|
||||
{30, 25}
|
||||
{ 10, 5 },
|
||||
{ 20, 15 },
|
||||
{ 30, 25 }
|
||||
};
|
||||
|
||||
// Vector -> LSPAny
|
||||
@@ -78,17 +79,17 @@ void test_json_string()
|
||||
std::cout << "jsonrpc = " << request.jsonrpc << std::endl;
|
||||
std::cout << "method = " << request.method << std::endl;
|
||||
std::cout << "id = ";
|
||||
std::visit([](const auto& value)
|
||||
{
|
||||
std::visit([](const auto& value) {
|
||||
std::cout << value;
|
||||
}, request.id);
|
||||
},
|
||||
request.id);
|
||||
std::cout << std::endl;
|
||||
|
||||
auto result = glz::write_json(request.params);
|
||||
std::cout << *result << std::endl;
|
||||
InitializeParams params;
|
||||
// std::string buffer = R"({"workDoneToken":123,"processId":"id","clientInfo":{"name":"VSCode","version":"1.0.0"},"rootPath":"456","initializationOptions":"options","trace":"messages"})";
|
||||
auto r2= glz::read_json(params, *result);
|
||||
auto r2 = glz::read_json(params, *result);
|
||||
if (params.processId.has_value())
|
||||
std::cout << "processId = " << params.processId.value() << "\n";
|
||||
else
|
||||
@@ -100,10 +101,9 @@ void test_json_string()
|
||||
void test_basic_types()
|
||||
{
|
||||
std::cout << "\n=== Test basic_types.hpp ===" << std::endl;
|
||||
Range range =
|
||||
{
|
||||
.start = {1, 3},
|
||||
.end = {2, 4}
|
||||
Range range = {
|
||||
.start = { 1, 3 },
|
||||
.end = { 2, 4 }
|
||||
};
|
||||
|
||||
DocumentFilter df = {
|
||||
@@ -113,29 +113,25 @@ void test_basic_types()
|
||||
};
|
||||
|
||||
AnnotatedTextEdit ate;
|
||||
ate.range = {.start = {1, 3}, .end = {2, 4}};
|
||||
ate.range = { .start = { 1, 3 }, .end = { 2, 4 } };
|
||||
ate.newText = "text_edit";
|
||||
ate.annotationId = "id";
|
||||
|
||||
Location location =
|
||||
{
|
||||
Location location = {
|
||||
.uri = "location_uri",
|
||||
.range = {.start = {1, 3}, .end = {2, 4}}
|
||||
.range = { .start = { 1, 3 }, .end = { 2, 4 } }
|
||||
};
|
||||
|
||||
Command command1 =
|
||||
{
|
||||
Command command1 = {
|
||||
.title = "command_title",
|
||||
.command = "command_command",
|
||||
};
|
||||
Command command2 =
|
||||
{
|
||||
Command command2 = {
|
||||
.title = "command_title",
|
||||
.command = "command_command",
|
||||
.arguments = "any_string"
|
||||
};
|
||||
Command command3 =
|
||||
{
|
||||
Command command3 = {
|
||||
.title = "command_title",
|
||||
.command = "command_command",
|
||||
.arguments = 123
|
||||
@@ -149,23 +145,21 @@ void test_basic_types()
|
||||
};
|
||||
LSPAny array_val = array;
|
||||
LSPObject object = {
|
||||
{"name", string("test object")},
|
||||
{"count", 42.0}, // decimal
|
||||
{"active", boolean(true)},
|
||||
{"data", array_val},
|
||||
{"metadata", nullptr}
|
||||
{ "name", string("test object") },
|
||||
{ "count", 42.0 }, // decimal
|
||||
{ "active", boolean(true) },
|
||||
{ "data", array_val },
|
||||
{ "metadata", nullptr }
|
||||
};
|
||||
Command command4 =
|
||||
{
|
||||
Command command4 = {
|
||||
.title = "command_title",
|
||||
.command = "command_command",
|
||||
.arguments = object
|
||||
};
|
||||
|
||||
MarkdownClientCapabilities mkcp =
|
||||
{
|
||||
MarkdownClientCapabilities mkcp = {
|
||||
.parser = "parse",
|
||||
.allowedTags = std::vector<string>{"h1", "h2", "p", "code", "pre"}
|
||||
.allowedTags = std::vector<string>{ "h1", "h2", "p", "code", "pre" }
|
||||
};
|
||||
std::cout << "Test....basic_types" << std::endl;
|
||||
print_json("Range", range);
|
||||
@@ -186,7 +180,7 @@ void test_capabilities()
|
||||
InitializeParams ip;
|
||||
ip.workDoneToken = 123;
|
||||
ip.processId = std::nullopt;
|
||||
ip.clientInfo = InitializeParams::ClientInfo{"VSCode", "1.0.0"};
|
||||
ip.clientInfo = InitializeParams::ClientInfo{ "VSCode", "1.0.0" };
|
||||
// ip.rootPath = "456";
|
||||
ip.initializationOptions = "options";
|
||||
ip.trace = TraceValueLiterals::Messages;
|
||||
@@ -238,21 +232,25 @@ void test_RequestMessage_serialize()
|
||||
RequestMessage request;
|
||||
auto error = glz::read_json(request, json);
|
||||
|
||||
if (error) {
|
||||
if (error)
|
||||
{
|
||||
std::cerr << "Failed to parse JSON: " << glz::format_error(error, json) << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "jsonrpc: " << request.jsonrpc << std::endl;
|
||||
std::cout << "method: " << request.method << std::endl;
|
||||
std::visit([](const auto& id)
|
||||
{
|
||||
std::visit([](const auto& id) {
|
||||
using T = std::decay_t<decltype(id)>;
|
||||
if constexpr (std::is_same_v<T, lsp::protocol::string>) {
|
||||
if constexpr (std::is_same_v<T, lsp::protocol::string>)
|
||||
{
|
||||
std::cout << "ID (string): " << id << std::endl;
|
||||
} else if constexpr (std::is_same_v<T, lsp::protocol::integer>) {
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, lsp::protocol::integer>)
|
||||
{
|
||||
std::cout << "ID (integer): " << id << std::endl;
|
||||
}
|
||||
}, request.id);
|
||||
},
|
||||
request.id);
|
||||
|
||||
auto completionParams = transform::As<CompletionParams>(request.params.value());
|
||||
std::cout << "URI: " << completionParams.textDocument.uri << std::endl;
|
||||
@@ -277,7 +275,7 @@ void test_message()
|
||||
result.serverInfo.version = "1.0.0";
|
||||
TextDocumentSyncOptions opts;
|
||||
opts.openClose = true;
|
||||
opts.change = TextDocumentSyncKind::kIncremental;
|
||||
opts.change = TextDocumentSyncKind::Incremental;
|
||||
result.capabilities.textDocumentSync = opts;
|
||||
|
||||
CompletionParams comparams;
|
||||
@@ -285,7 +283,7 @@ void test_message()
|
||||
comparams.position.character = 12;
|
||||
comparams.position.line = 22;
|
||||
comparams.context = CompletionContext{
|
||||
.triggerKind = CompletionTriggerKind::kInvoked,
|
||||
.triggerKind = CompletionTriggerKind::Invoked,
|
||||
.triggerCharacter = std::nullopt
|
||||
};
|
||||
RequestMessage rm;
|
||||
@@ -24,173 +24,227 @@ using LSPAnyVariant = std::variant<
|
||||
string,
|
||||
decimal, // 放在前面,优先匹配数字
|
||||
boolean,
|
||||
std::nullptr_t
|
||||
>;
|
||||
std::nullptr_t>;
|
||||
|
||||
struct LSPAny {
|
||||
struct LSPAny
|
||||
{
|
||||
LSPAnyVariant value;
|
||||
|
||||
// 默认构造函数
|
||||
LSPAny() : value(nullptr) {}
|
||||
LSPAny() :
|
||||
value(nullptr) {}
|
||||
|
||||
// 拷贝和移动构造函数
|
||||
LSPAny(const LSPAny& other) : value(other.value) {}
|
||||
LSPAny(LSPAny&& other) noexcept : value(std::move(other.value)) {}
|
||||
LSPAny(const LSPAny& other) :
|
||||
value(other.value) {}
|
||||
LSPAny(LSPAny&& other) noexcept :
|
||||
value(std::move(other.value)) {}
|
||||
|
||||
// 针对每种支持的类型的构造函数
|
||||
LSPAny(const std::map<string, LSPAny>& val) : value(val) {}
|
||||
LSPAny(std::map<string, LSPAny>&& val) : value(std::move(val)) {}
|
||||
LSPAny(const std::map<string, LSPAny>& val) :
|
||||
value(val) {}
|
||||
LSPAny(std::map<string, LSPAny>&& val) :
|
||||
value(std::move(val)) {}
|
||||
|
||||
LSPAny(const std::vector<LSPAny>& val) : value(val) {}
|
||||
LSPAny(std::vector<LSPAny>&& val) : value(std::move(val)) {}
|
||||
LSPAny(const std::vector<LSPAny>& val) :
|
||||
value(val) {}
|
||||
LSPAny(std::vector<LSPAny>&& val) :
|
||||
value(std::move(val)) {}
|
||||
|
||||
LSPAny(const string& val) : value(val) {}
|
||||
LSPAny(string&& val) : value(std::move(val)) {}
|
||||
LSPAny(const char* val) : value(string(val)) {}
|
||||
LSPAny(const string& val) :
|
||||
value(val) {}
|
||||
LSPAny(string&& val) :
|
||||
value(std::move(val)) {}
|
||||
LSPAny(const char* val) :
|
||||
value(string(val)) {}
|
||||
|
||||
// 所有数字类型都转换为 decimal
|
||||
LSPAny(int val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(long val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(long long val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(unsigned int val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(unsigned long val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(unsigned long long val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(float val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(double val) : value(val) {}
|
||||
LSPAny(long double val) : value(static_cast<decimal>(val)) {}
|
||||
LSPAny(int val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(long val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(long long val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(unsigned int val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(unsigned long val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(unsigned long long val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(float val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
LSPAny(double val) :
|
||||
value(val) {}
|
||||
LSPAny(long double val) :
|
||||
value(static_cast<decimal>(val)) {}
|
||||
|
||||
LSPAny(boolean val) : value(val) {}
|
||||
LSPAny(std::nullptr_t) : value(nullptr) {}
|
||||
LSPAny(boolean val) :
|
||||
value(val) {}
|
||||
LSPAny(std::nullptr_t) :
|
||||
value(nullptr) {}
|
||||
|
||||
// 赋值操作符
|
||||
LSPAny& operator=(const LSPAny& other) {
|
||||
LSPAny& operator=(const LSPAny& other)
|
||||
{
|
||||
value = other.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(LSPAny&& other) noexcept {
|
||||
LSPAny& operator=(LSPAny&& other) noexcept
|
||||
{
|
||||
value = std::move(other.value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 针对每种支持的类型的赋值操作符
|
||||
LSPAny& operator=(const std::map<string, LSPAny>& val) {
|
||||
LSPAny& operator=(const std::map<string, LSPAny>& val)
|
||||
{
|
||||
value = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(std::map<string, LSPAny>&& val) {
|
||||
LSPAny& operator=(std::map<string, LSPAny>&& val)
|
||||
{
|
||||
value = std::move(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(const std::vector<LSPAny>& val) {
|
||||
LSPAny& operator=(const std::vector<LSPAny>& val)
|
||||
{
|
||||
value = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(std::vector<LSPAny>&& val) {
|
||||
LSPAny& operator=(std::vector<LSPAny>&& val)
|
||||
{
|
||||
value = std::move(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(const string& val) {
|
||||
LSPAny& operator=(const string& val)
|
||||
{
|
||||
value = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(string&& val) {
|
||||
LSPAny& operator=(string&& val)
|
||||
{
|
||||
value = std::move(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(const char* val) {
|
||||
LSPAny& operator=(const char* val)
|
||||
{
|
||||
value = string(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 所有数字类型都转换为 decimal
|
||||
LSPAny& operator=(int val) {
|
||||
LSPAny& operator=(int val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(long val) {
|
||||
LSPAny& operator=(long val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(long long val) {
|
||||
LSPAny& operator=(long long val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(unsigned int val) {
|
||||
LSPAny& operator=(unsigned int val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(unsigned long val) {
|
||||
LSPAny& operator=(unsigned long val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(unsigned long long val) {
|
||||
LSPAny& operator=(unsigned long long val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(float val) {
|
||||
LSPAny& operator=(float val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(double val) {
|
||||
LSPAny& operator=(double val)
|
||||
{
|
||||
value = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(long double val) {
|
||||
LSPAny& operator=(long double val)
|
||||
{
|
||||
value = static_cast<decimal>(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(boolean val) {
|
||||
LSPAny& operator=(boolean val)
|
||||
{
|
||||
value = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LSPAny& operator=(std::nullptr_t) {
|
||||
LSPAny& operator=(std::nullptr_t)
|
||||
{
|
||||
value = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 类型检查辅助函数
|
||||
template<typename T>
|
||||
bool is() const { return std::holds_alternative<T>(value); }
|
||||
bool is() const
|
||||
{
|
||||
return std::holds_alternative<T>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& get() { return std::get<T>(value); }
|
||||
T& get()
|
||||
{
|
||||
return std::get<T>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& get() const { return std::get<T>(value); }
|
||||
const T& get() const
|
||||
{
|
||||
return std::get<T>(value);
|
||||
}
|
||||
|
||||
// 访问操作符
|
||||
template<typename Visitor>
|
||||
auto visit(Visitor&& visitor) const {
|
||||
auto visit(Visitor&& visitor) const
|
||||
{
|
||||
return std::visit(std::forward<Visitor>(visitor), value);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
auto visit(Visitor&& visitor) {
|
||||
auto visit(Visitor&& visitor)
|
||||
{
|
||||
return std::visit(std::forward<Visitor>(visitor), value);
|
||||
}
|
||||
};
|
||||
|
||||
// glaze 自动支持 std::variant,无需额外配置
|
||||
namespace glz {
|
||||
template <>
|
||||
struct meta<LSPAny> {
|
||||
namespace glz
|
||||
{
|
||||
template<>
|
||||
struct meta<LSPAny>
|
||||
{
|
||||
using T = LSPAny;
|
||||
static constexpr auto value = &T::value;
|
||||
};
|
||||
@@ -199,68 +253,83 @@ namespace glz {
|
||||
// ===== 简单清晰的转换模板 =====
|
||||
|
||||
// 转换工具类
|
||||
struct LSPConvert {
|
||||
struct LSPConvert
|
||||
{
|
||||
// === 基本类型的转换(优先级最高) ===
|
||||
|
||||
// boolean
|
||||
static LSPAny ToLSPAny(boolean value) {
|
||||
static LSPAny ToLSPAny(boolean value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
// 整数类型
|
||||
static LSPAny ToLSPAny(int value) {
|
||||
static LSPAny ToLSPAny(int value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(long value) {
|
||||
static LSPAny ToLSPAny(long value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(long long value) {
|
||||
static LSPAny ToLSPAny(long long value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(unsigned int value) {
|
||||
static LSPAny ToLSPAny(unsigned int value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(unsigned long value) {
|
||||
static LSPAny ToLSPAny(unsigned long value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(unsigned long long value) {
|
||||
static LSPAny ToLSPAny(unsigned long long value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
// 浮点类型
|
||||
static LSPAny ToLSPAny(float value) {
|
||||
static LSPAny ToLSPAny(float value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(double value) {
|
||||
static LSPAny ToLSPAny(double value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(long double value) {
|
||||
static LSPAny ToLSPAny(long double value)
|
||||
{
|
||||
return LSPAny(value);
|
||||
}
|
||||
|
||||
// string
|
||||
static LSPAny ToLSPAny(const string& str) {
|
||||
static LSPAny ToLSPAny(const string& str)
|
||||
{
|
||||
return LSPAny(str);
|
||||
}
|
||||
|
||||
static LSPAny ToLSPAny(const char* str) {
|
||||
static LSPAny ToLSPAny(const char* str)
|
||||
{
|
||||
return LSPAny(str);
|
||||
}
|
||||
|
||||
// nullptr
|
||||
static LSPAny ToLSPAny(std::nullptr_t) {
|
||||
static LSPAny ToLSPAny(std::nullptr_t)
|
||||
{
|
||||
return LSPAny(nullptr);
|
||||
}
|
||||
|
||||
// LSPAny 自身
|
||||
static LSPAny ToLSPAny(const LSPAny& any) {
|
||||
static LSPAny ToLSPAny(const LSPAny& any)
|
||||
{
|
||||
return any;
|
||||
}
|
||||
|
||||
@@ -268,10 +337,12 @@ struct LSPConvert {
|
||||
|
||||
// vector
|
||||
template<typename T>
|
||||
static LSPAny ToLSPAny(const std::vector<T>& vec) {
|
||||
static LSPAny ToLSPAny(const std::vector<T>& vec)
|
||||
{
|
||||
LSPArray arr;
|
||||
arr.reserve(vec.size());
|
||||
for (const auto& item : vec) {
|
||||
for (const auto& item : vec)
|
||||
{
|
||||
arr.push_back(ToLSPAny(item));
|
||||
}
|
||||
return LSPAny(std::move(arr));
|
||||
@@ -279,9 +350,11 @@ struct LSPConvert {
|
||||
|
||||
// map
|
||||
template<typename T>
|
||||
static LSPAny ToLSPAny(const std::map<string, T>& map) {
|
||||
static LSPAny ToLSPAny(const std::map<string, T>& map)
|
||||
{
|
||||
LSPObject obj;
|
||||
for (const auto& [key, value] : map) {
|
||||
for (const auto& [key, value] : map)
|
||||
{
|
||||
obj[key] = ToLSPAny(value);
|
||||
}
|
||||
return LSPAny(std::move(obj));
|
||||
@@ -289,8 +362,10 @@ struct LSPConvert {
|
||||
|
||||
// optional
|
||||
template<typename T>
|
||||
static LSPAny ToLSPAny(const std::optional<T>& opt) {
|
||||
if (opt.has_value()) {
|
||||
static LSPAny ToLSPAny(const std::optional<T>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
{
|
||||
return ToLSPAny(*opt);
|
||||
}
|
||||
return LSPAny(nullptr);
|
||||
@@ -304,19 +379,22 @@ struct LSPConvert {
|
||||
!std::is_same<T, const char*>::value &&
|
||||
!std::is_same<T, std::nullptr_t>::value &&
|
||||
!std::is_same<T, LSPAny>::value,
|
||||
LSPAny
|
||||
>::type ToLSPAny(const T& obj) {
|
||||
LSPAny>::type
|
||||
ToLSPAny(const T& obj)
|
||||
{
|
||||
// 序列化为 JSON 字符串
|
||||
std::string json;
|
||||
auto ec = glz::write_json(obj, json);
|
||||
if (ec) {
|
||||
if (ec)
|
||||
{
|
||||
throw std::runtime_error("Failed to serialize to JSON");
|
||||
}
|
||||
|
||||
// 直接解析为 LSPAny
|
||||
LSPAny result;
|
||||
ec = glz::read_json(result, json);
|
||||
if (ec) {
|
||||
if (ec)
|
||||
{
|
||||
throw std::runtime_error("Failed to parse JSON to LSPAny");
|
||||
}
|
||||
|
||||
@@ -326,8 +404,10 @@ struct LSPConvert {
|
||||
// === LSPAny 到基本类型的转换 ===
|
||||
|
||||
// boolean
|
||||
static boolean BoolFromLSPAny(const LSPAny& any) {
|
||||
if (!any.is<boolean>()) {
|
||||
static boolean BoolFromLSPAny(const LSPAny& any)
|
||||
{
|
||||
if (!any.is<boolean>())
|
||||
{
|
||||
throw std::runtime_error("LSPAny is not a boolean");
|
||||
}
|
||||
return any.get<boolean>();
|
||||
@@ -336,16 +416,20 @@ struct LSPConvert {
|
||||
// 数字类型
|
||||
template<typename T>
|
||||
static typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, boolean>::value, T>::type
|
||||
NumberFromLSPAny(const LSPAny& any) {
|
||||
if (!any.is<decimal>()) {
|
||||
NumberFromLSPAny(const LSPAny& any)
|
||||
{
|
||||
if (!any.is<decimal>())
|
||||
{
|
||||
throw std::runtime_error("LSPAny is not a number");
|
||||
}
|
||||
return static_cast<T>(any.get<decimal>());
|
||||
}
|
||||
|
||||
// string
|
||||
static string StringFromLSPAny(const LSPAny& any) {
|
||||
if (!any.is<string>()) {
|
||||
static string StringFromLSPAny(const LSPAny& any)
|
||||
{
|
||||
if (!any.is<string>())
|
||||
{
|
||||
throw std::runtime_error("LSPAny is not a string");
|
||||
}
|
||||
return any.get<string>();
|
||||
@@ -355,15 +439,18 @@ struct LSPConvert {
|
||||
|
||||
// vector
|
||||
template<typename T>
|
||||
static std::vector<T> VectorFromLSPAny(const LSPAny& any) {
|
||||
if (!any.is<LSPArray>()) {
|
||||
static std::vector<T> VectorFromLSPAny(const LSPAny& any)
|
||||
{
|
||||
if (!any.is<LSPArray>())
|
||||
{
|
||||
throw std::runtime_error("LSPAny is not an array");
|
||||
}
|
||||
|
||||
const auto& arr = any.get<LSPArray>();
|
||||
std::vector<T> result;
|
||||
result.reserve(arr.size());
|
||||
for (const auto& item : arr) {
|
||||
for (const auto& item : arr)
|
||||
{
|
||||
result.push_back(FromLSPAny<T>(item));
|
||||
}
|
||||
return result;
|
||||
@@ -371,8 +458,10 @@ struct LSPConvert {
|
||||
|
||||
// optional
|
||||
template<typename T>
|
||||
static std::optional<T> OptionalFromLSPAny(const LSPAny& any) {
|
||||
if (any.is<std::nullptr_t>()) {
|
||||
static std::optional<T> OptionalFromLSPAny(const LSPAny& any)
|
||||
{
|
||||
if (any.is<std::nullptr_t>())
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return FromLSPAny<T>(any);
|
||||
@@ -380,7 +469,8 @@ struct LSPConvert {
|
||||
|
||||
// === LSPAny 到 Struct 的转换 ===
|
||||
template<typename T>
|
||||
static T FromLSPAny(const LSPAny& any) {
|
||||
static T FromLSPAny(const LSPAny& any)
|
||||
{
|
||||
return FromLSPAnyImpl<T>(any);
|
||||
}
|
||||
|
||||
@@ -388,24 +478,28 @@ private:
|
||||
// 内部实现,使用重载来处理不同类型
|
||||
|
||||
// boolean
|
||||
static boolean FromLSPAnyImpl(const LSPAny& any, boolean*) {
|
||||
static boolean FromLSPAnyImpl(const LSPAny& any, boolean*)
|
||||
{
|
||||
return BoolFromLSPAny(any);
|
||||
}
|
||||
|
||||
// string
|
||||
static string FromLSPAnyImpl(const LSPAny& any, string*) {
|
||||
static string FromLSPAnyImpl(const LSPAny& any, string*)
|
||||
{
|
||||
return StringFromLSPAny(any);
|
||||
}
|
||||
|
||||
// 数字类型
|
||||
template<typename T>
|
||||
static typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, boolean>::value, T>::type
|
||||
FromLSPAnyImpl(const LSPAny& any, T*) {
|
||||
FromLSPAnyImpl(const LSPAny& any, T*)
|
||||
{
|
||||
return NumberFromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
// LSPAny 自身
|
||||
static LSPAny FromLSPAnyImpl(const LSPAny& any, LSPAny*) {
|
||||
static LSPAny FromLSPAnyImpl(const LSPAny& any, LSPAny*)
|
||||
{
|
||||
return any;
|
||||
}
|
||||
|
||||
@@ -415,19 +509,22 @@ private:
|
||||
!std::is_arithmetic<T>::value &&
|
||||
!std::is_same<T, string>::value &&
|
||||
!std::is_same<T, LSPAny>::value,
|
||||
T
|
||||
>::type FromLSPAnyImpl(const LSPAny& any, T*) {
|
||||
T>::type
|
||||
FromLSPAnyImpl(const LSPAny& any, T*)
|
||||
{
|
||||
// 序列化 LSPAny 为 JSON
|
||||
std::string json;
|
||||
auto ec = glz::write_json(any.value, json);
|
||||
if (ec) {
|
||||
if (ec)
|
||||
{
|
||||
throw std::runtime_error("Failed to serialize LSPAny to JSON");
|
||||
}
|
||||
|
||||
// 解析 JSON 到目标类型
|
||||
T result;
|
||||
ec = glz::read_json(result, json);
|
||||
if (ec) {
|
||||
if (ec)
|
||||
{
|
||||
throw std::runtime_error("Failed to parse JSON to target type");
|
||||
}
|
||||
|
||||
@@ -436,7 +533,8 @@ private:
|
||||
|
||||
// 通过指针类型来分派
|
||||
template<typename T>
|
||||
static T FromLSPAnyImpl(const LSPAny& any) {
|
||||
static T FromLSPAnyImpl(const LSPAny& any)
|
||||
{
|
||||
return FromLSPAnyImpl(any, static_cast<T*>(nullptr));
|
||||
}
|
||||
};
|
||||
@@ -461,17 +559,20 @@ inline LSPAny ToLSPAny(const LSPAny& any) { return LSPConvert::ToLSPAny(any); }
|
||||
|
||||
// 容器类型的便利函数
|
||||
template<typename T>
|
||||
LSPAny ToLSPAny(const std::vector<T>& vec) {
|
||||
LSPAny ToLSPAny(const std::vector<T>& vec)
|
||||
{
|
||||
return LSPConvert::ToLSPAny(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
LSPAny ToLSPAny(const std::map<string, T>& map) {
|
||||
LSPAny ToLSPAny(const std::map<string, T>& map)
|
||||
{
|
||||
return LSPConvert::ToLSPAny(map);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
LSPAny ToLSPAny(const std::optional<T>& opt) {
|
||||
LSPAny ToLSPAny(const std::optional<T>& opt)
|
||||
{
|
||||
return LSPConvert::ToLSPAny(opt);
|
||||
}
|
||||
|
||||
@@ -483,46 +584,54 @@ typename std::enable_if<
|
||||
!std::is_same<T, const char*>::value &&
|
||||
!std::is_same<T, std::nullptr_t>::value &&
|
||||
!std::is_same<T, LSPAny>::value,
|
||||
LSPAny
|
||||
>::type ToLSPAny(const T& value) {
|
||||
LSPAny>::type
|
||||
ToLSPAny(const T& value)
|
||||
{
|
||||
return LSPConvert::ToLSPAny(value);
|
||||
}
|
||||
|
||||
// FromLSPAny 便利函数
|
||||
template<typename T>
|
||||
T FromLSPAny(const LSPAny& any) {
|
||||
T FromLSPAny(const LSPAny& any)
|
||||
{
|
||||
return LSPConvert::FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
// ===== 测试代码 =====
|
||||
|
||||
// 测试用的结构体
|
||||
struct Message {
|
||||
struct Message
|
||||
{
|
||||
string jsonrpc = "2.0";
|
||||
string method;
|
||||
int id = 0;
|
||||
};
|
||||
|
||||
struct Position {
|
||||
struct Position
|
||||
{
|
||||
int line;
|
||||
int character;
|
||||
};
|
||||
|
||||
struct Range {
|
||||
struct Range
|
||||
{
|
||||
Position start;
|
||||
Position end;
|
||||
};
|
||||
|
||||
struct TextDocumentIdentifier {
|
||||
struct TextDocumentIdentifier
|
||||
{
|
||||
string uri;
|
||||
};
|
||||
|
||||
struct TextDocumentPositionParams {
|
||||
struct TextDocumentPositionParams
|
||||
{
|
||||
TextDocumentIdentifier textDocument;
|
||||
Position position;
|
||||
};
|
||||
|
||||
struct CompletionItem {
|
||||
struct CompletionItem
|
||||
{
|
||||
string label;
|
||||
std::optional<int> kind;
|
||||
std::optional<string> detail;
|
||||
@@ -535,71 +644,91 @@ struct CompletionItem {
|
||||
};
|
||||
|
||||
// 为测试结构体提供 glaze 元数据
|
||||
template <>
|
||||
struct glz::meta<Message> {
|
||||
template<>
|
||||
struct glz::meta<Message>
|
||||
{
|
||||
using T = Message;
|
||||
static constexpr auto value = object(
|
||||
"jsonrpc", &T::jsonrpc,
|
||||
"method", &T::method,
|
||||
"id", &T::id
|
||||
);
|
||||
"jsonrpc",
|
||||
&T::jsonrpc,
|
||||
"method",
|
||||
&T::method,
|
||||
"id",
|
||||
&T::id);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct glz::meta<Position> {
|
||||
template<>
|
||||
struct glz::meta<Position>
|
||||
{
|
||||
using T = Position;
|
||||
static constexpr auto value = object(
|
||||
"line", &T::line,
|
||||
"character", &T::character
|
||||
);
|
||||
"line",
|
||||
&T::line,
|
||||
"character",
|
||||
&T::character);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct glz::meta<Range> {
|
||||
template<>
|
||||
struct glz::meta<Range>
|
||||
{
|
||||
using T = Range;
|
||||
static constexpr auto value = object(
|
||||
"start", &T::start,
|
||||
"end", &T::end
|
||||
);
|
||||
"start",
|
||||
&T::start,
|
||||
"end",
|
||||
&T::end);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct glz::meta<TextDocumentIdentifier> {
|
||||
template<>
|
||||
struct glz::meta<TextDocumentIdentifier>
|
||||
{
|
||||
using T = TextDocumentIdentifier;
|
||||
static constexpr auto value = object(
|
||||
"uri", &T::uri
|
||||
);
|
||||
"uri",
|
||||
&T::uri);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct glz::meta<TextDocumentPositionParams> {
|
||||
template<>
|
||||
struct glz::meta<TextDocumentPositionParams>
|
||||
{
|
||||
using T = TextDocumentPositionParams;
|
||||
static constexpr auto value = object(
|
||||
"textDocument", &T::textDocument,
|
||||
"position", &T::position
|
||||
);
|
||||
"textDocument",
|
||||
&T::textDocument,
|
||||
"position",
|
||||
&T::position);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct glz::meta<CompletionItem> {
|
||||
template<>
|
||||
struct glz::meta<CompletionItem>
|
||||
{
|
||||
using T = CompletionItem;
|
||||
static constexpr auto value = object(
|
||||
"label", &T::label,
|
||||
"kind", &T::kind,
|
||||
"detail", &T::detail,
|
||||
"documentation", &T::documentation,
|
||||
"deprecated", &T::deprecated,
|
||||
"preselect", &T::preselect,
|
||||
"sortText", &T::sortText,
|
||||
"filterText", &T::filterText,
|
||||
"insertText", &T::insertText
|
||||
);
|
||||
"label",
|
||||
&T::label,
|
||||
"kind",
|
||||
&T::kind,
|
||||
"detail",
|
||||
&T::detail,
|
||||
"documentation",
|
||||
&T::documentation,
|
||||
"deprecated",
|
||||
&T::deprecated,
|
||||
"preselect",
|
||||
&T::preselect,
|
||||
"sortText",
|
||||
&T::sortText,
|
||||
"filterText",
|
||||
&T::filterText,
|
||||
"insertText",
|
||||
&T::insertText);
|
||||
};
|
||||
|
||||
// 测试函数
|
||||
#include <iostream>
|
||||
|
||||
void test_basic_conversion() {
|
||||
void test_basic_conversion()
|
||||
{
|
||||
std::cout << "=== Testing Basic Conversion ===" << std::endl;
|
||||
|
||||
// 测试 struct 转换
|
||||
@@ -621,13 +750,14 @@ void test_basic_conversion() {
|
||||
std::cout << "Restored id: " << restored.id << std::endl;
|
||||
}
|
||||
|
||||
void test_vector_conversion() {
|
||||
void test_vector_conversion()
|
||||
{
|
||||
std::cout << "\n=== Testing Vector Conversion ===" << std::endl;
|
||||
|
||||
std::vector<Position> positions = {
|
||||
{10, 5},
|
||||
{20, 15},
|
||||
{30, 25}
|
||||
{ 10, 5 },
|
||||
{ 20, 15 },
|
||||
{ 30, 25 }
|
||||
};
|
||||
|
||||
// Vector -> LSPAny
|
||||
@@ -642,7 +772,8 @@ void test_vector_conversion() {
|
||||
std::cout << "Restored " << restored.size() << " positions" << std::endl;
|
||||
}
|
||||
|
||||
void test_optional_conversion() {
|
||||
void test_optional_conversion()
|
||||
{
|
||||
std::cout << "\n=== Testing Optional Conversion ===" << std::endl;
|
||||
|
||||
CompletionItem item;
|
||||
@@ -663,14 +794,15 @@ void test_optional_conversion() {
|
||||
std::cout << "Empty optional as JSON: " << json << std::endl;
|
||||
}
|
||||
|
||||
void test_mixed_usage() {
|
||||
void test_mixed_usage()
|
||||
{
|
||||
std::cout << "\n=== Testing Mixed Usage ===" << std::endl;
|
||||
|
||||
// 创建复杂对象
|
||||
LSPObject obj;
|
||||
obj["message"] = ToLSPAny(Message{"2.0", "test/method", 123});
|
||||
obj["position"] = ToLSPAny(Position{10, 20});
|
||||
obj["numbers"] = ToLSPAny(std::vector<int>{1, 2, 3});
|
||||
obj["message"] = ToLSPAny(Message{ "2.0", "test/method", 123 });
|
||||
obj["position"] = ToLSPAny(Position{ 10, 20 });
|
||||
obj["numbers"] = ToLSPAny(std::vector<int>{ 1, 2, 3 });
|
||||
obj["flag"] = LSPAny(true);
|
||||
obj["value"] = LSPAny(3.14);
|
||||
obj["text"] = LSPAny("Hello LSP");
|
||||
@@ -683,7 +815,8 @@ void test_mixed_usage() {
|
||||
std::cout << "Complex object: " << json << std::endl;
|
||||
|
||||
// 提取值
|
||||
if (root.is<LSPObject>()) {
|
||||
if (root.is<LSPObject>())
|
||||
{
|
||||
auto& root_obj = root.get<LSPObject>();
|
||||
|
||||
Message msg = FromLSPAny<Message>(root_obj["message"]);
|
||||
@@ -694,15 +827,19 @@ void test_mixed_usage() {
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
test_basic_conversion();
|
||||
test_vector_conversion();
|
||||
test_optional_conversion();
|
||||
test_mixed_usage();
|
||||
|
||||
std::cout << "\nAll tests completed!" << std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Exception: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
@@ -1,41 +1 @@
|
||||
function MyFunc(a: string; b: array of string);
|
||||
begin
|
||||
end
|
||||
function MyFunc(a: string; b: array of string);overload;
|
||||
begin
|
||||
end;
|
||||
|
||||
// type ImageDimensions = class
|
||||
// property Width read width_;
|
||||
// property Width : array of string index 2 read width_;
|
||||
// end;
|
||||
|
||||
// <?tslx>
|
||||
// <div class="element-data-container">
|
||||
// <?tsl
|
||||
// rpt_data_bar(data[i],canAudit);
|
||||
// ?>
|
||||
// <div class="diff-section <?= isDiffed?'diff-section-diffed':''?>" id="eid-<?=tempid?>">
|
||||
// <div class="diff-left span5">
|
||||
// <?tsl
|
||||
// try
|
||||
// rpt_show_data(other_data_i);
|
||||
// except
|
||||
// dolog("diffrepot_erData","数据解析展示出错:"$data[i]["NAME"]);
|
||||
// dolog("diffrepot_erData",tostn(data[i]["DATA_ID"]));
|
||||
// end;
|
||||
|
||||
// ?>
|
||||
// </div>
|
||||
|
||||
// <div class="diff-right span5">
|
||||
// <?tsl rpt_show_data(data[i]); ?>
|
||||
// </div>
|
||||
// <div class="span2">
|
||||
// <?=class(IDS_LiveReport).rpt_data_comments(data[i]['comment'])?>
|
||||
// </div>
|
||||
// <div class="clear"></div>
|
||||
// </div>
|
||||
// </div><!--end element-data-container -->
|
||||
// <?tsl
|
||||
|
||||
data := `r | data;
|
||||
|
||||
@@ -13,6 +13,9 @@ ROOT_DIRS=(
|
||||
"/mnt/d/code/tinysoft/OfficeXml-dev/generator"
|
||||
"/mnt/d/code/tinysoft/tsoffice/"
|
||||
"/mnt/d/code/tinysoft/pdfconverter"
|
||||
"/mnt/c/Programs/Tinysoft/TSLGen2/funcext/other"
|
||||
"/mnt/c/Programs/Tinysoft/TSLGen2/funcext/tsword"
|
||||
"/mnt/c/Programs/Tinysoft/TSLGen2/funcext/word2arr"
|
||||
# "/mnt/d/code/tinysoft/PdfConverter"
|
||||
# 可以添加更多目录
|
||||
# "/path/to/third/directory"
|
||||
|
||||
@@ -58,9 +58,10 @@ module.exports = grammar({
|
||||
word: ($) => $.identifier,
|
||||
|
||||
conflicts: ($) => [
|
||||
[$._left_hand_side, $.primary_expression],
|
||||
[$.tssql_select_expression, $._table_or_subquery],
|
||||
[$._left_hand_side, $._primary_expression],
|
||||
[$._tssql_select_expression, $._table_or_subquery],
|
||||
[$.tslx_close_tag, $.tslx_expression_tag],
|
||||
[$._assignable_expression, $.array_element],
|
||||
],
|
||||
|
||||
inline: ($) => [$._statement],
|
||||
@@ -86,22 +87,22 @@ module.exports = grammar({
|
||||
$.break_statement,
|
||||
$.continue_statement,
|
||||
$.return_statement,
|
||||
$.inherited_statement,
|
||||
// $.inherited_statement,
|
||||
),
|
||||
|
||||
_compound_statement: ($) =>
|
||||
choice(
|
||||
$.if_statement,
|
||||
$.for_statement,
|
||||
$._for_statement,
|
||||
$.while_statement,
|
||||
$.repeat_statement,
|
||||
$.case_statement,
|
||||
$.try_statement,
|
||||
|
||||
$.anonymous_function_statement,
|
||||
// $.function_declaration_statement,
|
||||
$.function_declaration_statement,
|
||||
$.function_definition_statement,
|
||||
$.function_definition_statement_with_overload,
|
||||
$.function_definition_with_overload_statement,
|
||||
$.class_definition_statement,
|
||||
$.external_method_statement,
|
||||
|
||||
@@ -109,11 +110,14 @@ module.exports = grammar({
|
||||
$._tslx_template_statement,
|
||||
),
|
||||
|
||||
var_statement: ($) => seq($.var_declaration, kSemicolon),
|
||||
var_statement: ($) =>
|
||||
seq(field("declaration", $.var_declaration), kSemicolon),
|
||||
|
||||
static_statement: ($) => seq($.static_declaration, kSemicolon),
|
||||
static_statement: ($) =>
|
||||
seq(field("declaration", $.static_declaration), kSemicolon),
|
||||
|
||||
global_statement: ($) => seq($.global_declaration, kSemicolon),
|
||||
global_statement: ($) =>
|
||||
seq(field("declaration", $.global_declaration), kSemicolon),
|
||||
|
||||
const_statement: ($) =>
|
||||
seq(
|
||||
@@ -126,13 +130,16 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
var_declaration: ($) =>
|
||||
seq(kw("var"), $._variable_declaration, optional($._type_clause)),
|
||||
seq(kw("var"), $._variable_declaration, optional($._type_clause), optional($._initial_value)),
|
||||
|
||||
static_declaration: ($) =>
|
||||
seq(kw("static"), $._variable_declaration, optional($._type_clause)),
|
||||
seq(kw("static"), $._variable_declaration, optional($._type_clause), optional($._initial_value)),
|
||||
|
||||
global_declaration: ($) =>
|
||||
seq(kw("global"), $._variable_declaration, optional($._type_clause)),
|
||||
seq(kw("global"), $._variable_declaration, optional($._type_clause), optional($._initial_value)),
|
||||
|
||||
_initial_value: ($) =>
|
||||
seq(":=", field("initial_value", $._right_hand_side)),
|
||||
|
||||
_variable_declaration: ($) => sep1(field("name", $.identifier), ","),
|
||||
|
||||
@@ -165,73 +172,43 @@ module.exports = grammar({
|
||||
continue_statement: (_) => seq(kw("continue"), kSemicolon),
|
||||
|
||||
return_statement: ($) =>
|
||||
seq(kw("return"), optional($.expression), kSemicolon),
|
||||
seq(kw("return"), field("value", optional($.expression)), kSemicolon),
|
||||
|
||||
inherited_statement: ($) => seq($.inherited_expression, kSemicolon),
|
||||
// inherited_statement: ($) => seq($._inherited_expression, kSemicolon),
|
||||
|
||||
_built_in_expression: ($) =>
|
||||
choice($.echo_expression, $.raise_expression, $.new_expression),
|
||||
choice($.echo_expression, $.raise_expression, $.new_expression, $.inherited_expression),
|
||||
|
||||
echo_expression: ($) =>
|
||||
prec.left(1, seq(kw("echo"), sep1($.expression, ","))),
|
||||
prec.left(1, seq(kw("echo"), sep1(field("argument", $.expression), ","))),
|
||||
|
||||
raise_expression: ($) => seq(kw("raise"), $.expression),
|
||||
raise_expression: ($) => seq(kw("raise"), field("exception", $.expression)),
|
||||
|
||||
inherited_expression: ($) => seq(kw("inherited"), optional($.expression)),
|
||||
inherited_expression: ($) => prec.left(0, seq(kw("inherited"), field("class", optional($.expression)))),
|
||||
|
||||
new_expression: ($) => seq(kw("new"), $.expression),
|
||||
new_expression: ($) => seq(kw("new"), field("class", $.expression)),
|
||||
|
||||
expression_statement: ($) =>
|
||||
seq(choice($.expression, $.tssql_dml_expression), kSemicolon),
|
||||
seq(choice($.expression, $._tssql_dml_expression), kSemicolon),
|
||||
|
||||
expression: ($) =>
|
||||
choice(
|
||||
$.operator_expression,
|
||||
$.tssql_select_expression,
|
||||
$.primary_expression,
|
||||
$._operator_expression,
|
||||
$._tssql_select_expression,
|
||||
$._primary_expression,
|
||||
$._built_in_expression,
|
||||
),
|
||||
|
||||
operator_expression: ($) =>
|
||||
_operator_expression: ($) =>
|
||||
choice(
|
||||
$.expr_expression,
|
||||
|
||||
$.ternary_expression,
|
||||
|
||||
$.logical_or_expression,
|
||||
$.logical_and_expression,
|
||||
$.logical_not_expression,
|
||||
|
||||
$.comparison_expression,
|
||||
|
||||
$.bitwise_or_expression,
|
||||
$.bitwise_and_expression,
|
||||
$.bitwise_xor_expression,
|
||||
$.bitwise_not_expression,
|
||||
$.shift_expression,
|
||||
|
||||
$.addition_expression,
|
||||
$.multiplication_expression,
|
||||
$.power_expression,
|
||||
$.logarithm_expression,
|
||||
|
||||
$.matrix_multiplication_expression,
|
||||
$.matrix_power_expression,
|
||||
$.matrix_concatenation_expression,
|
||||
$.matrix_transpose_expression,
|
||||
$.range_expression,
|
||||
|
||||
$.set_operation_expression,
|
||||
|
||||
$.concatenation_expression,
|
||||
|
||||
$.unary_plus_expression,
|
||||
$.unary_minus_expression,
|
||||
$.binary_expression,
|
||||
$.unary_expression,
|
||||
$.prefix_increment_expression,
|
||||
$.prefix_decrement_expression,
|
||||
$.postfix_increment_expression,
|
||||
$.postfix_decrement_expression,
|
||||
$.derivative_expression,
|
||||
$.function_pointer_expression,
|
||||
),
|
||||
|
||||
@@ -295,7 +272,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
_with_assignment_expression: ($) =>
|
||||
_assignable_expression: ($) =>
|
||||
choice(
|
||||
$.expression,
|
||||
$.assignment_expression,
|
||||
@@ -308,51 +285,45 @@ module.exports = grammar({
|
||||
seq(
|
||||
field("condition", $.expression),
|
||||
"?",
|
||||
optional(field("consequence", $._with_assignment_expression)),
|
||||
optional(field("consequence", $._assignable_expression)),
|
||||
":",
|
||||
field("alternative", $._with_assignment_expression),
|
||||
field("alternative", $._assignable_expression),
|
||||
),
|
||||
),
|
||||
|
||||
logical_or_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogicalOr,
|
||||
seq(
|
||||
field("left", $.expression),
|
||||
field("operator", choice(kw("or"), ".||", "||")),
|
||||
field("right", $.expression),
|
||||
),
|
||||
binary_expression: ($) =>
|
||||
choice(
|
||||
$._logical_or_expression,
|
||||
$._logical_and_expression,
|
||||
|
||||
$._bitwise_or_expression,
|
||||
$._bitwise_and_expression,
|
||||
$._bitwise_xor_expression,
|
||||
$._shift_expression,
|
||||
|
||||
$._addition_expression,
|
||||
$._multiplication_expression,
|
||||
$._power_expression,
|
||||
$._logarithm_expression,
|
||||
|
||||
$._matrix_multiplication_expression,
|
||||
$._matrix_power_expression,
|
||||
$._matrix_concatenation_expression,
|
||||
$._range_expression,
|
||||
|
||||
$._comparison_expression,
|
||||
|
||||
$._set_operation_expression,
|
||||
|
||||
$._concatenation_expression,
|
||||
),
|
||||
|
||||
logical_and_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogicalAnd,
|
||||
seq(
|
||||
field("left", $.expression),
|
||||
field("operator", choice(kw("and"), ".&&", "&&")),
|
||||
field("right", $.expression),
|
||||
),
|
||||
),
|
||||
|
||||
logical_not_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogicalNot,
|
||||
seq(
|
||||
field("operator", choice(kw("not"), ".!!")),
|
||||
field("argument", $.expression),
|
||||
),
|
||||
),
|
||||
|
||||
comparison_expression: ($) =>
|
||||
_comparison_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kComparsion,
|
||||
seq(
|
||||
$.expression,
|
||||
repeat1(
|
||||
seq(
|
||||
field(
|
||||
"operators",
|
||||
choice(
|
||||
field("left", $.expression),
|
||||
field("operator", choice(
|
||||
"=",
|
||||
"<>",
|
||||
">",
|
||||
@@ -370,13 +341,40 @@ module.exports = grammar({
|
||||
kw("like"),
|
||||
),
|
||||
),
|
||||
$.expression,
|
||||
),
|
||||
),
|
||||
field("right", $.expression),
|
||||
),
|
||||
),
|
||||
|
||||
bitwise_or_expression: ($) =>
|
||||
_logical_or_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogicalOr,
|
||||
seq(
|
||||
field("left", $.expression),
|
||||
field("operator", choice(kw("or"), ".||", "||")),
|
||||
field("right", $.expression),
|
||||
),
|
||||
),
|
||||
|
||||
_logical_and_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogicalAnd,
|
||||
seq(
|
||||
field("left", $.expression),
|
||||
field("operator", choice(kw("and"), ".&&", "&&")),
|
||||
field("right", $.expression),
|
||||
),
|
||||
),
|
||||
|
||||
_logical_not_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogicalNot,
|
||||
seq(
|
||||
field("operator", choice(kw("not"), ".!!")),
|
||||
field("argument", $.expression),
|
||||
),
|
||||
),
|
||||
|
||||
_bitwise_or_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kBitwiseOr,
|
||||
seq(
|
||||
@@ -386,7 +384,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
bitwise_and_expression: ($) =>
|
||||
_bitwise_and_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kBitwiseAnd,
|
||||
seq(
|
||||
@@ -396,7 +394,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
bitwise_xor_expression: ($) =>
|
||||
_bitwise_xor_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kBitwiseXor,
|
||||
seq(
|
||||
@@ -406,13 +404,13 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
bitwise_not_expression: ($) =>
|
||||
_bitwise_not_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kBitwiseNot,
|
||||
seq(field("operator", ".!"), field("argument", $.expression)),
|
||||
),
|
||||
|
||||
shift_expression: ($) =>
|
||||
_shift_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kShift,
|
||||
seq(
|
||||
@@ -422,7 +420,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
addition_expression: ($) =>
|
||||
_addition_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kAddSub,
|
||||
seq(
|
||||
@@ -432,7 +430,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
multiplication_expression: ($) =>
|
||||
_multiplication_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kTimes,
|
||||
seq(
|
||||
@@ -442,7 +440,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
power_expression: ($) =>
|
||||
_power_expression: ($) =>
|
||||
prec.right(
|
||||
kPrec.kPower,
|
||||
seq(
|
||||
@@ -452,7 +450,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
logarithm_expression: ($) =>
|
||||
_logarithm_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kLogarithm,
|
||||
seq(
|
||||
@@ -462,7 +460,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
matrix_multiplication_expression: ($) =>
|
||||
_matrix_multiplication_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kMatrixTimes,
|
||||
seq(
|
||||
@@ -472,7 +470,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
matrix_power_expression: ($) =>
|
||||
_matrix_power_expression: ($) =>
|
||||
prec.right(
|
||||
kPrec.kMatrixPower,
|
||||
seq(
|
||||
@@ -482,7 +480,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
matrix_concatenation_expression: ($) =>
|
||||
_matrix_concatenation_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kMatrixConcat,
|
||||
seq(
|
||||
@@ -492,7 +490,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
range_expression: ($) =>
|
||||
_range_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kRange,
|
||||
seq(
|
||||
@@ -502,13 +500,13 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
matrix_transpose_expression: ($) =>
|
||||
_matrix_transpose_expression: ($) =>
|
||||
prec(
|
||||
kPrec.kMatrixTranspose,
|
||||
seq(field("operator", "`"), field("argument", $.expression)),
|
||||
),
|
||||
|
||||
set_operation_expression: ($) =>
|
||||
_set_operation_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kSet,
|
||||
seq(
|
||||
@@ -527,7 +525,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
concatenation_expression: ($) =>
|
||||
_concatenation_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kConcat,
|
||||
seq(
|
||||
@@ -537,18 +535,37 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
unary_plus_expression: ($) =>
|
||||
unary_expression: ($) =>
|
||||
choice(
|
||||
$._unary_plus_expression,
|
||||
$._unary_minus_expression,
|
||||
$._derivative_expression,
|
||||
|
||||
$._logical_not_expression,
|
||||
|
||||
$._bitwise_not_expression,
|
||||
|
||||
$._matrix_transpose_expression,
|
||||
),
|
||||
|
||||
_unary_plus_expression: ($) =>
|
||||
prec(
|
||||
kPrec.kSigned,
|
||||
seq(field("operator", "+"), field("argument", $.expression)),
|
||||
),
|
||||
|
||||
unary_minus_expression: ($) =>
|
||||
_unary_minus_expression: ($) =>
|
||||
prec(
|
||||
kPrec.kSigned,
|
||||
seq(field("operator", "-"), field("argument", $.expression)),
|
||||
),
|
||||
|
||||
_derivative_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kDerivative,
|
||||
seq(field("operator", "!"), field("argument", $.expression)),
|
||||
),
|
||||
|
||||
prefix_increment_expression: ($) =>
|
||||
prec.right(
|
||||
kPrec.kPrefix,
|
||||
@@ -573,12 +590,6 @@ module.exports = grammar({
|
||||
seq(field("argument", $.expression), field("operator", "--")),
|
||||
),
|
||||
|
||||
derivative_expression: ($) =>
|
||||
prec.left(
|
||||
kPrec.kDerivative,
|
||||
seq(field("operator", "!"), field("argument", $.expression)),
|
||||
),
|
||||
|
||||
function_pointer_expression: ($) =>
|
||||
prec(
|
||||
kPrec.kFunctionPointer,
|
||||
@@ -591,7 +602,7 @@ module.exports = grammar({
|
||||
$._parameter_signature,
|
||||
field("return_type", optional($._type_clause)),
|
||||
optional(kSemicolon),
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
),
|
||||
|
||||
unpack_pattern: ($) => prec.dynamic(1, seq("[", $._unpack_vars, "]")),
|
||||
@@ -604,10 +615,7 @@ module.exports = grammar({
|
||||
|
||||
_left_hand_side: ($) =>
|
||||
choice(
|
||||
$._assignable_identifier,
|
||||
$.var_declaration,
|
||||
$.static_declaration,
|
||||
$.global_declaration,
|
||||
$._identifier_like,
|
||||
$.attribute,
|
||||
$.subscript,
|
||||
$.unpack_pattern,
|
||||
@@ -620,7 +628,7 @@ module.exports = grammar({
|
||||
$.augmented_assignment_expression,
|
||||
),
|
||||
|
||||
tssql_select_expression: ($) =>
|
||||
_tssql_select_expression: ($) =>
|
||||
choice(
|
||||
$.select_expression,
|
||||
$.sselect_expression,
|
||||
@@ -628,7 +636,7 @@ module.exports = grammar({
|
||||
$.mselect_expression,
|
||||
),
|
||||
|
||||
tssql_dml_expression: ($) =>
|
||||
_tssql_dml_expression: ($) =>
|
||||
choice($.update_expression, $.delete_expression, $.insert_expression),
|
||||
|
||||
select_expression: ($) => seq(kw("select"), $._select_clause),
|
||||
@@ -673,7 +681,7 @@ module.exports = grammar({
|
||||
|
||||
update_assignment: ($) =>
|
||||
seq(
|
||||
field("column", $.primary_expression),
|
||||
field("column", $._primary_expression),
|
||||
"=",
|
||||
field("value", $.expression),
|
||||
),
|
||||
@@ -799,16 +807,16 @@ module.exports = grammar({
|
||||
")",
|
||||
),
|
||||
|
||||
primary_expression: ($) =>
|
||||
_primary_expression: ($) =>
|
||||
choice(
|
||||
$.attribute,
|
||||
$.subscript,
|
||||
$.parenthesized_expression,
|
||||
$.call,
|
||||
$.array,
|
||||
$._literal,
|
||||
$._assignable_identifier,
|
||||
$._reserved_keyword,
|
||||
$.literal,
|
||||
$.reserved_keyword,
|
||||
$._parenthesized_expression,
|
||||
$._identifier_like,
|
||||
|
||||
$.sql_field,
|
||||
),
|
||||
@@ -816,12 +824,12 @@ module.exports = grammar({
|
||||
// identifier: _ => /[a-zA-Z_][a-zA-Z0-9_]*/,
|
||||
identifier: (_) => token(prec(kPrec.kIdentifier, /[a-zA-Z_][a-zA-Z0-9_]*/)),
|
||||
|
||||
_literal: ($) =>
|
||||
literal: ($) =>
|
||||
choice($.number, $.string, $.boolean, $.nil, $.infinity, $.ellipsis),
|
||||
|
||||
_assignable_identifier: ($) => choice($.identifier, $.type, $.do),
|
||||
_identifier_like: ($) => choice($.identifier, $.type, $.do),
|
||||
|
||||
_reserved_keyword: ($) => choice($.class, $.in),
|
||||
reserved_keyword: ($) => choice($.class, $.in),
|
||||
|
||||
type: (_) => kw("type"),
|
||||
class: (_) => kw("class"),
|
||||
@@ -890,9 +898,9 @@ module.exports = grammar({
|
||||
prec(
|
||||
kPrec.kCall,
|
||||
seq(
|
||||
field("function", $.primary_expression),
|
||||
field("function", $._primary_expression),
|
||||
"(",
|
||||
field("arguments", optional($.argument_list)),
|
||||
optional(sep1(field("argument", $.argument), ",")),
|
||||
")",
|
||||
),
|
||||
),
|
||||
@@ -901,7 +909,7 @@ module.exports = grammar({
|
||||
prec(
|
||||
kPrec.kAttribute,
|
||||
seq(
|
||||
field("object", choice($.primary_expression)),
|
||||
field("object", choice($._primary_expression)),
|
||||
".",
|
||||
field("attribute", $.identifier),
|
||||
),
|
||||
@@ -913,7 +921,7 @@ module.exports = grammar({
|
||||
prec(
|
||||
kPrec.kSubscript,
|
||||
seq(
|
||||
field("value", $.primary_expression),
|
||||
field("value", $._primary_expression),
|
||||
"[",
|
||||
field("subscript", $._index_spec),
|
||||
"]",
|
||||
@@ -921,8 +929,7 @@ module.exports = grammar({
|
||||
),
|
||||
),
|
||||
|
||||
parenthesized_expression: ($) =>
|
||||
seq("(", $._with_assignment_expression, ")"),
|
||||
_parenthesized_expression: ($) => seq("(", optional($._assignable_expression), ")"),
|
||||
|
||||
array: ($) =>
|
||||
prec(
|
||||
@@ -930,15 +937,18 @@ module.exports = grammar({
|
||||
seq(kw("array"), "(", optional($._array_elements), ")"),
|
||||
),
|
||||
|
||||
argument_list: ($) => sep1($.argument, ","),
|
||||
|
||||
argument: ($) =>
|
||||
choice(
|
||||
$.expression,
|
||||
seq(field("name", $.identifier), ":", field("value", $.expression)),
|
||||
"*",
|
||||
$.named_argument,
|
||||
// $.spread_argument
|
||||
),
|
||||
|
||||
named_argument: ($) =>
|
||||
seq(field("name", $.identifier), ":", field("value", $.expression)),
|
||||
|
||||
// spread_argument: (_) => "*",
|
||||
|
||||
_index_spec: ($) => choice($._multi_index, $._single_index),
|
||||
|
||||
_multi_index: ($) => seq($._index_item, repeat1(seq(",", $._index_item))),
|
||||
@@ -969,9 +979,9 @@ module.exports = grammar({
|
||||
|
||||
key_value_pair: ($) =>
|
||||
seq(
|
||||
field("key", $.expression),
|
||||
field("key", choice($.expression)),
|
||||
":",
|
||||
field("value", choice($.expression, $.parenthesized_array)),
|
||||
field("value", choice($.parenthesized_array, $.expression)),
|
||||
),
|
||||
|
||||
parenthesized_array: ($) =>
|
||||
@@ -979,12 +989,7 @@ module.exports = grammar({
|
||||
1,
|
||||
seq(
|
||||
"(",
|
||||
choice(
|
||||
seq($.key_value_pair, ",", sep1($.key_value_pair, ",")),
|
||||
$.key_value_pair,
|
||||
seq($.expression, ",", sep1($.expression, ",")),
|
||||
$.expression,
|
||||
),
|
||||
sep1($.array_element, ","),
|
||||
optional(","),
|
||||
")",
|
||||
),
|
||||
@@ -1001,15 +1006,15 @@ module.exports = grammar({
|
||||
kPrec.kIf,
|
||||
seq(
|
||||
$.if_clause,
|
||||
repeat(field("alternative", $.else_if_clause)),
|
||||
optional(field("alternative", $.else_clause)),
|
||||
repeat($.else_if_clause),
|
||||
optional($.else_clause),
|
||||
),
|
||||
),
|
||||
|
||||
if_clause: ($) =>
|
||||
seq(
|
||||
kw("if"),
|
||||
field("condition", $._with_assignment_expression),
|
||||
field("condition", $._assignable_expression),
|
||||
kw("then"),
|
||||
field("consequence", $._statement_suite),
|
||||
),
|
||||
@@ -1020,7 +1025,7 @@ module.exports = grammar({
|
||||
seq(
|
||||
kw("else"),
|
||||
kw("if"),
|
||||
field("condition", $._with_assignment_expression),
|
||||
field("condition", $._assignable_expression),
|
||||
kw("then"),
|
||||
field("consequence", $._statement_suite),
|
||||
),
|
||||
@@ -1030,13 +1035,13 @@ module.exports = grammar({
|
||||
seq(kw("else"), field("consequence", $._statement_suite)),
|
||||
|
||||
_statement_suite: ($) =>
|
||||
choice(seq($.block_statement, optional(kSemicolon)), $.single_suite),
|
||||
choice(seq($.block_suite, optional(kSemicolon)), $.single_suite),
|
||||
|
||||
single_suite: ($) => $._statement,
|
||||
|
||||
block_statement: ($) => seq(kw("begin"), repeat($._statement), kw("end")),
|
||||
block_suite: ($) => seq(kw("begin"), repeat($._statement), kw("end")),
|
||||
|
||||
for_statement: ($) => choice($.for_in_statement, $.for_to_statement),
|
||||
_for_statement: ($) => choice($.for_in_statement, $.for_to_statement),
|
||||
|
||||
for_in_statement: ($) =>
|
||||
seq(
|
||||
@@ -1091,13 +1096,9 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
case_branch: ($) =>
|
||||
seq(
|
||||
$.case_values,
|
||||
":",
|
||||
field("consequence", $._statement_suite),
|
||||
),
|
||||
seq($._case_values, ":", field("consequence", $._statement_suite)),
|
||||
|
||||
case_values: ($) => sep1(field("value", $.expression), ","),
|
||||
_case_values: ($) => sep1(field("value", $.expression), ","),
|
||||
|
||||
case_else: ($) => seq(kw("else"), field("consequence", $._statement_suite)),
|
||||
|
||||
@@ -1114,14 +1115,14 @@ module.exports = grammar({
|
||||
anonymous_function_statement: ($) =>
|
||||
seq($.anonymous_function_expression, optional(kSemicolon)),
|
||||
|
||||
// function_declaration_statement: ($) =>
|
||||
// seq(
|
||||
// kw("function"),
|
||||
// field("name", $.identifier),
|
||||
// $._parameter_signature,
|
||||
// optional(field("return_type", $._type_clause)),
|
||||
// kSemicolon,
|
||||
// ),
|
||||
function_declaration_statement: ($) =>
|
||||
seq(
|
||||
kw("function"),
|
||||
field("name", $.identifier),
|
||||
$._parameter_signature,
|
||||
optional(field("return_type", $._type_clause)),
|
||||
kSemicolon,
|
||||
),
|
||||
|
||||
function_definition_statement: ($) =>
|
||||
seq(
|
||||
@@ -1130,11 +1131,11 @@ module.exports = grammar({
|
||||
$._parameter_signature,
|
||||
field("return_type", optional($._type_clause)),
|
||||
optional(kSemicolon),
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
function_definition_statement_with_overload: ($) =>
|
||||
function_definition_with_overload_statement: ($) =>
|
||||
seq(
|
||||
kw("function"),
|
||||
field("name", $.identifier),
|
||||
@@ -1143,20 +1144,20 @@ module.exports = grammar({
|
||||
kSemicolon,
|
||||
kw("overload"),
|
||||
kSemicolon,
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
_parameter_signature: ($) =>
|
||||
seq("(", optional(field("parameters", $.parameter_list)), ")"),
|
||||
seq("(", optional(field("parameters", $.parameters)), ")"),
|
||||
|
||||
parameter_list: ($) => sep1($.parameter, kSemicolon),
|
||||
parameters: ($) => sep1(field("parameter", $.parameter), kSemicolon),
|
||||
|
||||
parameter: ($) =>
|
||||
seq(
|
||||
optional(choice(kw("var"), kw("out"))),
|
||||
sep1(field("name", $.identifier), ","),
|
||||
optional(field("type", $._type_clause)),
|
||||
optional($._type_clause),
|
||||
optional(seq("=", field("default", $.expression))),
|
||||
),
|
||||
|
||||
@@ -1184,9 +1185,10 @@ module.exports = grammar({
|
||||
class_member: ($) =>
|
||||
choice(
|
||||
field("access_modifier", $.access_modifier),
|
||||
field("reference_modifier", $.reference_modifier),
|
||||
choice(
|
||||
$.variable_declaration,
|
||||
$.method_declaration,
|
||||
$._method_declaration,
|
||||
$.property_declaration,
|
||||
),
|
||||
$.uses_statement,
|
||||
@@ -1198,7 +1200,7 @@ module.exports = grammar({
|
||||
variable_declaration: ($) =>
|
||||
seq(
|
||||
optional($._reference_tag),
|
||||
field("variables", $.member_variable),
|
||||
field("variable", $.member_variable),
|
||||
kSemicolon,
|
||||
),
|
||||
|
||||
@@ -1207,13 +1209,15 @@ module.exports = grammar({
|
||||
|
||||
reference_modifier: (_) => choice(kw("weakref"), kw("autoref")),
|
||||
|
||||
member_variable: ($) =>
|
||||
choice($.static_declaration, $.nostatic_declaration),
|
||||
member_variable: ($) => choice($.static_member_variable, $.field_member_variable),
|
||||
|
||||
nostatic_declaration: ($) =>
|
||||
seq($._variable_declaration, optional($._type_clause)),
|
||||
static_member_variable: ($) =>
|
||||
seq(kw("static"), $._variable_declaration, optional($._type_clause), optional(seq("=", field("initial_value", $._right_hand_side)))),
|
||||
|
||||
method_declaration: ($) =>
|
||||
field_member_variable: ($) =>
|
||||
seq($._variable_declaration, optional($._type_clause), optional(seq("=", field("initial_value", $._right_hand_side)))),
|
||||
|
||||
_method_declaration: ($) =>
|
||||
choice(
|
||||
$.method_declaration_only,
|
||||
$.method_with_modifier,
|
||||
@@ -1239,7 +1243,7 @@ module.exports = grammar({
|
||||
kSemicolon,
|
||||
field("modifier", $.method_modifier),
|
||||
kSemicolon,
|
||||
optional(seq(field("body", $.block_statement), optional(kSemicolon))),
|
||||
optional(seq(field("body", $.block_suite), optional(kSemicolon))),
|
||||
),
|
||||
|
||||
method_with_implementation: ($) =>
|
||||
@@ -1250,13 +1254,13 @@ module.exports = grammar({
|
||||
$._parameter_signature,
|
||||
optional(field("return_type", $._type_clause)),
|
||||
optional(kSemicolon),
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
method_name: ($) =>
|
||||
choice(
|
||||
$._assignable_identifier,
|
||||
$._identifier_like,
|
||||
// $.identifier,
|
||||
$.operator_overload,
|
||||
),
|
||||
@@ -1279,35 +1283,35 @@ module.exports = grammar({
|
||||
kSemicolon,
|
||||
),
|
||||
|
||||
_property_index: ($) => seq(kw("index"), choice($.number, $.string)),
|
||||
_property_index: ($) => seq(kw("index"), field("index", choice($.number, $.string))),
|
||||
|
||||
property_accessors: ($) =>
|
||||
choice(
|
||||
$.read_only_accessor,
|
||||
$.write_only_accessor,
|
||||
$.read_write_accessor,
|
||||
$.write_read_accessor,
|
||||
$._read_only_accessor,
|
||||
$._write_only_accessor,
|
||||
$._read_write_accessor,
|
||||
$._write_read_accessor,
|
||||
),
|
||||
|
||||
read_only_accessor: ($) => seq(kw("read"), $.identifier),
|
||||
_read_only_accessor: ($) => seq(kw("read"), field("read", $.identifier)),
|
||||
|
||||
write_only_accessor: ($) => seq(kw("write"), $.identifier),
|
||||
_write_only_accessor: ($) => seq(kw("write"), field("write", $.identifier)),
|
||||
|
||||
read_write_accessor: ($) =>
|
||||
seq(kw("read"), $.identifier, kw("write"), $.identifier),
|
||||
_read_write_accessor: ($) =>
|
||||
seq(kw("read"), field("read", $.identifier), kw("write"), field("write", $.identifier)),
|
||||
|
||||
write_read_accessor: ($) =>
|
||||
seq(kw("write"), $.identifier, kw("read"), $.identifier),
|
||||
_write_read_accessor: ($) =>
|
||||
seq(kw("write"), field("write", $.identifier), kw("read"), field("read", $.identifier)),
|
||||
|
||||
// 类外方法实现
|
||||
external_method_statement: ($) =>
|
||||
choice($.modifier_method, $.operator_method, $.normal_method),
|
||||
choice($._modifier_method, $._operator_method, $._normal_method),
|
||||
|
||||
matrix_iteration_statement: ($) =>
|
||||
seq(
|
||||
field("target", $.expression),
|
||||
"::",
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
@@ -1364,7 +1368,7 @@ module.exports = grammar({
|
||||
html_comment: (_) =>
|
||||
token(seq("<!--", repeat(choice(/[^-]/, /-[^-]/, /--[^>]/)), "-->")),
|
||||
|
||||
modifier_method: ($) =>
|
||||
_modifier_method: ($) =>
|
||||
seq(
|
||||
kw("function"),
|
||||
$._qualified_method_name,
|
||||
@@ -1373,14 +1377,14 @@ module.exports = grammar({
|
||||
kSemicolon,
|
||||
field("modifier", $.method_modifier),
|
||||
kSemicolon,
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
operator_method: ($) =>
|
||||
_operator_method: ($) =>
|
||||
choice($._operator_method, $._operator_method_with_modifier),
|
||||
|
||||
normal_method: ($) =>
|
||||
_normal_method: ($) =>
|
||||
seq(
|
||||
optional($.class),
|
||||
kw("function"),
|
||||
@@ -1388,7 +1392,7 @@ module.exports = grammar({
|
||||
$._parameter_signature,
|
||||
optional(field("return_type", $._type_clause)),
|
||||
optional(kSemicolon),
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
@@ -1402,7 +1406,7 @@ module.exports = grammar({
|
||||
$._parameter_signature,
|
||||
optional(field("return_type", $._type_clause)),
|
||||
optional(kSemicolon),
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
@@ -1418,7 +1422,7 @@ module.exports = grammar({
|
||||
kSemicolon,
|
||||
field("modifier", $.method_modifier),
|
||||
kSemicolon,
|
||||
field("body", $.block_statement),
|
||||
field("body", $.block_suite),
|
||||
optional(kSemicolon),
|
||||
),
|
||||
|
||||
@@ -1444,16 +1448,16 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
interface_section: ($) =>
|
||||
seq(kw("interface"), optional(repeat($._statement))),
|
||||
seq(kw("interface"), repeat($._statement)),
|
||||
|
||||
implementation_section: ($) =>
|
||||
seq(kw("implementation"), optional(repeat($._statement))),
|
||||
seq(kw("implementation"), repeat($._statement)),
|
||||
|
||||
initialization_section: ($) =>
|
||||
seq(kw("initialization"), optional(repeat($._statement))),
|
||||
seq(kw("initialization"), repeat($._statement)),
|
||||
|
||||
finalization_section: ($) =>
|
||||
seq(kw("finalization"), optional(repeat($._statement))),
|
||||
seq(kw("finalization"), repeat($._statement)),
|
||||
|
||||
uses_statement: ($) =>
|
||||
seq(kw("uses"), sep1(field("module", $.identifier), ","), kSemicolon),
|
||||
|
||||
+760
-604
File diff suppressed because it is too large
Load Diff
+1109
-1753
File diff suppressed because it is too large
Load Diff
+166381
-146442
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user