大量更新,不想写更新日志
This commit is contained in:
@@ -39,6 +39,9 @@ namespace lsp::language::ast::detail
|
||||
registry.Register("class_definition_statement", ParseClassDefinition);
|
||||
registry.Register("external_method_statement", ParseExternalMethodStatement);
|
||||
registry.Register("matrix_iteration_statement", ParseMatrixIterationStatement);
|
||||
registry.Register("compiler_directive_statement", ParseCompilerDirectiveStatement);
|
||||
registry.Register("conditional_block_statement", ParseConditionalBlockStatement);
|
||||
registry.Register("conditional_directive_statement", ParseConditionalDirectiveStatement);
|
||||
|
||||
registry.Register("anonymous_function_statement",
|
||||
[](TSNode n, ParseContext& ctx) -> StatementPtr {
|
||||
@@ -880,6 +883,11 @@ namespace lsp::language::ast::detail
|
||||
if (!ts_node_is_null(value_node))
|
||||
arg.value = ParseExpression(value_node, ctx);
|
||||
}
|
||||
else if (child_node_type == "asterisk_argument")
|
||||
{
|
||||
arg.name = "*";
|
||||
arg.location = ts::NodeLocation(child);
|
||||
}
|
||||
arguments.push_back(std::move(arg));
|
||||
}
|
||||
expr->callee = std::move(callee);
|
||||
@@ -1779,6 +1787,91 @@ namespace lsp::language::ast::detail
|
||||
return stmt;
|
||||
}
|
||||
|
||||
StatementPtr ParseCompilerDirectiveStatement(TSNode node, ParseContext& ctx)
|
||||
{
|
||||
TSNode name_node = ts_node_child_by_field_name(node, "name", 4);
|
||||
TSNode switch_node = ts_node_child_by_field_name(node, "switch", 6);
|
||||
|
||||
auto stmt = MakeNode<CompilerDirectiveStatement>();
|
||||
stmt->kind = NodeKind::kCompilerDirectiveStatement;
|
||||
stmt->span = ts::NodeLocation(node);
|
||||
|
||||
if (!ts_node_is_null(name_node))
|
||||
{
|
||||
stmt->name = ts::Text(name_node, ctx.Source());
|
||||
stmt->location = ts::NodeLocation(name_node);
|
||||
}
|
||||
|
||||
if (!ts_node_is_null(switch_node))
|
||||
stmt->switch_value = ts::Text(switch_node, ctx.Source());
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
StatementPtr ParseConditionalDirectiveStatement(TSNode node, ParseContext& ctx)
|
||||
{
|
||||
auto stmt = MakeNode<ConditionalDirectiveStatement>();
|
||||
stmt->kind = NodeKind::kConditionalDirectiveStatement;
|
||||
stmt->span = ts::NodeLocation(node);
|
||||
|
||||
TSNode def_node = ts_node_child(node, 1);
|
||||
if (!ts_node_is_null(def_node))
|
||||
{
|
||||
std::string def_text = utils::ToLower(ts::Text(def_node, ctx.Source()));
|
||||
if (def_text == "define")
|
||||
stmt->type = ConditionalCompilationType::kDef;
|
||||
else
|
||||
stmt->type = ConditionalCompilationType::kUndef;
|
||||
}
|
||||
|
||||
TSNode name_node = ts_node_child_by_field_name(node, "name", 4);
|
||||
if (!ts_node_is_null(name_node))
|
||||
{
|
||||
stmt->name = ts::Text(name_node, ctx.Source());
|
||||
stmt->location = ts::NodeLocation(name_node);
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
|
||||
StatementPtr ParseConditionalBlockStatement(TSNode node, ParseContext& ctx)
|
||||
{
|
||||
auto stmt = MakeNode<ConditionalBlockStatement>();
|
||||
stmt->kind = NodeKind::kConditionalBlockStatement;
|
||||
stmt->span = ts::NodeLocation(node);
|
||||
|
||||
TSNode name_node = ts_node_child_by_field_name(node, "name", 4);
|
||||
if (!ts_node_is_null(name_node))
|
||||
{
|
||||
stmt->name = ts::Text(name_node, ctx.Source());
|
||||
stmt->location = ts::NodeLocation(name_node);
|
||||
}
|
||||
|
||||
// 解析consequence语句块
|
||||
uint32_t count = ts_node_child_count(node);
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
const char* field = ts_node_field_name_for_child(node, i);
|
||||
if (!field)
|
||||
continue;
|
||||
if (std::string_view(field) == "consequence")
|
||||
{
|
||||
TSNode child = ts_node_child(node, i);
|
||||
auto child_stmt = ParseStatement(child, ctx);
|
||||
if (child_stmt)
|
||||
stmt->consequence.push_back(std::move(child_stmt));
|
||||
}
|
||||
if (std::string_view(field) == "alternative")
|
||||
{
|
||||
TSNode child = ts_node_child(node, i);
|
||||
auto child_stmt = ParseStatement(child, ctx);
|
||||
if (child_stmt)
|
||||
stmt->alternative.push_back(std::move(child_stmt));
|
||||
}
|
||||
}
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
// ===== TSLX 模板解析 =====
|
||||
|
||||
StatementPtr ParseTSLXOpenTag(TSNode node, [[maybe_unused]] ParseContext& ctx)
|
||||
|
||||
@@ -190,6 +190,9 @@ namespace lsp::language::ast::detail
|
||||
StatementPtr ParseClassDefinition(TSNode node, ParseContext& ctx);
|
||||
StatementPtr ParseExternalMethodStatement(TSNode node, ParseContext& ctx);
|
||||
StatementPtr ParseMatrixIterationStatement(TSNode node, ParseContext& ctx);
|
||||
StatementPtr ParseCompilerDirectiveStatement(TSNode node, ParseContext& ctx);
|
||||
StatementPtr ParseConditionalBlockStatement(TSNode node, ParseContext& ctx);
|
||||
StatementPtr ParseConditionalDirectiveStatement(TSNode node, ParseContext& ctx);
|
||||
|
||||
// ===== TSLX 模板解析 =====
|
||||
StatementPtr ParseTSLXOpenTag(TSNode node, ParseContext& ctx);
|
||||
|
||||
@@ -93,6 +93,10 @@ namespace lsp::language::ast
|
||||
kClassMember,
|
||||
|
||||
kMatrixIterationStatement,
|
||||
|
||||
kCompilerDirectiveStatement,
|
||||
kConditionalBlockStatement,
|
||||
kConditionalDirectiveStatement,
|
||||
};
|
||||
|
||||
// ===== 枚举类型 =====
|
||||
@@ -245,6 +249,14 @@ namespace lsp::language::ast
|
||||
kInsert
|
||||
};
|
||||
|
||||
enum class ConditionalCompilationType
|
||||
{
|
||||
kIfDef,
|
||||
kIfNDef,
|
||||
kUndef,
|
||||
kDef,
|
||||
};
|
||||
|
||||
// ===== 前向声明 =====
|
||||
class ASTNode;
|
||||
class Program;
|
||||
@@ -303,6 +315,9 @@ namespace lsp::language::ast
|
||||
class UnitDefinition;
|
||||
class TSSQLExpression;
|
||||
class MatrixIterationStatement;
|
||||
class CompilerDirectiveStatement;
|
||||
class ConditionalBlockStatement;
|
||||
class ConditionalDirectiveStatement;
|
||||
|
||||
using ASTNodePtr = std::unique_ptr<ASTNode>;
|
||||
using ExpressionPtr = std::unique_ptr<Expression>;
|
||||
@@ -366,6 +381,9 @@ namespace lsp::language::ast
|
||||
virtual void VisitTSSQLExpression(TSSQLExpression& node) = 0;
|
||||
virtual void VisitUnpackPattern(UnpackPattern& node) = 0;
|
||||
virtual void VisitMatrixIterationStatement(MatrixIterationStatement& node) = 0;
|
||||
virtual void VisitCompilerDirectiveStatement(CompilerDirectiveStatement& node) = 0;
|
||||
virtual void VisitConditionalBlockStatement(ConditionalBlockStatement& node) = 0;
|
||||
virtual void VisitConditionalDirectiveStatement(ConditionalDirectiveStatement& node) = 0;
|
||||
};
|
||||
|
||||
struct TypeAnnotation
|
||||
@@ -1074,6 +1092,44 @@ namespace lsp::language::ast
|
||||
std::vector<StatementPtr> statements;
|
||||
};
|
||||
|
||||
class CompilerDirectiveStatement : public Statement
|
||||
{
|
||||
public:
|
||||
CompilerDirectiveStatement() { kind = NodeKind::kCompilerDirectiveStatement; }
|
||||
void Accept(ASTVisitor& visitor) override { visitor.VisitCompilerDirectiveStatement(*this); }
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
Location location;
|
||||
std::optional<std::string> switch_value; // "+" or "-"
|
||||
};
|
||||
|
||||
class ConditionalBlockStatement : public Statement
|
||||
{
|
||||
public:
|
||||
ConditionalBlockStatement() { kind = NodeKind::kConditionalBlockStatement; }
|
||||
void Accept(ASTVisitor& visitor) override { visitor.VisitConditionalBlockStatement(*this); }
|
||||
|
||||
public:
|
||||
ConditionalCompilationType type;
|
||||
std::string name;
|
||||
Location location;
|
||||
std::vector<StatementPtr> consequence;
|
||||
std::vector<StatementPtr> alternative;
|
||||
};
|
||||
|
||||
class ConditionalDirectiveStatement : public Statement
|
||||
{
|
||||
public:
|
||||
ConditionalDirectiveStatement() { kind = NodeKind::kConditionalDirectiveStatement; }
|
||||
void Accept(ASTVisitor& visitor) override { visitor.VisitConditionalDirectiveStatement(*this); }
|
||||
|
||||
public:
|
||||
ConditionalCompilationType type;
|
||||
std::string name;
|
||||
Location location;
|
||||
};
|
||||
|
||||
template<typename T, typename... Args>
|
||||
std::unique_ptr<T> MakeNode(Args&&... args)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace lsp::language::symbol
|
||||
{
|
||||
Builder::Builder(SymbolTable& table) : table_(table), current_scope_id_(kInvalidScopeId)
|
||||
Builder::Builder(SymbolTable& table) :
|
||||
table_(table), current_scope_id_(kInvalidScopeId)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,7 +28,7 @@ namespace lsp::language::symbol
|
||||
root.Accept(*this);
|
||||
}
|
||||
|
||||
SymbolId Builder::CreateSymbol(const std::string& name, SymbolKind kind, const ast::ASTNode& node, const std::optional<std::string>& type_hint)
|
||||
SymbolId Builder::CreateSymbol(const std::string& name, SymbolKind kind, const ast::ASTNode& node, const std::optional<std::string>& type_hint, bool is_class_method)
|
||||
{
|
||||
return table_.CreateSymbol(
|
||||
name,
|
||||
@@ -35,7 +36,8 @@ namespace lsp::language::symbol
|
||||
node.span,
|
||||
current_scope_id_,
|
||||
current_parent_symbol_id_,
|
||||
type_hint);
|
||||
type_hint,
|
||||
is_class_method);
|
||||
}
|
||||
|
||||
ScopeId Builder::EnterScopeWithSymbol(ScopeKind kind, SymbolId symbol_id, const ast::Location& range)
|
||||
@@ -189,7 +191,10 @@ namespace lsp::language::symbol
|
||||
|
||||
EnterScopeWithSymbol(ScopeKind::Function, symbol_id, node.span);
|
||||
auto prev_function = current_function_id_;
|
||||
auto prev_parent = current_parent_symbol_id_;
|
||||
|
||||
current_function_id_ = symbol_id;
|
||||
current_parent_symbol_id_ = symbol_id;
|
||||
|
||||
// 添加参数
|
||||
for (const auto& param : node.signature.parameters)
|
||||
@@ -200,6 +205,8 @@ namespace lsp::language::symbol
|
||||
CreateSymbol(param.name, SymbolKind::Variable, node, type_hint);
|
||||
}
|
||||
|
||||
current_parent_symbol_id_ = prev_parent;
|
||||
|
||||
if (node.body)
|
||||
node.body->Accept(*this);
|
||||
|
||||
@@ -220,7 +227,7 @@ namespace lsp::language::symbol
|
||||
{
|
||||
SymbolKind kind = node.method_type == ast::MethodType::kConstructor ? SymbolKind::Constructor : SymbolKind::Method;
|
||||
|
||||
auto symbol_id = CreateSymbol(node.name, kind, node);
|
||||
auto symbol_id = CreateSymbol(node.name, kind, node, "", node.is_class_method);
|
||||
|
||||
table_.GetDefinitionStore().Update(symbol_id, [&](SymbolDefinition& def) {
|
||||
def.detail = FormatSignature(node.signature);
|
||||
@@ -229,6 +236,8 @@ namespace lsp::language::symbol
|
||||
|
||||
EnterScopeWithSymbol(ScopeKind::Function, symbol_id, node.span);
|
||||
auto prev_function = current_function_id_;
|
||||
auto prev_parent = current_parent_symbol_id_;
|
||||
|
||||
current_function_id_ = symbol_id;
|
||||
|
||||
for (const auto& param : node.signature.parameters)
|
||||
@@ -236,12 +245,15 @@ namespace lsp::language::symbol
|
||||
std::optional<std::string> type_hint;
|
||||
if (param.type)
|
||||
type_hint = param.type->name;
|
||||
auto param_prev = current_parent_symbol_id_;
|
||||
current_parent_symbol_id_ = symbol_id;
|
||||
CreateSymbol(param.name, SymbolKind::Variable, node, type_hint);
|
||||
current_parent_symbol_id_ = param_prev;
|
||||
}
|
||||
|
||||
if (node.body)
|
||||
node.body->Accept(*this);
|
||||
|
||||
current_parent_symbol_id_ = prev_parent;
|
||||
current_function_id_ = prev_function;
|
||||
ExitScope();
|
||||
}
|
||||
@@ -255,7 +267,7 @@ namespace lsp::language::symbol
|
||||
{
|
||||
SymbolKind kind = node.method_type == ast::MethodType::kConstructor ? SymbolKind::Constructor : SymbolKind::Method;
|
||||
|
||||
auto symbol_id = CreateSymbol(node.name, kind, node);
|
||||
auto symbol_id = CreateSymbol(node.name, kind, node, std::nullopt, node.is_class_method);
|
||||
|
||||
table_.GetDefinitionStore().Update(symbol_id, [&](SymbolDefinition& def) {
|
||||
def.detail = FormatSignature(node.signature);
|
||||
@@ -264,6 +276,8 @@ namespace lsp::language::symbol
|
||||
|
||||
EnterScopeWithSymbol(ScopeKind::Function, symbol_id, node.span);
|
||||
auto prev_function = current_function_id_;
|
||||
auto prev_parent = current_parent_symbol_id_;
|
||||
|
||||
current_function_id_ = symbol_id;
|
||||
|
||||
for (const auto& param : node.signature.parameters)
|
||||
@@ -271,12 +285,16 @@ namespace lsp::language::symbol
|
||||
std::optional<std::string> type_hint;
|
||||
if (param.type)
|
||||
type_hint = param.type->name;
|
||||
auto param_prev = current_parent_symbol_id_;
|
||||
current_parent_symbol_id_ = symbol_id;
|
||||
CreateSymbol(param.name, SymbolKind::Variable, node, type_hint);
|
||||
current_parent_symbol_id_ = param_prev;
|
||||
}
|
||||
|
||||
if (node.body)
|
||||
node.body->Accept(*this);
|
||||
|
||||
current_parent_symbol_id_ = prev_parent;
|
||||
current_function_id_ = prev_function;
|
||||
ExitScope();
|
||||
}
|
||||
@@ -286,7 +304,8 @@ namespace lsp::language::symbol
|
||||
std::visit([this](auto& member_ptr) {
|
||||
if (member_ptr)
|
||||
member_ptr->Accept(*this);
|
||||
}, node.member);
|
||||
},
|
||||
node.member);
|
||||
}
|
||||
|
||||
void Builder::VisitVarStatement(ast::VarStatement& node)
|
||||
@@ -659,4 +678,33 @@ namespace lsp::language::symbol
|
||||
ExitScope();
|
||||
}
|
||||
|
||||
void Builder::VisitCompilerDirectiveStatement(ast::CompilerDirectiveStatement& node)
|
||||
{
|
||||
// 当前阶段:不处理
|
||||
// 未来可以在这里维护宏定义状态
|
||||
}
|
||||
|
||||
void Builder::VisitConditionalDirectiveStatement(ast::ConditionalDirectiveStatement& node)
|
||||
{
|
||||
// 当前阶段:不处理
|
||||
// 条件指令本身不影响符号收集
|
||||
}
|
||||
|
||||
void Builder::VisitConditionalBlockStatement(ast::ConditionalBlockStatement& node)
|
||||
{
|
||||
// 处理所有分支,不管条件是否满足
|
||||
|
||||
// 处理 THEN 分支 (consequence)
|
||||
if (!node.consequence.empty())
|
||||
{
|
||||
VisitStatements(node.consequence);
|
||||
}
|
||||
|
||||
// 处理 ELSE 分支 (alternative)
|
||||
if (!node.alternative.empty())
|
||||
{
|
||||
VisitStatements(node.alternative);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -70,9 +70,12 @@ namespace lsp::language::symbol
|
||||
void VisitTSSQLExpression(ast::TSSQLExpression&) override {}
|
||||
void VisitUnpackPattern(ast::UnpackPattern&) override {}
|
||||
void VisitMatrixIterationStatement(ast::MatrixIterationStatement& node) override;
|
||||
void VisitCompilerDirectiveStatement(ast::CompilerDirectiveStatement& node) override;
|
||||
void VisitConditionalDirectiveStatement(ast::ConditionalDirectiveStatement& node) override;
|
||||
void VisitConditionalBlockStatement(ast::ConditionalBlockStatement& node) override;
|
||||
|
||||
private:
|
||||
SymbolId CreateSymbol(const std::string& name, SymbolKind kind, const ast::ASTNode& node, const std::optional<std::string>& type_hint = std::nullopt);
|
||||
SymbolId CreateSymbol(const std::string& name, SymbolKind kind, const ast::ASTNode& node, const std::optional<std::string>& type_hint = std::nullopt, bool is_class_method = false);
|
||||
ScopeId EnterScopeWithSymbol(ScopeKind kind, SymbolId symbol_id, const ast::Location& range);
|
||||
ScopeId EnterScope(ScopeKind kind, const ast::Location& range);
|
||||
|
||||
|
||||
@@ -197,7 +197,8 @@ namespace lsp::language::symbol
|
||||
const ast::Location& location,
|
||||
ScopeId scope_id,
|
||||
std::optional<SymbolId> parent_id,
|
||||
const std::optional<std::string>& type_hint)
|
||||
const std::optional<std::string>& type_hint,
|
||||
bool is_class_method)
|
||||
{
|
||||
// 创建符号定义
|
||||
SymbolDefinition def;
|
||||
@@ -207,6 +208,7 @@ namespace lsp::language::symbol
|
||||
def.selection_range = location;
|
||||
def.type_hint = type_hint;
|
||||
def.parent_id = parent_id;
|
||||
def.is_class_method = is_class_method;
|
||||
|
||||
SymbolId symbol_id = definition_store_.Add(std::move(def));
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ namespace lsp::language::symbol
|
||||
const ast::Location& location,
|
||||
ScopeId scope_id,
|
||||
std::optional<SymbolId> parent_id = std::nullopt,
|
||||
const std::optional<std::string>& type_hint = std::nullopt);
|
||||
const std::optional<std::string>& type_hint = std::nullopt,
|
||||
bool is_class_method = false);
|
||||
|
||||
// 创建作用域(可以选择关联符号)
|
||||
ScopeId CreateScope(
|
||||
|
||||
@@ -5,39 +5,11 @@
|
||||
#include <unordered_map>
|
||||
#include "../ast/types.hpp"
|
||||
#include "../../utils/string.hpp"
|
||||
#include "../../protocol/protocol.hpp"
|
||||
|
||||
namespace lsp::language::symbol
|
||||
{
|
||||
enum class SymbolKind
|
||||
{
|
||||
File = 1,
|
||||
Module = 2,
|
||||
Namespace = 3,
|
||||
Package = 4,
|
||||
Class = 5,
|
||||
Method = 6,
|
||||
Property = 7,
|
||||
Field = 8,
|
||||
Constructor = 9,
|
||||
Enum = 10,
|
||||
Interface = 11,
|
||||
Function = 12,
|
||||
Variable = 13,
|
||||
Constant = 14,
|
||||
String = 15,
|
||||
Number = 16,
|
||||
Boolean = 17,
|
||||
Array = 18,
|
||||
Object = 19,
|
||||
Key = 20,
|
||||
Null = 21,
|
||||
EnumMember = 22,
|
||||
Struct = 23,
|
||||
Event = 24,
|
||||
Operator = 25,
|
||||
TypeParameter = 26
|
||||
};
|
||||
|
||||
using SymbolKind = protocol::SymbolKind;
|
||||
enum class ScopeKind
|
||||
{
|
||||
Global,
|
||||
@@ -75,6 +47,7 @@ namespace lsp::language::symbol
|
||||
std::optional<ast::AccessModifier> access_modifier;
|
||||
std::optional<ast::MethodModifier> method_modifier;
|
||||
std::optional<ast::ReferenceModifier> reference_modifier;
|
||||
bool is_class_method = false;
|
||||
|
||||
std::optional<SymbolId> parent_id;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user