mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-10 03:27:59 +00:00
feat: add Lua language support
This commit is contained in:
parent
77844acb6a
commit
bf9337a5e7
13 changed files with 466 additions and 0 deletions
|
|
@ -43,6 +43,7 @@ const EXTENSION_MAP: Record<SupportedLanguages, readonly string[]> = {
|
|||
[SupportedLanguages.Dart]: ['.dart'],
|
||||
[SupportedLanguages.Vue]: ['.vue'],
|
||||
[SupportedLanguages.Cobol]: ['.cbl', '.cob', '.cpy', '.cobol'],
|
||||
[SupportedLanguages.Lua]: ['.lua'],
|
||||
} satisfies Record<SupportedLanguages, readonly string[]>; // Ensure exhaustiveness
|
||||
|
||||
/** Pre-built reverse lookup: extension → language (built once at module load). */
|
||||
|
|
@ -101,6 +102,7 @@ const SYNTAX_MAP: Record<SupportedLanguages, string> = {
|
|||
[SupportedLanguages.Dart]: 'dart',
|
||||
[SupportedLanguages.Vue]: 'typescript',
|
||||
[SupportedLanguages.Cobol]: 'cobol',
|
||||
[SupportedLanguages.Lua]: 'lua',
|
||||
} satisfies Record<SupportedLanguages, string>; // Ensure exhaustiveness
|
||||
|
||||
/** Non-code file extensions → Prism-compatible syntax identifiers */
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ export enum SupportedLanguages {
|
|||
Vue = 'vue',
|
||||
/** Standalone regex processor — no tree-sitter, no LanguageProvider. */
|
||||
Cobol = 'cobol',
|
||||
Lua = 'lua',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@
|
|||
"tree-sitter-javascript": "^0.23.0",
|
||||
"tree-sitter-php": "^0.23.0",
|
||||
"tree-sitter-python": "0.23.4",
|
||||
"@tree-sitter-grammars/tree-sitter-lua": "^0.4.1",
|
||||
"tree-sitter-ruby": "^0.23.1",
|
||||
"tree-sitter-rust": "0.23.1",
|
||||
"tree-sitter-typescript": "^0.23.2",
|
||||
|
|
|
|||
|
|
@ -246,3 +246,6 @@ export const rubyExportChecker: ExportChecker = (_node, _name) => true;
|
|||
|
||||
/** Dart: public if no leading underscore (convention, same as Python). */
|
||||
export const dartExportChecker: ExportChecker = (_node, name) => !name.startsWith('_');
|
||||
|
||||
/** Lua: no explicit visibility system — all top-level definitions are public. */
|
||||
export const luaExportChecker: ExportChecker = (_node, _name) => true;
|
||||
|
|
|
|||
27
gitnexus/src/core/ingestion/import-resolvers/configs/lua.ts
Normal file
27
gitnexus/src/core/ingestion/import-resolvers/configs/lua.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Lua import resolution config.
|
||||
*
|
||||
* Lua's `require("foo.bar")` converts dots to path separators:
|
||||
* require("scripts.combat.player") → scripts/combat/player.lua
|
||||
*
|
||||
* We apply a simple suffix-match after converting dot-separators.
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { suffixResolve } from '../utils.js';
|
||||
|
||||
/** Lua require() resolution strategy. Dots in the module name map to path separators. */
|
||||
export const luaRequireStrategy: ImportResolverStrategy = (rawImportPath, _filePath, ctx) => {
|
||||
// Strip surrounding quotes if present (e.g. '"scripts.player"' → 'scripts.player')
|
||||
const stripped = rawImportPath.replace(/^['"]|['"]$/g, '');
|
||||
// Convert Lua dot-separators to path separators, then append .lua if missing.
|
||||
const pathParts = stripped.split('.').filter(Boolean);
|
||||
const resolved = suffixResolve(pathParts, ctx.normalizedFileList, ctx.allFileList, ctx.index);
|
||||
return resolved ? { kind: 'files', files: [resolved] } : null;
|
||||
};
|
||||
|
||||
export const luaImportConfig: ImportResolutionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
strategies: [luaRequireStrategy],
|
||||
};
|
||||
|
|
@ -25,6 +25,7 @@ import { swiftProvider } from './swift.js';
|
|||
import { dartProvider } from './dart.js';
|
||||
import { vueProvider } from './vue.js';
|
||||
import { cobolProvider } from './cobol.js';
|
||||
import { luaProvider } from './lua.js';
|
||||
|
||||
export const providers = {
|
||||
[SupportedLanguages.JavaScript]: javascriptProvider,
|
||||
|
|
@ -43,6 +44,7 @@ export const providers = {
|
|||
[SupportedLanguages.Dart]: dartProvider,
|
||||
[SupportedLanguages.Vue]: vueProvider,
|
||||
[SupportedLanguages.Cobol]: cobolProvider,
|
||||
[SupportedLanguages.Lua]: luaProvider,
|
||||
} satisfies Record<SupportedLanguages, LanguageProvider>;
|
||||
|
||||
/** Get provider by language enum (always succeeds for SupportedLanguages). */
|
||||
|
|
|
|||
78
gitnexus/src/core/ingestion/languages/lua.ts
Normal file
78
gitnexus/src/core/ingestion/languages/lua.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Lua Language Provider
|
||||
*
|
||||
* Assembles all Lua-specific ingestion capabilities into a single
|
||||
* LanguageProvider, following the Strategy pattern used by the pipeline.
|
||||
*
|
||||
* Key Lua traits:
|
||||
* - importSemantics: 'wildcard-leaf' (require() returns the full module table)
|
||||
* - No explicit visibility system — everything is public
|
||||
* - No formal class/type system — tables used as namespace/class idiom
|
||||
* - emitScopeCaptures: implemented (emits @scope.module for every file)
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import { defineLanguage } from '../language-provider.js';
|
||||
import { typeConfig as luaConfig } from '../type-extractors/lua.js';
|
||||
import { luaExportChecker } from '../export-detection.js';
|
||||
import { createImportResolver } from '../import-resolvers/resolver-factory.js';
|
||||
import { luaImportConfig } from '../import-resolvers/configs/lua.js';
|
||||
import { LUA_QUERIES } from '../tree-sitter-queries.js';
|
||||
import { emitLuaScopeCaptures } from './lua/index.js';
|
||||
|
||||
const BUILT_INS: ReadonlySet<string> = new Set([
|
||||
// Standard library globals
|
||||
'print',
|
||||
'tostring',
|
||||
'tonumber',
|
||||
'type',
|
||||
'pairs',
|
||||
'ipairs',
|
||||
'next',
|
||||
'select',
|
||||
'unpack',
|
||||
'table',
|
||||
'string',
|
||||
'math',
|
||||
'io',
|
||||
'os',
|
||||
'coroutine',
|
||||
'package',
|
||||
'debug',
|
||||
'load',
|
||||
'loadfile',
|
||||
'dofile',
|
||||
'require',
|
||||
'rawget',
|
||||
'rawset',
|
||||
'rawequal',
|
||||
'rawlen',
|
||||
'setmetatable',
|
||||
'getmetatable',
|
||||
'pcall',
|
||||
'xpcall',
|
||||
'error',
|
||||
'assert',
|
||||
'collectgarbage',
|
||||
'gcinfo',
|
||||
'newproxy',
|
||||
'_G',
|
||||
'_VERSION',
|
||||
'arg',
|
||||
]);
|
||||
|
||||
export const luaProvider = defineLanguage({
|
||||
id: SupportedLanguages.Lua,
|
||||
extensions: ['.lua'],
|
||||
treeSitterQueries: LUA_QUERIES,
|
||||
typeConfig: luaConfig,
|
||||
exportChecker: luaExportChecker,
|
||||
importResolver: createImportResolver(luaImportConfig),
|
||||
importSemantics: 'wildcard-leaf',
|
||||
builtInNames: BUILT_INS,
|
||||
|
||||
// ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
|
||||
// Lua emits at minimum @scope.module (the `(chunk)` capture) so the
|
||||
// pipeline can register each .lua file in the scope-based registry.
|
||||
emitScopeCaptures: emitLuaScopeCaptures,
|
||||
});
|
||||
46
gitnexus/src/core/ingestion/languages/lua/captures.ts
Normal file
46
gitnexus/src/core/ingestion/languages/lua/captures.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* `emitScopeCaptures` for Lua.
|
||||
*
|
||||
* Drives the Lua scope query against `@tree-sitter-grammars/tree-sitter-lua`
|
||||
* and groups raw matches into `CaptureMatch[]` for the central extractor.
|
||||
*
|
||||
* Lua has no formal module system. The top-level chunk (file) is the module
|
||||
* scope. Tables assigned to names are the idiomatic namespace mechanism.
|
||||
*
|
||||
* Pure given the input source text. No I/O, no globals consulted.
|
||||
*/
|
||||
|
||||
import type { Capture, CaptureMatch } from 'gitnexus-shared';
|
||||
import { nodeToCapture } from '../../utils/ast-helpers.js';
|
||||
import { getLuaParser, getLuaScopeQuery } from './query.js';
|
||||
import { getTreeSitterBufferSize } from '../../constants.js';
|
||||
|
||||
export function emitLuaScopeCaptures(
|
||||
sourceText: string,
|
||||
_filePath: string,
|
||||
cachedTree?: unknown,
|
||||
): readonly CaptureMatch[] {
|
||||
let tree = cachedTree as ReturnType<ReturnType<typeof getLuaParser>['parse']> | undefined;
|
||||
if (tree === undefined) {
|
||||
tree = getLuaParser().parse(sourceText, undefined, {
|
||||
bufferSize: getTreeSitterBufferSize(sourceText),
|
||||
});
|
||||
}
|
||||
|
||||
const rawMatches = getLuaScopeQuery().matches(tree.rootNode);
|
||||
const out: CaptureMatch[] = [];
|
||||
|
||||
for (const m of rawMatches) {
|
||||
const grouped: Record<string, Capture> = {};
|
||||
for (const c of m.captures) {
|
||||
const tag = '@' + c.name;
|
||||
// Skip internal predicate captures (e.g. @_req, @_req2, @_sm, @_idx)
|
||||
if (tag.startsWith('@_')) continue;
|
||||
grouped[tag] = nodeToCapture(tag, c.node);
|
||||
}
|
||||
if (Object.keys(grouped).length === 0) continue;
|
||||
out.push(grouped);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
11
gitnexus/src/core/ingestion/languages/lua/index.ts
Normal file
11
gitnexus/src/core/ingestion/languages/lua/index.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Lua scope-resolution hooks (RFC #909 Ring 3, RFC §5).
|
||||
*
|
||||
* Public API barrel for the Lua language provider.
|
||||
*
|
||||
* Module layout:
|
||||
* - `query.ts` — LUA_SCOPE_QUERY string + lazy parser/query singletons
|
||||
* - `captures.ts` — `emitLuaScopeCaptures` (top-level orchestrator)
|
||||
*/
|
||||
|
||||
export { emitLuaScopeCaptures } from './captures.js';
|
||||
128
gitnexus/src/core/ingestion/languages/lua/query.ts
Normal file
128
gitnexus/src/core/ingestion/languages/lua/query.ts
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* Tree-sitter scope-query for Lua (RFC §5.1).
|
||||
*
|
||||
* Exposes lazy `Parser` and `Query` singletons so callers don't
|
||||
* pay tree-sitter init cost per file.
|
||||
*
|
||||
* Capture vocabulary
|
||||
* ──────────────────
|
||||
* @scope.module — top-level chunk (file == module)
|
||||
* @scope.function — function body
|
||||
*
|
||||
* @declaration.name — the identifier being declared
|
||||
* @declaration.function — function definition_statement / local_function
|
||||
* @declaration.method — method via dot_index / method_index
|
||||
* @declaration.variable — local or global variable assignment
|
||||
* @declaration.module — table literal assigned to a name (Lua namespace)
|
||||
*
|
||||
* @import.statement — require() call (local or bare)
|
||||
*
|
||||
* @reference.name — callee of any function/method call
|
||||
* @reference.call.free — free call (foo())
|
||||
* @reference.call.member — method call (obj:method())
|
||||
*/
|
||||
|
||||
import Parser from 'tree-sitter';
|
||||
import Lua from '@tree-sitter-grammars/tree-sitter-lua';
|
||||
|
||||
const LUA_SCOPE_QUERY = `
|
||||
;; ── Scopes ──────────────────────────────────────────────────────────────────
|
||||
;; The entire file is one module scope.
|
||||
(chunk) @scope.module
|
||||
|
||||
;; Each function body introduces its own function scope.
|
||||
(function_definition) @scope.function
|
||||
|
||||
;; ── Declarations: global functions ──────────────────────────────────────────
|
||||
;; function foo(...) ... end
|
||||
(function_definition_statement
|
||||
name: (identifier) @declaration.name) @declaration.function
|
||||
|
||||
;; ── Declarations: method-style (Foo.bar / Foo:bar) ──────────────────────────
|
||||
;; function Foo.bar(...) ... end
|
||||
(function_definition_statement
|
||||
name: (dot_index_expression
|
||||
field: (identifier) @declaration.name)) @declaration.method
|
||||
|
||||
;; function Foo:bar(...) ... end
|
||||
(function_definition_statement
|
||||
name: (method_index_expression
|
||||
method: (identifier) @declaration.name)) @declaration.method
|
||||
|
||||
;; ── Declarations: local functions ────────────────────────────────────────────
|
||||
;; local function bar(...) ... end
|
||||
(local_function_definition_statement
|
||||
name: (identifier) @declaration.name) @declaration.function
|
||||
|
||||
;; ── Declarations: tables used as namespaces/modules ──────────────────────────
|
||||
;; Foo = {}
|
||||
(assignment_statement
|
||||
(variable_list
|
||||
name: (identifier) @declaration.name)
|
||||
(expression_list
|
||||
(table_constructor))) @declaration.module
|
||||
|
||||
;; local Foo = {}
|
||||
(local_variable_declaration
|
||||
(attribute_list
|
||||
name: (identifier) @declaration.name)
|
||||
(expression_list
|
||||
(table_constructor))) @declaration.module
|
||||
|
||||
;; ── Declarations: variables ──────────────────────────────────────────────────
|
||||
;; local x = ...
|
||||
(local_variable_declaration
|
||||
(attribute_list
|
||||
name: (identifier) @declaration.name)) @declaration.variable
|
||||
|
||||
;; x = ... (global assignment)
|
||||
(assignment_statement
|
||||
(variable_list
|
||||
name: (identifier) @declaration.name)) @declaration.variable
|
||||
|
||||
;; ── Imports ──────────────────────────────────────────────────────────────────
|
||||
;; local M = require("foo.bar")
|
||||
(local_variable_declaration
|
||||
(expression_list
|
||||
(function_call_expression
|
||||
name: (identifier) @_req
|
||||
(argument_list
|
||||
(string) @import.source))
|
||||
(#eq? @_req "require"))) @import.statement
|
||||
|
||||
;; require("foo.bar") (bare call)
|
||||
(function_call_expression
|
||||
name: (identifier) @_req2
|
||||
(argument_list
|
||||
(string) @import.source)
|
||||
(#eq? @_req2 "require")) @import.statement
|
||||
|
||||
;; ── References: free calls ───────────────────────────────────────────────────
|
||||
(function_call_expression
|
||||
name: (identifier) @reference.name) @reference.call.free
|
||||
|
||||
;; ── References: method calls ─────────────────────────────────────────────────
|
||||
(method_call_expression
|
||||
method: (identifier) @reference.name) @reference.call.member
|
||||
`;
|
||||
|
||||
let _parser: Parser | null = null;
|
||||
let _query: Parser.Query | null = null;
|
||||
|
||||
export function getLuaParser(): Parser {
|
||||
if (_parser === null) {
|
||||
_parser = new Parser();
|
||||
_parser.setLanguage(Lua as Parameters<Parser['setLanguage']>[0]);
|
||||
}
|
||||
return _parser;
|
||||
}
|
||||
|
||||
export function getLuaScopeQuery(): Parser.Query {
|
||||
if (_query === null) {
|
||||
_query = new Parser.Query(
|
||||
Lua as Parameters<Parser['setLanguage']>[0],
|
||||
LUA_SCOPE_QUERY,
|
||||
);
|
||||
}
|
||||
return _query;
|
||||
}
|
||||
|
|
@ -1334,6 +1334,106 @@ export const DART_QUERIES = `
|
|||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
|
||||
// Lua queries - works with @tree-sitter-grammars/tree-sitter-lua
|
||||
// Lua has no formal module system; a chunk (file) is a module.
|
||||
// Tables assigned to globals/locals are the idiomatic way to namespace code.
|
||||
export const LUA_QUERIES = `
|
||||
; ── Scopes ────────────────────────────────────────────────────────────────────
|
||||
; The top-level chunk maps 1-to-1 to a module scope.
|
||||
(chunk) @scope.module
|
||||
|
||||
; Each function body introduces a new scope.
|
||||
(function_definition) @scope.function
|
||||
|
||||
; ── Functions: top-level / global ────────────────────────────────────────────
|
||||
; function foo(...) ... end
|
||||
(function_definition_statement
|
||||
name: (identifier) @name) @definition.function
|
||||
|
||||
; ── Functions: method-style (Foo:bar, Foo.bar) ───────────────────────────────
|
||||
; function Foo.bar(...) ... end
|
||||
(function_definition_statement
|
||||
name: (dot_index_expression
|
||||
field: (identifier) @name)) @definition.method
|
||||
|
||||
; function Foo:bar(...) ... end
|
||||
(function_definition_statement
|
||||
name: (method_index_expression
|
||||
method: (identifier) @name)) @definition.method
|
||||
|
||||
; ── Local functions ───────────────────────────────────────────────────────────
|
||||
; local function bar(...) ... end
|
||||
(local_function_definition_statement
|
||||
name: (identifier) @name) @definition.function
|
||||
|
||||
; ── Tables as modules / namespaces ───────────────────────────────────────────
|
||||
; Foo = {}
|
||||
(assignment_statement
|
||||
(variable_list
|
||||
name: (identifier) @name)
|
||||
(expression_list
|
||||
(table_constructor))) @definition.module
|
||||
|
||||
; local Foo = {}
|
||||
(local_variable_declaration
|
||||
(attribute_list
|
||||
name: (identifier) @name)
|
||||
(expression_list
|
||||
(table_constructor))) @definition.module
|
||||
|
||||
; ── Variables (local and global) ─────────────────────────────────────────────
|
||||
; local x = ...
|
||||
(local_variable_declaration
|
||||
(attribute_list
|
||||
name: (identifier) @name)) @definition.variable
|
||||
|
||||
; x = ... (bare assignment, top-level)
|
||||
(assignment_statement
|
||||
(variable_list
|
||||
name: (identifier) @name)) @definition.variable
|
||||
|
||||
; ── Imports (require / dofile / loadfile) ────────────────────────────────────
|
||||
; local M = require("foo.bar")
|
||||
(local_variable_declaration
|
||||
(expression_list
|
||||
(function_call_expression
|
||||
name: (identifier) @_req
|
||||
(argument_list
|
||||
(string) @import.source))
|
||||
(#eq? @_req "require"))) @import
|
||||
|
||||
; require("foo.bar") (bare call)
|
||||
(function_call_expression
|
||||
name: (identifier) @_req
|
||||
(argument_list
|
||||
(string) @import.source)
|
||||
(#eq? @_req "require")) @import
|
||||
|
||||
; ── Function calls ────────────────────────────────────────────────────────────
|
||||
; foo()
|
||||
(function_call_expression
|
||||
name: (identifier) @call.name) @call
|
||||
|
||||
; obj:method() / obj.method()
|
||||
(method_call_expression
|
||||
method: (identifier) @call.name) @call
|
||||
|
||||
; ── Heritage (table extension patterns) ─────────────────────────────────────
|
||||
; setmetatable(Foo, {__index = Bar})
|
||||
(function_call_expression
|
||||
name: (identifier) @_sm
|
||||
(argument_list
|
||||
(identifier) @heritage.class
|
||||
(table_constructor
|
||||
(field
|
||||
name: (identifier) @_idx
|
||||
value: (identifier) @heritage.extends)))
|
||||
(#eq? @_sm "setmetatable")
|
||||
(#eq? @_idx "__index")) @heritage
|
||||
`;
|
||||
|
||||
|
||||
|
||||
export const LANGUAGE_QUERIES: Record<SupportedLanguages, string> = {
|
||||
[SupportedLanguages.TypeScript]: TYPESCRIPT_QUERIES,
|
||||
[SupportedLanguages.JavaScript]: JAVASCRIPT_QUERIES,
|
||||
|
|
@ -1351,4 +1451,5 @@ export const LANGUAGE_QUERIES: Record<SupportedLanguages, string> = {
|
|||
[SupportedLanguages.Dart]: DART_QUERIES,
|
||||
[SupportedLanguages.Vue]: TYPESCRIPT_QUERIES, // Vue <script> blocks are parsed as TypeScript
|
||||
[SupportedLanguages.Cobol]: '', // Standalone regex processor — no tree-sitter queries
|
||||
[SupportedLanguages.Lua]: LUA_QUERIES,
|
||||
};
|
||||
|
|
|
|||
64
gitnexus/src/core/ingestion/type-extractors/lua.ts
Normal file
64
gitnexus/src/core/ingestion/type-extractors/lua.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Lua type extractor configuration.
|
||||
*
|
||||
* Lua is dynamically typed — there are no explicit type annotations.
|
||||
* This extractor provides a minimal implementation that records
|
||||
* constructor-call bindings (`local x = Foo.new(...)`) so the pipeline
|
||||
* can still emit call edges, but does not attempt type inference.
|
||||
*/
|
||||
|
||||
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
||||
import type { LanguageTypeConfig } from '../type-extractors/types.js';
|
||||
|
||||
const DECLARATION_NODE_TYPES: ReadonlySet<string> = new Set([
|
||||
'local_variable_declaration',
|
||||
'assignment_statement',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Lua: local x = Foo.new() / local x = Foo()
|
||||
* Extracts a constructor-call binding so the pipeline can infer types on
|
||||
* the left-hand-side variable. Lua has no explicit type system, so we
|
||||
* only record the callee name as a heuristic type hint.
|
||||
*/
|
||||
const extractDeclaration = (node: SyntaxNode, env: Map<string, string>): void => {
|
||||
// local x = Foo() / local x = Foo.new()
|
||||
if (node.type !== 'local_variable_declaration' && node.type !== 'assignment_statement') return;
|
||||
|
||||
// Find the variable name(s) and the rhs expression(s).
|
||||
// Tree-sitter-lua: local_variable_declaration has attribute_list + expression_list children.
|
||||
const attrList =
|
||||
node.type === 'local_variable_declaration'
|
||||
? (node.children.find((c) => c.type === 'attribute_list') ?? null)
|
||||
: (node.children.find((c) => c.type === 'variable_list') ?? null);
|
||||
|
||||
const exprList = node.children.find((c) => c.type === 'expression_list') ?? null;
|
||||
if (!attrList || !exprList) return;
|
||||
|
||||
// Only handle single-name = single-expression for simplicity.
|
||||
const nameNode =
|
||||
node.type === 'local_variable_declaration'
|
||||
? attrList.children.find((c) => c.type === 'identifier') ?? null
|
||||
: attrList.children.find((c) => c.type === 'identifier') ?? null;
|
||||
|
||||
const exprNode = exprList.children.find((c) => c.isNamed) ?? null;
|
||||
if (!nameNode || !exprNode) return;
|
||||
|
||||
// Heuristic: if the RHS is a function call to something ending in .new or a PascalCase name
|
||||
if (exprNode.type === 'function_call_expression') {
|
||||
const nameField = exprNode.children.find((c) => c.isNamed);
|
||||
if (nameField) {
|
||||
env.set(nameNode.text, nameField.text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const extractParameter = (_node: SyntaxNode, _env: Map<string, string>): void => {
|
||||
// Lua has no type annotations on parameters; no-op.
|
||||
};
|
||||
|
||||
export const typeConfig: LanguageTypeConfig = {
|
||||
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
||||
extractDeclaration,
|
||||
extractParameter,
|
||||
};
|
||||
|
|
@ -15,6 +15,7 @@ import Go from 'tree-sitter-go';
|
|||
import Rust from 'tree-sitter-rust';
|
||||
import PHP from 'tree-sitter-php';
|
||||
import Ruby from 'tree-sitter-ruby';
|
||||
import Lua from '@tree-sitter-grammars/tree-sitter-lua';
|
||||
import { createRequire } from 'node:module';
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
|
||||
|
|
@ -51,6 +52,7 @@ const languageMap: Record<string, any> = {
|
|||
...(Kotlin ? { [SupportedLanguages.Kotlin]: Kotlin } : {}),
|
||||
[SupportedLanguages.PHP]: PHP.php_only,
|
||||
[SupportedLanguages.Ruby]: Ruby,
|
||||
[SupportedLanguages.Lua]: Lua,
|
||||
[SupportedLanguages.Vue]: TypeScript.typescript,
|
||||
...(Dart ? { [SupportedLanguages.Dart]: Dart } : {}),
|
||||
...(Swift ? { [SupportedLanguages.Swift]: Swift } : {}),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue