feat: IDE支持 — workspace拆分、LSP服务器、VS Code扩展
**Workspace 拆分** - aster-core: 纯库,zero-dependency,包含 lexer/parser/ast/interpreter/error/analysis - aster: REPL 二进制,薄封装 aster-core - aster-lsp: LSP 语言服务器 **VS Code 扩展 (vscode-ext/)** - TextMate 语法高亮 (.ast 文件) - 语言配置 (注释切换、括号配对、自动缩进) - LSP 客户端 (extension.js) **LSP 服务端功能** - Diagnostics: 实时显示 lex/parse 错误红色波浪线 - Completion: 关键字 + 内置函数 + 用户定义符号补全 - Hover: 悬停显示变量/函数信息 - Signature Help: 函数参数提示 - Goto Definition: Ctrl+Click 跳转到声明处 - Find References: 查找所有引用位置 - Rename: F2 重命名符号 **新增 analysis 模块** - collect_symbols: AST 遍历收集符号 - find_declaration/find_all_references: Token 扫描定位声明和引用
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
.vscode/**
|
||||
node_modules/**
|
||||
.gitignore
|
||||
@@ -0,0 +1,43 @@
|
||||
const path = require('path');
|
||||
const { LanguageClient, TransportKind } = require('vscode-languageclient/node');
|
||||
|
||||
/** @type {LanguageClient} */
|
||||
let client;
|
||||
|
||||
/**
|
||||
* @param {import('vscode').ExtensionContext} context
|
||||
*/
|
||||
function activate(context) {
|
||||
const isWindows = process.platform === 'win32';
|
||||
const serverExe = isWindows ? 'aster-lsp.exe' : 'aster-lsp';
|
||||
|
||||
// __dirname resolves to the real filesystem path (following the junction),
|
||||
// so .. goes to the workspace root where target/ lives
|
||||
const serverPath = path.join(__dirname, '..', 'target', 'debug', serverExe);
|
||||
|
||||
const serverOptions = {
|
||||
command: serverPath,
|
||||
args: [],
|
||||
};
|
||||
|
||||
const clientOptions = {
|
||||
documentSelector: [{ scheme: 'file', language: 'aster' }],
|
||||
};
|
||||
|
||||
client = new LanguageClient(
|
||||
'aster-lsp',
|
||||
'Aster Language Server',
|
||||
serverOptions,
|
||||
clientOptions
|
||||
);
|
||||
|
||||
client.start();
|
||||
}
|
||||
|
||||
function deactivate() {
|
||||
if (client) {
|
||||
return client.stop();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { activate, deactivate };
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": ["/*", "*/"]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
],
|
||||
"autoClosingPairs": [
|
||||
{ "open": "{", "close": "}" },
|
||||
{ "open": "[", "close": "]" },
|
||||
{ "open": "(", "close": ")" },
|
||||
{ "open": "\"", "close": "\"" },
|
||||
{ "open": "'", "close": "'" }
|
||||
],
|
||||
"surroundingPairs": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["\"", "\""],
|
||||
["'", "'"]
|
||||
],
|
||||
"wordPattern": "[a-zA-Z_][a-zA-Z0-9_]*"
|
||||
}
|
||||
Generated
+96
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"name": "aster-lang",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "aster-lang",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.85.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.1.1.tgz",
|
||||
"integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.8.5",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
|
||||
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-jsonrpc": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
|
||||
"integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageclient": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
|
||||
"integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minimatch": "^5.1.0",
|
||||
"semver": "^7.3.7",
|
||||
"vscode-languageserver-protocol": "3.17.5"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.82.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-protocol": {
|
||||
"version": "3.17.5",
|
||||
"resolved": "https://registry.npmmirror.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
|
||||
"integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"vscode-jsonrpc": "8.2.0",
|
||||
"vscode-languageserver-types": "3.17.5"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-types": {
|
||||
"version": "3.17.5",
|
||||
"resolved": "https://registry.npmmirror.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
|
||||
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "aster-lang",
|
||||
"displayName": "Aster Language Support",
|
||||
"description": "Syntax highlighting and language support for the Aster scripting language",
|
||||
"version": "0.1.0",
|
||||
"publisher": "aster",
|
||||
"engines": {
|
||||
"vscode": "^1.85.0"
|
||||
},
|
||||
"categories": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"main": "./extension.js",
|
||||
"contributes": {
|
||||
"languages": [
|
||||
{
|
||||
"id": "aster",
|
||||
"aliases": [
|
||||
"Aster",
|
||||
"aster"
|
||||
],
|
||||
"extensions": [
|
||||
".ast"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "aster",
|
||||
"scopeName": "source.aster",
|
||||
"path": "./syntaxes/aster.tmLanguage.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^9.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||
"name": "Aster",
|
||||
"scopeName": "source.aster",
|
||||
"fileTypes": ["ast"],
|
||||
"patterns": [
|
||||
{ "include": "#comments" },
|
||||
{ "include": "#strings" },
|
||||
{ "include": "#numbers" },
|
||||
{ "include": "#function-declaration" },
|
||||
{ "include": "#keywords" },
|
||||
{ "include": "#constants" },
|
||||
{ "include": "#builtins" },
|
||||
{ "include": "#operators" },
|
||||
{ "include": "#punctuation" },
|
||||
{ "include": "#identifiers" }
|
||||
],
|
||||
"repository": {
|
||||
"comments": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "comment.block.aster",
|
||||
"begin": "/\\*",
|
||||
"end": "\\*/",
|
||||
"patterns": [
|
||||
{
|
||||
"name": "comment.block.aster",
|
||||
"match": "."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "comment.line.double-slash.aster",
|
||||
"match": "//.*$"
|
||||
}
|
||||
]
|
||||
},
|
||||
"strings": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "string.quoted.double.aster",
|
||||
"begin": "\"",
|
||||
"end": "\"",
|
||||
"patterns": [
|
||||
{
|
||||
"name": "constant.character.escape.aster",
|
||||
"match": "\\\\[ntr\"\\\\]"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "string.quoted.single.aster",
|
||||
"begin": "'",
|
||||
"end": "'",
|
||||
"patterns": [
|
||||
{
|
||||
"name": "constant.character.escape.aster",
|
||||
"match": "\\\\[ntr'\\\\]"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"numbers": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "constant.numeric.float.aster",
|
||||
"match": "\\b\\d+\\.\\d+\\b"
|
||||
},
|
||||
{
|
||||
"name": "constant.numeric.integer.aster",
|
||||
"match": "\\b\\d+\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"function-declaration": {
|
||||
"match": "\\b(fn)\\s+([a-zA-Z_][a-zA-Z0-9_]*)",
|
||||
"captures": {
|
||||
"1": { "name": "keyword.control.aster" },
|
||||
"2": { "name": "entity.name.function.aster" }
|
||||
}
|
||||
},
|
||||
"keywords": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "keyword.control.aster",
|
||||
"match": "\\b(let|const|fn|if|else|while|for|in|break|continue|return)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"constants": {
|
||||
"match": "\\b(true|false|nil)\\b",
|
||||
"name": "constant.language.aster"
|
||||
},
|
||||
"builtins": {
|
||||
"match": "\\b(print|input|clock|len|typeof|push|pop|split|trim|substring|replace|contains|upper|lower|starts_with|ends_with|require)\\b",
|
||||
"name": "support.function.builtin.aster"
|
||||
},
|
||||
"operators": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "keyword.operator.assignment.compound.aster",
|
||||
"match": "\\+=|-=|\\*=|/=|%="
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.logical.aster",
|
||||
"match": "&&|\\|\\||!"
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.comparison.aster",
|
||||
"match": "==|!=|<=|>="
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.assignment.aster",
|
||||
"match": "="
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.arithmetic.aster",
|
||||
"match": "[+\\-*/%]"
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.comparison.aster",
|
||||
"match": "<|>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"punctuation": {
|
||||
"patterns": [
|
||||
{
|
||||
"name": "punctuation.section.scope.aster",
|
||||
"match": "[{}]"
|
||||
},
|
||||
{
|
||||
"name": "punctuation.section.brackets.aster",
|
||||
"match": "[\\[\\]]"
|
||||
},
|
||||
{
|
||||
"name": "punctuation.section.parens.aster",
|
||||
"match": "[\\(\\)]"
|
||||
},
|
||||
{
|
||||
"name": "punctuation.separator.aster",
|
||||
"match": "[,;:\\.]"
|
||||
},
|
||||
{
|
||||
"name": "keyword.operator.ternary.question.aster",
|
||||
"match": "\\?"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifiers": {
|
||||
"match": "[a-zA-Z_][a-zA-Z0-9_]*",
|
||||
"name": "variable.other.aster"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user