支持全局函数补全

This commit is contained in:
csh
2025-09-27 22:23:04 +08:00
parent aac12137cb
commit dc713e6893
220 changed files with 195514 additions and 195869 deletions
+297
View File
@@ -0,0 +1,297 @@
#include "./keyword_manager.hpp"
namespace tsl
{
KeywordManager& KeywordManager::GetInstance()
{
static KeywordManager instance;
return instance;
}
KeywordManager::KeywordManager()
{
InitKeywords();
}
std::vector<KeywordInfo> KeywordManager::GetAllKeywords()
{
std::vector<KeywordInfo> keyword;
keyword.reserve(keywords_.size());
for (const auto& [key, value] : keywords_)
keyword.push_back(value);
return keyword;
}
std::vector<KeywordInfo> KeywordManager::GetKeyWordByPrefix(std::string prefix)
{
std::vector<KeywordInfo> keyword;
for (const auto& [key, value] : keywords_)
{
if (key.starts_with(prefix))
keyword.push_back(value);
}
return keyword;
}
std::optional<KeywordInfo> KeywordManager::GetKeywordInfo(std::string key)
{
auto target = keywords_.find(key);
if (target == keywords_.end())
return std::nullopt;
return target->second;
}
void KeywordManager::InitKeywords()
{
keywords_.reserve(200);
InitProgramStructureKeywords();
InitDataTypeKeywords();
InitClassKeywords();
InitControlFlowKeywords();
InitOperatorKeywords();
InitSqlKeywords();
InitBuiltinKeywords();
InitConstantKeywords();
}
void KeywordManager::InitProgramStructureKeywords()
{
keywords_["program"] = {
"program",
KeywordCategory::kProgramStructure,
"## Program\n\n程序开始的入口,一般用户不需要使用,在作为独立的TSL脚本时可以使用。 \n通常来说,倘若编写TSL代码作为CGI执行运行,系统默认以PROGRAM模式运行。虽然TSL可以省略PROGRAM关键字,但是使用PROGRAM关键字可以使得TSL代码里包含子函数.\n\n**例如:**\n```pascal\nprogram Test;\n\tfunction sub1();\n\tbegin\n\t\twriteln('Execute sub1');\n\tend;\nbegin\n\tsub1();\nend.\n```"
};
keywords_["function"] = {
"function",
KeywordCategory::kProgramStructure,
"## Function\n\n函数声明开始,组成类似于FUNCTION XXXX(); BEGIN END;的函数块"
};
keywords_["procedure"] = {
"procedure",
KeywordCategory::kProgramStructure,
"## Procedure\n\n与FUNCTION类似,但是在函数头后不允许加返回类型值"
};
keywords_["unit"] = {
"unit",
KeywordCategory::kProgramStructure,
"## Unit Declaration\n\nDeclares a code unit/module.\n\n**Syntax:**\n```pascal\nunit UnitName;\ninterface\n // public declarations\nimplementation\n // private implementation\nend.\n```"
};
keywords_["uses"] = {
"uses",
KeywordCategory::kProgramStructure,
"## Uses Clause\n\nImports external units/modules.\n\n**Syntax:**\n```pascal\nuses Unit1, Unit2, Unit3;\n```\n\n**Example:**\n```pascal\nuses System, SysUtils, Classes;\n```"
};
keywords_["implementation"] = {
"implementation",
KeywordCategory::kProgramStructure,
"## Implementation Section\n\nMarks the beginning of the private implementation section in a unit.\n\n**Usage:**\n```pascal\nunit MyUnit;\ninterface\n // public interface\nimplementation\n // private implementation\nend.\n```"
};
keywords_["interface"] = {
"interface",
KeywordCategory::kProgramStructure,
"## Interface Section\n\nMarks the public interface section in a unit.\n\n**Usage:**\n```pascal\nunit MyUnit;\ninterface\n // public declarations\n function PublicFunction: integer;\nimplementation\nend.\n```"
};
keywords_["initialization"] = {
"initialization",
KeywordCategory::kProgramStructure,
"## Initialization Section\n\nCode executed when the unit is first loaded.\n\n**Usage:**\n```pascal\nunit MyUnit;\ninterface\nimplementation\ninitialization\n // initialization code\nend.\n```"
};
keywords_["finalization"] = {
"finalization",
KeywordCategory::kProgramStructure,
"## Finalization Section\n\nCode executed when the program terminates.\n\n**Usage:**\n```pascal\nunit MyUnit;\ninterface\nimplementation\ninitialization\n // setup code\nfinalization\n // cleanup code\nend.\n```"
};
}
void KeywordManager::InitDataTypeKeywords()
{
keywords_["string"] = {
"string",
KeywordCategory::kDataTypes,
"## String Type\n\nVariable-length string data type.\n\n**Example:**\n```pascal\nvar\n myString: string;\nbegin\n myString := 'Hello World';\nend;\n```\n\n**Note:** Supports Unicode and automatic memory management."
};
keywords_["integer"] = {
"integer",
KeywordCategory::kDataTypes,
"## Integer Type\n\n32-bit signed integer data type.\n\n**Range:** -2,147,483,648 to 2,147,483,647\n\n**Example:**\n```pascal\nvar\n count: integer;\nbegin\n count := 42;\nend;\n```"
};
keywords_["boolean"] = {
"boolean",
KeywordCategory::kDataTypes,
"## Boolean Type\n\nLogical data type with values `true` or `false`.\n\n**Example:**\n```pascal\nvar\n isValid: boolean;\nbegin\n isValid := true;\n if isValid then\n echo('Valid!');\nend;\n```"
};
keywords_["int64"] = {
"int64",
KeywordCategory::kDataTypes,
"## Int64 Type\n\n64-bit signed integer data type.\n\n**Range:** -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807\n\n**Example:**\n```pascal\nvar\n bigNumber: int64;\nbegin\n bigNumber := 1234567890123456789;\nend;\n```"
};
keywords_["real"] = {
"real",
KeywordCategory::kDataTypes,
"## Real Type\n\nFloating-point number data type.\n\n**Example:**\n```pascal\nvar\n price: real;\nbegin\n price := 19.99;\nend;\n```"
};
keywords_["array"] = {
"array",
KeywordCategory::kDataTypes,
"## Array Type\n\nCollection of elements of the same type.\n\n**Syntax:**\n```pascal\narray[IndexType] of ElementType\n```\n\n**Examples:**\n```pascal\nvar\n numbers: array[1..10] of integer;\n names: array of string; // dynamic array\nbegin\n numbers[1] := 42;\nend;\n```"
};
}
void KeywordManager::InitClassKeywords()
{
keywords_["type"] = {
"type",
KeywordCategory::kClassTypes,
"## Type Declaration\n\nDeclares custom data types.\n\n**Syntax:**\n```pascal\ntype\n TypeName = TypeDefinition;\n```\n\n**Example:**\n```pascal\ntype\n TPoint = record\n X, Y: integer;\n end;\n \n TMyClass = class\n // class members\n end;\n```"
};
keywords_["class"] = {
"class",
KeywordCategory::kClassTypes,
"## Class Declaration\n\nDeclares an object-oriented class.\n\n**Syntax:**\n```pascal\ntype\n TClassName = class(TBaseClass)\n private\n // private members\n public\n // public members\n end;\n```\n\n**Example:**\n```pascal\ntype\n TPerson = class\n private\n FName: string;\n public\n constructor Create(AName: string);\n property Name: string read FName write FName;\n end;\n```"
};
keywords_["new"] = {
"new",
KeywordCategory::kClassTypes,
"## New Instance\n\nCreates a new instance of a class.\n\n**Syntax:**\n```pascal\nInstanceVar := ClassName.Create();\n```\n\n**Example:**\n```pascal\nvar\n person: TPerson;\nbegin\n person := TPerson.Create('John');\n try\n // use person\n finally\n person.Free;\n end;\nend;\n```"
};
}
void KeywordManager::InitControlFlowKeywords()
{
keywords_["if"] = {
"if",
KeywordCategory::kConditionals,
"## If Statement\n\nConditional execution based on a boolean expression.\n\n**Syntax:**\n```pascal\nif condition then\n statement\nelse\n statement;\n```\n\n**Example:**\n```pascal\nif age >= 18 then\n echo('Adult')\nelse\n echo('Minor');\n```\n\n**Multi-line:**\n```pascal\nif score >= 90 then\nbegin\n grade := 'A';\n echo('Excellent!');\nend;\n```"
};
keywords_["for"] = {
"for",
KeywordCategory::kLoops,
"## For Loop\n\nIterates over a range of values.\n\n**Syntax:**\n```pascal\nfor variable := startValue to endValue do\n statement;\n \nfor variable := startValue downto endValue do\n statement;\n```\n\n**Examples:**\n```pascal\n// Forward loop\nfor i := 1 to 10 do\n echo(i);\n \n// Reverse loop\nfor i := 10 downto 1 do\n echo(i);\n \n// Array iteration\nfor i := Low(myArray) to High(myArray) do\n echo(myArray[i]);\n```"
};
keywords_["while"] = {
"while",
KeywordCategory::kLoops,
"## While Loop\n\nRepeats while a condition is true.\n\n**Syntax:**\n```pascal\nwhile condition do\n statement;\n```\n\n**Example:**\n```pascal\ni := 0;\nwhile i < 10 do\nbegin\n echo(i);\n i := i + 1;\nend;\n```\n\n**Note:** The condition is checked before each iteration."
};
keywords_["case"] = {
"case",
KeywordCategory::kConditionals,
"## Case Statement\n\nMulti-way conditional based on value matching.\n\n**Syntax:**\n```pascal\ncase expression of\n value1: statement1;\n value2: statement2;\n else\n defaultStatement;\nend;\n```\n\n**Example:**\n```pascal\ncase dayOfWeek of\n 1: echo('Monday');\n 2: echo('Tuesday');\n 3: echo('Wednesday');\n 4: echo('Thursday');\n 5: echo('Friday');\n 6, 7: echo('Weekend');\n else\n echo('Invalid day');\nend;\n```"
};
}
void KeywordManager::InitOperatorKeywords()
{
keywords_["and"] = {
"and",
KeywordCategory::kLogicalOperators,
"## Logical AND\n\nLogical conjunction operator.\n\n**Truth Table:**\n| A | B | A and B |\n|---|---|--------|\n| T | T | T |\n| T | F | F |\n| F | T | F |\n| F | F | F |\n\n**Example:**\n```pascal\nif (age >= 18) and (hasLicense) then\n echo('Can drive');\n```"
};
keywords_["or"] = {
"or",
KeywordCategory::kLogicalOperators,
"## Logical OR\n\nLogical disjunction operator.\n\n**Truth Table:**\n| A | B | A or B |\n|---|---|-------|\n| T | T | T |\n| T | F | T |\n| F | T | T |\n| F | F | F |\n\n**Example:**\n```pascal\nif (isAdmin) or (isOwner) then\n echo('Has permission');\n```"
};
keywords_["div"] = {
"div",
KeywordCategory::kArithmeticOperators,
"## Integer Division\n\nPerforms integer division (truncates decimal part).\n\n**Example:**\n```pascal\nvar result: integer;\nbegin\n result := 17 div 5; // result = 3\n result := 20 div 4; // result = 5\nend;\n```\n\n**Note:** Use `/` for real division, `div` for integer division."
};
keywords_["mod"] = {
"mod",
KeywordCategory::kArithmeticOperators,
"## Modulo Operator\n\nReturns the remainder of integer division.\n\n**Example:**\n```pascal\nvar remainder: integer;\nbegin\n remainder := 17 mod 5; // remainder = 2\n remainder := 20 mod 4; // remainder = 0\n \n // Check if number is even\n if (number mod 2) = 0 then\n echo('Even number');\nend;\n```"
};
}
void KeywordManager::InitSqlKeywords()
{
keywords_["select"] = {
"select",
KeywordCategory::kSqlControl,
"## SQL SELECT Statement\n\nRetrieves data from database tables.\n\n**Syntax:**\n```sql\nSELECT column1, column2, ...\nFROM table_name\nWHERE condition\nORDER BY column;\n```\n\n**Examples:**\n```sql\n-- Basic select\nSELECT name, age FROM users;\n\n-- With condition\nSELECT * FROM products WHERE price > 100;\n\n-- With ordering\nSELECT name, salary FROM employees ORDER BY salary DESC;\n```"
};
keywords_["update"] = {
"update",
KeywordCategory::kSqlControl,
"## SQL UPDATE Statement\n\nModifies existing records in a table.\n\n**Syntax:**\n```sql\nUPDATE table_name\nSET column1 = value1, column2 = value2, ...\nWHERE condition;\n```\n\n**Examples:**\n```sql\n-- Update single record\nUPDATE users SET age = 30 WHERE id = 1;\n\n-- Update multiple columns\nUPDATE products \nSET price = 99.99, category = 'Electronics'\nWHERE id = 100;\n```\n\n**⚠️ Warning:** Always use WHERE clause to avoid updating all records!"
};
}
void KeywordManager::InitBuiltinKeywords()
{
keywords_["echo"] = {
"echo",
KeywordCategory::kBuiltinFunctions,
"## Echo Function\n\nOutputs text to the console or output stream.\n\n**Syntax:**\n```pascal\necho(expression);\necho(format, args...);\n```\n\n**Examples:**\n```pascal\necho('Hello World!');\necho('Number: ', 42);\necho('Name: %s, Age: %d', name, age);\n```\n\n**Features:**\n- Supports multiple arguments\n- Automatic type conversion\n- Format string support"
};
keywords_["mtic"] = {
"mtic",
KeywordCategory::kBuiltinFunctions,
"## Timer Start (mtic)\n\nStarts a high-precision timer for performance measurement.\n\n**Usage:**\n```pascal\nmtic(); // Start timer\n// ... code to measure ...\nvar elapsed := mtoc(); // Get elapsed time\necho('Elapsed: ', elapsed, ' seconds');\n```\n\n**Note:** Use with `mtoc()` to measure execution time."
};
keywords_["mtoc"] = {
"mtoc",
KeywordCategory::kBuiltinFunctions,
"## Timer End (mtoc)\n\nReturns elapsed time since last `mtic()` call.\n\n**Returns:** Time in seconds (real number)\n\n**Example:**\n```pascal\nmtic();\nfor i := 1 to 1000000 do\n // some computation\nvar timeElapsed := mtoc();\necho('Loop took: ', timeElapsed, ' seconds');\n```"
};
}
void KeywordManager::InitConstantKeywords()
{
keywords_["true"] = {
"true",
KeywordCategory::kBooleanConstants,
"## Boolean True\n\nRepresents the boolean value **true**.\n\n**Usage:**\n```pascal\nvar\n flag: boolean;\nbegin\n flag := true;\n \n if flag then\n echo('Flag is set!');\nend;\n```\n\n**Note:** Case-insensitive in most Pascal dialects."
};
keywords_["false"] = {
"false",
KeywordCategory::kBooleanConstants,
"## Boolean False\n\nRepresents the boolean value **false**.\n\n**Usage:**\n```pascal\nvar\n isComplete: boolean;\nbegin\n isComplete := false;\n \n while not isComplete do\n begin\n // do work\n isComplete := checkCompletion();\n end;\nend;\n```"
};
keywords_["nil"] = {
"nil",
KeywordCategory::kNullConstants,
"## Nil Constant\n\nRepresents a null/empty pointer or object reference.\n\n**Usage:**\n```pascal\nvar\n obj: TMyClass;\nbegin\n obj := nil; // Initialize to null\n \n if obj <> nil then\n obj.DoSomething();\n \n obj := TMyClass.Create();\n try\n // use obj\n finally\n obj.Free;\n obj := nil; // Clear reference\n end;\nend;\n```\n\n**Best Practice:** Always check for nil before using object references."
};
keywords_["inf"] = {
"inf",
KeywordCategory::kMathConstants,
"## Infinity Constant\n\nRepresents positive mathematical infinity.\n\n**Usage:**\n```pascal\nvar\n result: real;\nbegin\n result := 1.0 / 0.0; // Results in inf\n \n if result = inf then\n echo('Result is infinite');\nend;\n```\n\n**Note:** Use for floating-point calculations and comparisons."
};
keywords_["nan"] = {
"nan",
KeywordCategory::kMathConstants,
"## Not a Number (NaN)\n\nRepresents an undefined or invalid floating-point result.\n\n**Common Causes:**\n- `0.0 / 0.0`\n- `sqrt(-1.0)`\n- `inf - inf`\n\n**Usage:**\n```pascal\nvar\n result: real;\nbegin\n result := sqrt(-1.0); // Results in NaN\n \n if IsNaN(result) then\n echo('Invalid calculation');\nend;\n```\n\n**Note:** NaN ≠ NaN, use `IsNaN()` function for checking."
};
}
}
@@ -0,0 +1,35 @@
#pragma once
#include <optional>
#include <unordered_map>
#include <vector>
#include "./keyword_types.hpp"
namespace tsl
{
class KeywordManager
{
public:
KeywordManager(const KeywordManager&) = delete;
KeywordManager& operator=(const KeywordManager&) = delete;
static KeywordManager& GetInstance();
std::vector<KeywordInfo> GetAllKeywords();
std::vector<KeywordInfo> GetKeyWordByPrefix(std::string prefix);
std::optional<KeywordInfo> GetKeywordInfo(std::string key);
private:
KeywordManager();
void InitKeywords();
void InitProgramStructureKeywords();
void InitDataTypeKeywords();
void InitClassKeywords();
void InitControlFlowKeywords();
void InitOperatorKeywords();
void InitSqlKeywords();
void InitBuiltinKeywords();
void InitConstantKeywords();
std::unordered_map<std::string, KeywordInfo> keywords_;
};
}
@@ -1,71 +1,49 @@
#pragma once
#include <vector>
#include <string>
#include <unordered_set>
#include "../protocol/protocol.hpp"
namespace tsl
{
enum class KeywordCategory
{
kProgramStructure, // program, function, procedure, unit, uses, implementation, interface, initialization, finalization
kDataTypes, // string, integer, boolean, int64, real, array
kClassTypes, // type, class, fakeclass, new
kClassModifiers, // override, overload, virtual, property, self, inherited
kAccessModifiers, // public, protected, private, published
kPropertyAccessors, // read, write
kConstructors, // create, destroy, operator
kVariableModifiers, // external, const, out, var, global, static
kConditionals, // if, else, then, case, of
kLoops, // for, while, do, downto, step, until, repeat, to
kBranchControl, // break, continue, goto, label, exit
kReturnControl, // return, debugreturn, debugrunenv, debugrunenvdo
kBlockControl, // begin, end, with
kReferences, // weakref, autoref
kNamespace, // namespace
kExceptions, // except, raise, try, finally, exceptobject
kLogicalOperators, // and, in, is, not, or
kArithmeticOperators, // div, mod
kBitwiseOperators, // ror, rol, shr, shl
kSetOperators, // union, minus, union2
kSqlControl, // select, vselect, sselect, update, delete, mselect
kSqlOperators, // on, like, in (SQL context)
kSqlKeywords, // sqlin, from, where, group, by, order, distinct, join
kCallingConventions, // cdecl, pascal, stdcall, safecall, fastcall, register
kSystemKeywords, // setuid, sudo
kBuiltinVariables, // paramcount, realparamcount, params, system, tslassigning, likeeps, likeepsrate
kBuiltinFunctions, // echo, mtic, mtoc
kBooleanConstants, // false, true
kMathConstants, // inf, nan
kNullConstants // nil
};
// 关键字信息
struct KeywordInfo
{
std::string keyword;
KeywordCategory category;
std::string description;
lsp::protocol::CompletionItemKind completion_kind;
};
class TslKeywords
{
public:
static const std::vector<KeywordInfo>& GetAllKeywords();
static std::vector<KeywordInfo> GetKeywordsByCategory(KeywordCategory category);
static std::vector<lsp::protocol::CompletionItem> GetCompletionItems(const std::string& prefix = "");
static bool IsKeyword(const std::string& word);
static KeywordCategory GetKeywordCategory(const std::string& word);
private:
static void InitKeywords();
static std::string ToLowerCase(const std::string& str);
static bool StartsWith(const std::string& str, const std::string& prefix);
private:
static std::vector<KeywordInfo> keywords_;
static std::unordered_set<std::string> keyword_set_;
static bool initialized_;
};
}
#pragma once
#include <string>
#include <optional>
#include "../protocol/protocol.hpp"
namespace tsl
{
enum class KeywordCategory
{
kProgramStructure, // program, function, procedure, unit, uses, implementation, interface, initialization, finalization
kDataTypes, // string, integer, boolean, int64, real, array
kClassTypes, // type, class, fakeclass, new
kClassModifiers, // override, overload, virtual, property, self, inherited
kAccessModifiers, // public, protected, private, published
kPropertyAccessors, // read, write
kConstructors, // create, destroy, operator
kVariableModifiers, // external, const, out, var, global, static
kConditionals, // if, else, then, case, of
kLoops, // for, while, do, downto, step, until, repeat, to
kBranchControl, // break, continue, goto, label, exit
kReturnControl, // return, debugreturn, debugrunenv, debugrunenvdo
kBlockControl, // begin, end, with
kReferences, // weakref, autoref
kNamespace, // namespace
kExceptions, // except, raise, try, finally, exceptobject
kLogicalOperators, // and, in, is, not, or
kArithmeticOperators, // div, mod
kBitwiseOperators, // ror, rol, shr, shl
kSetOperators, // union, minus, union2
kSqlControl, // select, vselect, sselect, update, delete, mselect
kSqlOperators, // on, like, in (SQL context)
kSqlKeywords, // sqlin, from, where, group, by, order, distinct, join
kCallingConventions, // cdecl, pascal, stdcall, safecall, fastcall, register
kSystemKeywords, // setuid, sudo
kBuiltinVariables, // paramcount, realparamcount, params, system, tslassigning, likeeps, likeepsrate
kBuiltinFunctions, // echo, mtic, mtoc
kBooleanConstants, // false, true
kMathConstants, // inf, nan
kNullConstants // nil
};
struct KeywordInfo
{
std::string keyword;
KeywordCategory category;
std::string description;
};
}
-281
View File
@@ -1,281 +0,0 @@
#include <vector>
#include <cctype>
#include <algorithm>
#include "./tsl_keywords.hpp"
namespace tsl
{
std::vector<KeywordInfo> TslKeywords::keywords_;
std::unordered_set<std::string> TslKeywords::keyword_set_;
bool TslKeywords::initialized_ = false;
const std::vector<KeywordInfo>& TslKeywords::GetAllKeywords()
{
InitKeywords();
return keywords_;
}
std::vector<KeywordInfo> TslKeywords::GetKeywordsByCategory(KeywordCategory category)
{
InitKeywords();
std::vector<KeywordInfo> result;
for (const auto& keyword : keywords_)
if (keyword.category == category)
result.push_back(keyword);
return result;
}
std::vector<lsp::protocol::CompletionItem> TslKeywords::GetCompletionItems(const std::string& prefix)
{
InitKeywords();
std::vector<lsp::protocol::CompletionItem> result;
std::string lower_prefix = ToLowerCase(prefix);
for (const auto& keyword : keywords_)
{
if (prefix.empty() || StartsWith(ToLowerCase(keyword.keyword), lower_prefix))
{
lsp::protocol::CompletionItem item;
item.label = keyword.keyword;
item.kind = keyword.completion_kind;
item.detail = keyword.description;
item.insertText = keyword.keyword;
result.push_back(item);
}
}
// 按字母顺序排序
std::sort(result.begin(), result.end(),
[](const lsp::protocol::CompletionItem& a, const lsp::protocol::CompletionItem& b) {
return a.label < b.label;
});
return result;
}
KeywordCategory TslKeywords::GetKeywordCategory(const std::string& word)
{
InitKeywords();
std::string lower_word = ToLowerCase(word);
for (const auto& keyword : keywords_)
{
if (ToLowerCase(keyword.keyword) == lower_word) {
return keyword.category;
}
}
// 如果没找到,返回一个默认值(可以考虑抛出异常)
return KeywordCategory::kProgramStructure;
}
void TslKeywords::InitKeywords()
{
if (initialized_)
return;
keywords_ = {
// Program Structure
{ "program", KeywordCategory::kProgramStructure, "Program declaration", lsp::protocol::CompletionItemKind::kKeyword },
{ "function", KeywordCategory::kProgramStructure, "Function declaration", lsp::protocol::CompletionItemKind::kFunction },
{ "procedure", KeywordCategory::kProgramStructure, "Procedure declaration", lsp::protocol::CompletionItemKind::kFunction },
{ "unit", KeywordCategory::kProgramStructure, "Unit declaration", lsp::protocol::CompletionItemKind::kModule },
{ "uses", KeywordCategory::kProgramStructure, "Uses clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "implementation", KeywordCategory::kProgramStructure, "Implementation section", lsp::protocol::CompletionItemKind::kKeyword },
{ "interface", KeywordCategory::kProgramStructure, "Interface section", lsp::protocol::CompletionItemKind::kInterface },
{ "initialization", KeywordCategory::kProgramStructure, "Initialization section", lsp::protocol::CompletionItemKind::kKeyword },
{ "finalization", KeywordCategory::kProgramStructure, "Finalization section", lsp::protocol::CompletionItemKind::kKeyword },
// Data Types
{ "string", KeywordCategory::kDataTypes, "String data type", lsp::protocol::CompletionItemKind::kClass },
{ "integer", KeywordCategory::kDataTypes, "Integer data type", lsp::protocol::CompletionItemKind::kClass },
{ "boolean", KeywordCategory::kDataTypes, "Boolean data type", lsp::protocol::CompletionItemKind::kClass },
{ "int64", KeywordCategory::kDataTypes, "64-bit integer data type", lsp::protocol::CompletionItemKind::kClass },
{ "real", KeywordCategory::kDataTypes, "Real number data type", lsp::protocol::CompletionItemKind::kClass },
{ "array", KeywordCategory::kDataTypes, "Array data type", lsp::protocol::CompletionItemKind::kClass },
// Class Types
{ "type", KeywordCategory::kClassTypes, "Type declaration", lsp::protocol::CompletionItemKind::kKeyword },
{ "class", KeywordCategory::kClassTypes, "Class declaration", lsp::protocol::CompletionItemKind::kClass },
{ "fakeclass", KeywordCategory::kClassTypes, "Fake class declaration", lsp::protocol::CompletionItemKind::kClass },
{ "new", KeywordCategory::kClassTypes, "Object instantiation", lsp::protocol::CompletionItemKind::kKeyword },
// Class Modifiers
{ "override", KeywordCategory::kClassModifiers, "Override method", lsp::protocol::CompletionItemKind::kKeyword },
{ "overload", KeywordCategory::kClassModifiers, "Overload method", lsp::protocol::CompletionItemKind::kKeyword },
{ "virtual", KeywordCategory::kClassModifiers, "Virtual method", lsp::protocol::CompletionItemKind::kKeyword },
{ "property", KeywordCategory::kClassModifiers, "Property declaration", lsp::protocol::CompletionItemKind::kProperty },
{ "self", KeywordCategory::kClassModifiers, "Self reference", lsp::protocol::CompletionItemKind::kVariable },
{ "inherited", KeywordCategory::kClassModifiers, "Inherited method call", lsp::protocol::CompletionItemKind::kKeyword },
// Access Modifiers
{ "public", KeywordCategory::kAccessModifiers, "Public access modifier", lsp::protocol::CompletionItemKind::kKeyword },
{ "protected", KeywordCategory::kAccessModifiers, "Protected access modifier", lsp::protocol::CompletionItemKind::kKeyword },
{ "private", KeywordCategory::kAccessModifiers, "Private access modifier", lsp::protocol::CompletionItemKind::kKeyword },
{ "published", KeywordCategory::kAccessModifiers, "Published access modifier", lsp::protocol::CompletionItemKind::kKeyword },
// Property Accessors
{ "read", KeywordCategory::kPropertyAccessors, "Property read accessor", lsp::protocol::CompletionItemKind::kKeyword },
{ "write", KeywordCategory::kPropertyAccessors, "Property write accessor", lsp::protocol::CompletionItemKind::kKeyword },
// Constructors
{ "create", KeywordCategory::kConstructors, "Constructor method", lsp::protocol::CompletionItemKind::kConstructor },
{ "destroy", KeywordCategory::kConstructors, "Destructor method", lsp::protocol::CompletionItemKind::kMethod },
{ "operator", KeywordCategory::kConstructors, "Operator overload", lsp::protocol::CompletionItemKind::kOperator },
// Variable Modifiers
{ "external", KeywordCategory::kVariableModifiers, "External declaration", lsp::protocol::CompletionItemKind::kKeyword },
{ "const", KeywordCategory::kVariableModifiers, "Constant declaration", lsp::protocol::CompletionItemKind::kConstant },
{ "out", KeywordCategory::kVariableModifiers, "Output parameter", lsp::protocol::CompletionItemKind::kKeyword },
{ "var", KeywordCategory::kVariableModifiers, "Variable declaration", lsp::protocol::CompletionItemKind::kVariable },
{ "global", KeywordCategory::kVariableModifiers, "Global variable", lsp::protocol::CompletionItemKind::kVariable },
{ "static", KeywordCategory::kVariableModifiers, "Static variable", lsp::protocol::CompletionItemKind::kVariable },
// Conditionals
{ "if", KeywordCategory::kConditionals, "If statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "else", KeywordCategory::kConditionals, "Else clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "then", KeywordCategory::kConditionals, "Then clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "case", KeywordCategory::kConditionals, "Case statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "of", KeywordCategory::kConditionals, "Of clause", lsp::protocol::CompletionItemKind::kKeyword },
// Loops
{ "for", KeywordCategory::kLoops, "For loop", lsp::protocol::CompletionItemKind::kKeyword },
{ "while", KeywordCategory::kLoops, "While loop", lsp::protocol::CompletionItemKind::kKeyword },
{ "do", KeywordCategory::kLoops, "Do clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "downto", KeywordCategory::kLoops, "Downto clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "step", KeywordCategory::kLoops, "Step clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "until", KeywordCategory::kLoops, "Until clause", lsp::protocol::CompletionItemKind::kKeyword },
{ "repeat", KeywordCategory::kLoops, "Repeat loop", lsp::protocol::CompletionItemKind::kKeyword },
{ "to", KeywordCategory::kLoops, "To clause", lsp::protocol::CompletionItemKind::kKeyword },
// Branch Control
{ "break", KeywordCategory::kBranchControl, "Break statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "continue", KeywordCategory::kBranchControl, "Continue statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "goto", KeywordCategory::kBranchControl, "Goto statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "label", KeywordCategory::kBranchControl, "Label declaration", lsp::protocol::CompletionItemKind::kKeyword },
{ "exit", KeywordCategory::kBranchControl, "Exit statement", lsp::protocol::CompletionItemKind::kKeyword },
// Return Control
{ "return", KeywordCategory::kReturnControl, "Return statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "debugreturn", KeywordCategory::kReturnControl, "Debug return statement", lsp::protocol::CompletionItemKind::kKeyword },
{ "debugrunenv", KeywordCategory::kReturnControl, "Debug run environment", lsp::protocol::CompletionItemKind::kKeyword },
{ "debugrunenvdo", KeywordCategory::kReturnControl, "Debug run environment do", lsp::protocol::CompletionItemKind::kKeyword },
// Block Control
{ "begin", KeywordCategory::kBlockControl, "Begin block", lsp::protocol::CompletionItemKind::kKeyword },
{ "end", KeywordCategory::kBlockControl, "End block", lsp::protocol::CompletionItemKind::kKeyword },
{ "with", KeywordCategory::kBlockControl, "With statement", lsp::protocol::CompletionItemKind::kKeyword },
// References
{ "weakref", KeywordCategory::kReferences, "Weak reference", lsp::protocol::CompletionItemKind::kKeyword },
{ "autoref", KeywordCategory::kReferences, "Auto reference", lsp::protocol::CompletionItemKind::kKeyword },
// Namespace
{ "namespace", KeywordCategory::kNamespace, "Namespace declaration", lsp::protocol::CompletionItemKind::kModule },
// Exceptions
{ "except", KeywordCategory::kExceptions, "Exception handling", lsp::protocol::CompletionItemKind::kKeyword },
{ "raise", KeywordCategory::kExceptions, "Raise exception", lsp::protocol::CompletionItemKind::kKeyword },
{ "try", KeywordCategory::kExceptions, "Try block", lsp::protocol::CompletionItemKind::kKeyword },
{ "finally", KeywordCategory::kExceptions, "Finally block", lsp::protocol::CompletionItemKind::kKeyword },
{ "exceptobject", KeywordCategory::kExceptions, "Exception object", lsp::protocol::CompletionItemKind::kKeyword },
// Logical Operators
{ "and", KeywordCategory::kLogicalOperators, "Logical AND", lsp::protocol::CompletionItemKind::kOperator },
{ "in", KeywordCategory::kLogicalOperators, "In operator", lsp::protocol::CompletionItemKind::kOperator },
{ "is", KeywordCategory::kLogicalOperators, "Is operator", lsp::protocol::CompletionItemKind::kOperator },
{ "not", KeywordCategory::kLogicalOperators, "Logical NOT", lsp::protocol::CompletionItemKind::kOperator },
{ "or", KeywordCategory::kLogicalOperators, "Logical OR", lsp::protocol::CompletionItemKind::kOperator },
// Arithmetic Operators
{ "div", KeywordCategory::kArithmeticOperators, "Integer division", lsp::protocol::CompletionItemKind::kOperator },
{ "mod", KeywordCategory::kArithmeticOperators, "Modulo operation", lsp::protocol::CompletionItemKind::kOperator },
// Bitwise Operators
{ "ror", KeywordCategory::kBitwiseOperators, "Rotate right", lsp::protocol::CompletionItemKind::kOperator },
{ "rol", KeywordCategory::kBitwiseOperators, "Rotate left", lsp::protocol::CompletionItemKind::kOperator },
{ "shr", KeywordCategory::kBitwiseOperators, "Shift right", lsp::protocol::CompletionItemKind::kOperator },
{ "shl", KeywordCategory::kBitwiseOperators, "Shift left", lsp::protocol::CompletionItemKind::kOperator },
// Set Operators
{ "union", KeywordCategory::kSetOperators, "Set union", lsp::protocol::CompletionItemKind::kOperator },
{ "minus", KeywordCategory::kSetOperators, "Set difference", lsp::protocol::CompletionItemKind::kOperator },
{ "union2", KeywordCategory::kSetOperators, "Set union (alternative)", lsp::protocol::CompletionItemKind::kOperator },
// SQL Control
{ "select", KeywordCategory::kSqlControl, "SQL SELECT", lsp::protocol::CompletionItemKind::kKeyword },
{ "vselect", KeywordCategory::kSqlControl, "Virtual SELECT", lsp::protocol::CompletionItemKind::kKeyword },
{ "sselect", KeywordCategory::kSqlControl, "Special SELECT", lsp::protocol::CompletionItemKind::kKeyword },
{ "update", KeywordCategory::kSqlControl, "SQL UPDATE", lsp::protocol::CompletionItemKind::kKeyword },
{ "delete", KeywordCategory::kSqlControl, "SQL DELETE", lsp::protocol::CompletionItemKind::kKeyword },
{ "mselect", KeywordCategory::kSqlControl, "Multiple SELECT", lsp::protocol::CompletionItemKind::kKeyword },
// SQL Keywords
{ "sqlin", KeywordCategory::kSqlKeywords, "SQL IN", lsp::protocol::CompletionItemKind::kKeyword },
{ "from", KeywordCategory::kSqlKeywords, "SQL FROM", lsp::protocol::CompletionItemKind::kKeyword },
{ "where", KeywordCategory::kSqlKeywords, "SQL WHERE", lsp::protocol::CompletionItemKind::kKeyword },
{ "group", KeywordCategory::kSqlKeywords, "SQL GROUP", lsp::protocol::CompletionItemKind::kKeyword },
{ "by", KeywordCategory::kSqlKeywords, "SQL BY", lsp::protocol::CompletionItemKind::kKeyword },
{ "order", KeywordCategory::kSqlKeywords, "SQL ORDER", lsp::protocol::CompletionItemKind::kKeyword },
{ "distinct", KeywordCategory::kSqlKeywords, "SQL DISTINCT", lsp::protocol::CompletionItemKind::kKeyword },
{ "join", KeywordCategory::kSqlKeywords, "SQL JOIN", lsp::protocol::CompletionItemKind::kKeyword },
// SQL Operators (note: some overlap with logical operators)
{ "on", KeywordCategory::kSqlOperators, "SQL ON", lsp::protocol::CompletionItemKind::kOperator },
{ "like", KeywordCategory::kSqlOperators, "SQL LIKE", lsp::protocol::CompletionItemKind::kOperator },
// Calling Conventions
{ "cdecl", KeywordCategory::kCallingConventions, "C calling convention", lsp::protocol::CompletionItemKind::kKeyword },
{ "pascal", KeywordCategory::kCallingConventions, "Pascal calling convention", lsp::protocol::CompletionItemKind::kKeyword },
{ "stdcall", KeywordCategory::kCallingConventions, "Standard calling convention", lsp::protocol::CompletionItemKind::kKeyword },
{ "safecall", KeywordCategory::kCallingConventions, "Safe calling convention", lsp::protocol::CompletionItemKind::kKeyword },
{ "fastcall", KeywordCategory::kCallingConventions, "Fast calling convention", lsp::protocol::CompletionItemKind::kKeyword },
{ "register", KeywordCategory::kCallingConventions, "Register calling convention", lsp::protocol::CompletionItemKind::kKeyword },
// System Keywords
{ "setuid", KeywordCategory::kSystemKeywords, "Set user ID", lsp::protocol::CompletionItemKind::kKeyword },
{ "sudo", KeywordCategory::kSystemKeywords, "Super user do", lsp::protocol::CompletionItemKind::kKeyword },
// Builtin Variables
{ "paramcount", KeywordCategory::kBuiltinVariables, "Parameter count", lsp::protocol::CompletionItemKind::kVariable },
{ "realparamcount", KeywordCategory::kBuiltinVariables, "Real parameter count", lsp::protocol::CompletionItemKind::kVariable },
{ "params", KeywordCategory::kBuiltinVariables, "Parameters array", lsp::protocol::CompletionItemKind::kVariable },
{ "system", KeywordCategory::kBuiltinVariables, "System variable", lsp::protocol::CompletionItemKind::kVariable },
{ "tslassigning", KeywordCategory::kBuiltinVariables, "TSL assigning", lsp::protocol::CompletionItemKind::kVariable },
{ "likeeps", KeywordCategory::kBuiltinVariables, "Like EPS", lsp::protocol::CompletionItemKind::kVariable },
{ "likeepsrate", KeywordCategory::kBuiltinVariables, "Like EPS rate", lsp::protocol::CompletionItemKind::kVariable },
// Builtin Functions
{ "echo", KeywordCategory::kBuiltinFunctions, "Echo function", lsp::protocol::CompletionItemKind::kFunction },
{ "mtic", KeywordCategory::kBuiltinFunctions, "MTIC function", lsp::protocol::CompletionItemKind::kFunction },
{ "mtoc", KeywordCategory::kBuiltinFunctions, "MTOC function", lsp::protocol::CompletionItemKind::kFunction },
// Boolean Constants
{ "false", KeywordCategory::kBooleanConstants, "Boolean false", lsp::protocol::CompletionItemKind::kConstant },
{ "true", KeywordCategory::kBooleanConstants, "Boolean true", lsp::protocol::CompletionItemKind::kConstant },
// Math Constants
{ "inf", KeywordCategory::kMathConstants, "Infinity", lsp::protocol::CompletionItemKind::kConstant },
{ "nan", KeywordCategory::kMathConstants, "Not a Number", lsp::protocol::CompletionItemKind::kConstant },
// Null Constants
{ "nil", KeywordCategory::kNullConstants, "Null value", lsp::protocol::CompletionItemKind::kConstant }
};
keyword_set_.clear();
for (const auto& keyword : keywords_)
keyword_set_.insert(ToLowerCase(keyword.keyword));
initialized_ = true;
}
std::string TslKeywords::ToLowerCase(const std::string& str)
{
std::string result = str;
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
return result;
}
bool TslKeywords::StartsWith(const std::string& str, const std::string& prefix)
{
if (prefix.length() > str.length())
return false;
return str.compare(0, prefix.length(), prefix) == 0;
}
}