mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-29 01:41:42 +00:00
feat(lua): add Lua language provider and all extractors
Full tree-sitter-based Lua support: - LUA_QUERIES: functions, methods (dot+colon), require() imports, calls, variables, table field assignments - Type extractor (no-op, dynamically typed), call/field/method/variable/ heritage/class/import extractors following Go provider pattern - Export checker (all public, like Ruby) - Import resolver for dot-separated require() paths - Registered in parser-loader SOURCES, LANGUAGE_QUERIES, providers table, entry-point-scoring, framework-detection exhaustive records - FUNCTION_NODE_TYPES extended with Lua node types - Import resolver EXTENSIONS extended with .lua and /init.lua
This commit is contained in:
parent
bfe05d54d6
commit
3e637364a2
15 changed files with 486 additions and 0 deletions
|
|
@ -0,0 +1,6 @@
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { CallExtractionConfig } from '../../call-types.js';
|
||||
|
||||
export const luaCallConfig: CallExtractionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
};
|
||||
16
gitnexus/src/core/ingestion/class-extractors/configs/lua.ts
Normal file
16
gitnexus/src/core/ingestion/class-extractors/configs/lua.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ClassExtractionConfig } from '../../class-types.js';
|
||||
|
||||
/**
|
||||
* Lua class extraction config.
|
||||
*
|
||||
* Lua has no native class syntax. Class-like structures are detected via
|
||||
* local_variable_declaration with table constructors (local M = {}), which
|
||||
* is the standard module/class pattern. Method definitions on the table
|
||||
* (function M:method()) are handled by the method extractor, not here.
|
||||
*/
|
||||
export const luaClassConfig: ClassExtractionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
typeDeclarationNodes: [],
|
||||
fileScopeNodeTypes: ['chunk'],
|
||||
};
|
||||
|
|
@ -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: all definitions are public (no visibility modifiers). Local scope is file-scoped. */
|
||||
export const luaExportChecker: ExportChecker = (_node, _name) => true;
|
||||
|
|
|
|||
40
gitnexus/src/core/ingestion/field-extractors/configs/lua.ts
Normal file
40
gitnexus/src/core/ingestion/field-extractors/configs/lua.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { FieldExtractionConfig } from '../generic.js';
|
||||
|
||||
/**
|
||||
* Lua field extraction config.
|
||||
*
|
||||
* Lua tables are the only compound data type. Table fields are defined in
|
||||
* constructors ({ key = value }) or via assignment (tbl.key = value).
|
||||
* Tree-sitter-lua represents constructor fields as `field` nodes inside `table`.
|
||||
*
|
||||
* Lua has no visibility modifiers — all fields are public.
|
||||
*/
|
||||
export const luaFieldConfig: FieldExtractionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
typeDeclarationNodes: ['local_variable_declaration', 'variable_assignment'],
|
||||
fieldNodeTypes: ['field'],
|
||||
bodyNodeTypes: ['field_list'],
|
||||
defaultVisibility: 'public',
|
||||
|
||||
extractName(node) {
|
||||
const key = node.childForFieldName('key');
|
||||
return key?.type === 'identifier' ? key.text : undefined;
|
||||
},
|
||||
|
||||
extractType(_node) {
|
||||
return undefined; // Lua is dynamically typed
|
||||
},
|
||||
|
||||
extractVisibility(_node) {
|
||||
return 'public';
|
||||
},
|
||||
|
||||
isStatic(_node) {
|
||||
return false;
|
||||
},
|
||||
|
||||
isReadonly(_node) {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { HeritageExtractionConfig } from '../../heritage-types.js';
|
||||
|
||||
/**
|
||||
* Lua heritage extraction config.
|
||||
*
|
||||
* Lua uses metatables for inheritance (setmetatable + __index). Since this is
|
||||
* runtime behavior rather than syntactic inheritance, tree-sitter queries
|
||||
* cannot reliably capture it. The heritage extractor is configured but relies
|
||||
* on future call-routing hooks to detect setmetatable patterns.
|
||||
*/
|
||||
export const luaHeritageConfig: HeritageExtractionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
};
|
||||
20
gitnexus/src/core/ingestion/import-resolvers/configs/lua.ts
Normal file
20
gitnexus/src/core/ingestion/import-resolvers/configs/lua.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Lua import resolution config.
|
||||
* Lua require() uses dot-separated module paths: require('foo.bar') → foo/bar.lua or foo/bar/init.lua
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { ImportResolutionConfig, ImportResolverStrategy } from '../types.js';
|
||||
import { suffixResolve } from '../utils.js';
|
||||
|
||||
export const luaRequireStrategy: ImportResolverStrategy = (rawImportPath, _filePath, ctx) => {
|
||||
const dotPath = rawImportPath.replace(/^['"]|['"]$/g, '');
|
||||
const pathParts = dotPath.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],
|
||||
};
|
||||
|
|
@ -47,6 +47,9 @@ export const EXTENSIONS = [
|
|||
'.swift',
|
||||
// Ruby
|
||||
'.rb',
|
||||
// Lua
|
||||
'.lua',
|
||||
'/init.lua',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { rubyProvider } from './ruby.js';
|
|||
import { swiftProvider } from './swift.js';
|
||||
import { dartProvider } from './dart.js';
|
||||
import { vueProvider } from './vue.js';
|
||||
import { luaProvider } from './lua.js';
|
||||
import { cobolProvider } from './cobol.js';
|
||||
|
||||
export const providers = {
|
||||
|
|
@ -41,6 +42,7 @@ export const providers = {
|
|||
[SupportedLanguages.Ruby]: rubyProvider,
|
||||
[SupportedLanguages.Swift]: swiftProvider,
|
||||
[SupportedLanguages.Dart]: dartProvider,
|
||||
[SupportedLanguages.Lua]: luaProvider,
|
||||
[SupportedLanguages.Vue]: vueProvider,
|
||||
[SupportedLanguages.Cobol]: cobolProvider,
|
||||
} satisfies Record<SupportedLanguages, LanguageProvider>;
|
||||
|
|
|
|||
107
gitnexus/src/core/ingestion/languages/lua.ts
Normal file
107
gitnexus/src/core/ingestion/languages/lua.ts
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* 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() brings the module table into scope)
|
||||
* - No static typing — type extractors are minimal
|
||||
* - Class-like structures via table + metatable convention
|
||||
* - Methods via function M:method() (colon syntax) and function M.func() (dot syntax)
|
||||
*/
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import { createClassExtractor } from '../class-extractors/generic.js';
|
||||
import { luaClassConfig } from '../class-extractors/configs/lua.js';
|
||||
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 { createFieldExtractor } from '../field-extractors/generic.js';
|
||||
import { luaFieldConfig } from '../field-extractors/configs/lua.js';
|
||||
import { createMethodExtractor } from '../method-extractors/generic.js';
|
||||
import { luaMethodConfig } from '../method-extractors/configs/lua.js';
|
||||
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
||||
import { luaVariableConfig } from '../variable-extractors/configs/lua.js';
|
||||
import { createCallExtractor } from '../call-extractors/generic.js';
|
||||
import { luaCallConfig } from '../call-extractors/configs/lua.js';
|
||||
import { createHeritageExtractor } from '../heritage-extractors/generic.js';
|
||||
import { luaHeritageConfig } from '../heritage-extractors/configs/lua.js';
|
||||
|
||||
const BUILT_INS: ReadonlySet<string> = new Set([
|
||||
'print',
|
||||
'type',
|
||||
'tostring',
|
||||
'tonumber',
|
||||
'error',
|
||||
'assert',
|
||||
'pcall',
|
||||
'xpcall',
|
||||
'require',
|
||||
'dofile',
|
||||
'loadfile',
|
||||
'load',
|
||||
'rawget',
|
||||
'rawset',
|
||||
'rawequal',
|
||||
'rawlen',
|
||||
'setmetatable',
|
||||
'getmetatable',
|
||||
'select',
|
||||
'next',
|
||||
'pairs',
|
||||
'ipairs',
|
||||
'unpack',
|
||||
'table.insert',
|
||||
'table.remove',
|
||||
'table.concat',
|
||||
'table.sort',
|
||||
'string.format',
|
||||
'string.find',
|
||||
'string.match',
|
||||
'string.gsub',
|
||||
'string.sub',
|
||||
'string.len',
|
||||
'string.byte',
|
||||
'string.char',
|
||||
'string.rep',
|
||||
'string.reverse',
|
||||
'string.upper',
|
||||
'string.lower',
|
||||
'math.floor',
|
||||
'math.ceil',
|
||||
'math.abs',
|
||||
'math.max',
|
||||
'math.min',
|
||||
'math.sqrt',
|
||||
'math.random',
|
||||
'io.open',
|
||||
'io.read',
|
||||
'io.write',
|
||||
'io.close',
|
||||
'os.time',
|
||||
'os.clock',
|
||||
'os.date',
|
||||
'os.execute',
|
||||
'collectgarbage',
|
||||
]);
|
||||
|
||||
export const luaProvider = defineLanguage({
|
||||
id: SupportedLanguages.Lua,
|
||||
extensions: ['.lua'],
|
||||
treeSitterQueries: LUA_QUERIES,
|
||||
typeConfig: luaConfig,
|
||||
exportChecker: luaExportChecker,
|
||||
importResolver: createImportResolver(luaImportConfig),
|
||||
importSemantics: 'wildcard-leaf',
|
||||
callExtractor: createCallExtractor(luaCallConfig),
|
||||
fieldExtractor: createFieldExtractor(luaFieldConfig),
|
||||
methodExtractor: createMethodExtractor(luaMethodConfig),
|
||||
variableExtractor: createVariableExtractor(luaVariableConfig),
|
||||
classExtractor: createClassExtractor(luaClassConfig),
|
||||
heritageExtractor: createHeritageExtractor(luaHeritageConfig),
|
||||
builtInNames: BUILT_INS,
|
||||
});
|
||||
90
gitnexus/src/core/ingestion/method-extractors/configs/lua.ts
Normal file
90
gitnexus/src/core/ingestion/method-extractors/configs/lua.ts
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { MethodExtractionConfig, ParameterInfo } from '../../method-types.js';
|
||||
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
||||
|
||||
function extractLuaName(node: SyntaxNode): string | undefined {
|
||||
const nameField = node.childForFieldName('name');
|
||||
if (!nameField) return undefined;
|
||||
if (nameField.type === 'identifier') return nameField.text;
|
||||
if (nameField.type === 'variable') {
|
||||
const method = nameField.childForFieldName('method');
|
||||
if (method) return method.text;
|
||||
const field = nameField.childForFieldName('field');
|
||||
if (field) return field.text;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function extractLuaParameters(node: SyntaxNode): ParameterInfo[] {
|
||||
const paramList = node.childForFieldName('parameters');
|
||||
if (!paramList) return [];
|
||||
const params: ParameterInfo[] = [];
|
||||
for (let i = 0; i < paramList.namedChildCount; i++) {
|
||||
const child = paramList.namedChild(i);
|
||||
if (!child) continue;
|
||||
if (child.type === 'identifier') {
|
||||
params.push({
|
||||
name: child.text,
|
||||
type: null,
|
||||
rawType: null,
|
||||
isOptional: false,
|
||||
isVariadic: false,
|
||||
});
|
||||
} else if (child.type === 'vararg_expression') {
|
||||
params.push({
|
||||
name: '...',
|
||||
type: null,
|
||||
rawType: null,
|
||||
isOptional: false,
|
||||
isVariadic: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function extractLuaOwnerName(node: SyntaxNode): string | undefined {
|
||||
const nameField = node.childForFieldName('name');
|
||||
if (nameField?.type !== 'variable') return undefined;
|
||||
const table = nameField.childForFieldName('table');
|
||||
return table?.type === 'identifier' ? table.text : undefined;
|
||||
}
|
||||
|
||||
export const luaMethodConfig: MethodExtractionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
typeDeclarationNodes: ['function_definition_statement', 'local_function_definition_statement'],
|
||||
methodNodeTypes: ['function_definition_statement', 'local_function_definition_statement'],
|
||||
bodyNodeTypes: [],
|
||||
|
||||
extractName: extractLuaName,
|
||||
|
||||
extractReturnType(_node) {
|
||||
return undefined; // Lua is dynamically typed
|
||||
},
|
||||
|
||||
extractParameters: extractLuaParameters,
|
||||
|
||||
extractVisibility(_node) {
|
||||
return 'public';
|
||||
},
|
||||
|
||||
extractReceiverType(node) {
|
||||
return extractLuaOwnerName(node);
|
||||
},
|
||||
|
||||
extractOwnerName: extractLuaOwnerName,
|
||||
|
||||
isStatic(node) {
|
||||
const nameField = node.childForFieldName('name');
|
||||
if (nameField?.type !== 'variable') return true;
|
||||
return nameField.childForFieldName('method') == null;
|
||||
},
|
||||
|
||||
isAbstract(_node) {
|
||||
return false;
|
||||
},
|
||||
|
||||
isFinal(_node) {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
|
@ -1373,6 +1373,64 @@ export const DART_QUERIES = `
|
|||
(type_identifier) @heritage.trait))) @heritage
|
||||
`;
|
||||
|
||||
export const LUA_QUERIES = `
|
||||
; Functions (global)
|
||||
(function_definition_statement name: (identifier) @name) @definition.function
|
||||
|
||||
; Methods — function M.foo() end (dot-access method on table)
|
||||
(function_definition_statement
|
||||
name: (variable
|
||||
table: (identifier) @definition.class.hint
|
||||
field: (identifier) @name)) @definition.method
|
||||
|
||||
; Methods — function M:bar() end (colon-access method on table)
|
||||
(function_definition_statement
|
||||
name: (variable
|
||||
table: (identifier) @definition.class.hint
|
||||
method: (identifier) @name)) @definition.method
|
||||
|
||||
; Local functions
|
||||
(local_function_definition_statement name: (identifier) @name) @definition.function
|
||||
|
||||
; Imports — require('module') with expression_list wrapper
|
||||
(call
|
||||
function: (variable name: (identifier) @_fn)
|
||||
arguments: (argument_list (expression_list (string) @import.source))
|
||||
(#eq? @_fn "require")) @import
|
||||
|
||||
; Imports — require "module" without parens (string directly in argument_list)
|
||||
(call
|
||||
function: (variable name: (identifier) @_fn)
|
||||
arguments: (argument_list (string) @import.source)
|
||||
(#eq? @_fn "require")) @import
|
||||
|
||||
; Calls — free function calls: foo(...)
|
||||
(call function: (variable name: (identifier) @call.name)) @call
|
||||
|
||||
; Calls — method/field calls: obj.method(...) or obj:method(...)
|
||||
(call
|
||||
function: (variable
|
||||
field: (identifier) @call.name)) @call
|
||||
(call
|
||||
function: (variable
|
||||
method: (identifier) @call.name)) @call
|
||||
|
||||
; Local variable declarations: local x = ...
|
||||
(local_variable_declaration
|
||||
(variable_list (variable name: (identifier) @name))) @definition.variable
|
||||
|
||||
; Global variable assignments: x = ... (top-level)
|
||||
(variable_assignment
|
||||
(variable_list (variable name: (identifier) @name))) @definition.variable
|
||||
|
||||
; Table field assignments: M.field = value (property definition)
|
||||
(variable_assignment
|
||||
(variable_list
|
||||
(variable
|
||||
table: (identifier) @assignment.receiver
|
||||
field: (identifier) @assignment.property))) @assignment
|
||||
`;
|
||||
|
||||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
|
||||
export const LANGUAGE_QUERIES: Record<SupportedLanguages, string> = {
|
||||
|
|
@ -1390,6 +1448,7 @@ export const LANGUAGE_QUERIES: Record<SupportedLanguages, string> = {
|
|||
[SupportedLanguages.Ruby]: RUBY_QUERIES,
|
||||
[SupportedLanguages.Swift]: SWIFT_QUERIES,
|
||||
[SupportedLanguages.Dart]: DART_QUERIES,
|
||||
[SupportedLanguages.Lua]: LUA_QUERIES,
|
||||
[SupportedLanguages.Vue]: TYPESCRIPT_QUERIES, // Vue <script> blocks are parsed as TypeScript
|
||||
[SupportedLanguages.Cobol]: '', // Standalone regex processor — no tree-sitter queries
|
||||
};
|
||||
|
|
|
|||
72
gitnexus/src/core/ingestion/type-extractors/lua.ts
Normal file
72
gitnexus/src/core/ingestion/type-extractors/lua.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import type { SyntaxNode } from '../utils/ast-helpers.js';
|
||||
import type {
|
||||
ConstructorBindingScanner,
|
||||
LanguageTypeConfig,
|
||||
ParameterExtractor,
|
||||
TypeBindingExtractor,
|
||||
} from './types.js';
|
||||
import { extractVarName } from './shared.js';
|
||||
|
||||
const DECLARATION_NODE_TYPES: ReadonlySet<string> = new Set([
|
||||
'local_variable_declaration',
|
||||
'variable_assignment',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Lua: local x = Foo.new(...) or local x = Foo(...)
|
||||
* Extract variable name from local_variable_declaration or variable_assignment.
|
||||
*/
|
||||
const extractDeclaration: TypeBindingExtractor = (
|
||||
_node: SyntaxNode,
|
||||
_env: Map<string, string>,
|
||||
): void => {
|
||||
// Lua is dynamically typed — no type annotations to extract
|
||||
};
|
||||
|
||||
const extractParameter: ParameterExtractor = (
|
||||
_node: SyntaxNode,
|
||||
_env: Map<string, string>,
|
||||
): void => {
|
||||
// Lua is dynamically typed — no parameter type annotations
|
||||
};
|
||||
|
||||
const scanConstructorBinding: ConstructorBindingScanner = (node) => {
|
||||
if (node.type !== 'local_variable_declaration') return undefined;
|
||||
|
||||
let varList: SyntaxNode | null = null;
|
||||
let exprList: SyntaxNode | null = null;
|
||||
for (let i = 0; i < node.namedChildCount; i++) {
|
||||
const child = node.namedChild(i);
|
||||
if (child?.type === 'variable_list') varList = child;
|
||||
if (child?.type === 'expression_list') exprList = child;
|
||||
}
|
||||
if (!varList || !exprList) return undefined;
|
||||
|
||||
const firstVar = varList.firstNamedChild;
|
||||
const firstExpr = exprList.firstNamedChild;
|
||||
if (!firstVar || !firstExpr) return undefined;
|
||||
|
||||
const varName = extractVarName(firstVar.childForFieldName?.('name') ?? firstVar);
|
||||
if (!varName) return undefined;
|
||||
|
||||
// local obj = ClassName.new(...)
|
||||
if (firstExpr.type === 'call') {
|
||||
const funcNode = firstExpr.childForFieldName('function');
|
||||
if (funcNode?.type === 'variable') {
|
||||
const table = funcNode.childForFieldName('table');
|
||||
const field = funcNode.childForFieldName('field');
|
||||
if (table?.type === 'identifier' && field?.text === 'new') {
|
||||
return { varName, calleeName: `${table.text}.new` };
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const typeConfig: LanguageTypeConfig = {
|
||||
declarationNodeTypes: DECLARATION_NODE_TYPES,
|
||||
forLoopNodeTypes: new Set(['for_generic_statement']),
|
||||
extractDeclaration,
|
||||
extractParameter,
|
||||
scanConstructorBinding,
|
||||
};
|
||||
|
|
@ -95,6 +95,9 @@ export const FUNCTION_NODE_TYPES = new Set([
|
|||
// Dart
|
||||
'function_signature',
|
||||
'method_signature',
|
||||
// Lua
|
||||
'function_definition_statement',
|
||||
'local_function_definition_statement',
|
||||
]);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
import { SupportedLanguages } from 'gitnexus-shared';
|
||||
import type { VariableExtractionConfig, VariableVisibility } from '../../variable-types.js';
|
||||
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
||||
|
||||
function extractLuaVarName(node: SyntaxNode): string | undefined {
|
||||
for (let i = 0; i < node.namedChildCount; i++) {
|
||||
const child = node.namedChild(i);
|
||||
if (child?.type === 'variable_list') {
|
||||
const firstVar = child.namedChildren.find((c: SyntaxNode) => c.type === 'variable');
|
||||
if (firstVar) {
|
||||
const name = firstVar.childForFieldName('name');
|
||||
return name?.type === 'identifier' ? name.text : undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export const luaVariableConfig: VariableExtractionConfig = {
|
||||
language: SupportedLanguages.Lua,
|
||||
constNodeTypes: [],
|
||||
staticNodeTypes: [],
|
||||
variableNodeTypes: ['local_variable_declaration', 'variable_assignment'],
|
||||
|
||||
extractName: extractLuaVarName,
|
||||
|
||||
extractType(_node) {
|
||||
return undefined; // Lua is dynamically typed
|
||||
},
|
||||
|
||||
extractVisibility(node): VariableVisibility {
|
||||
return node.type === 'local_variable_declaration' ? 'private' : 'public';
|
||||
},
|
||||
|
||||
isConst(_node) {
|
||||
return false;
|
||||
},
|
||||
|
||||
isStatic(_node) {
|
||||
return false;
|
||||
},
|
||||
|
||||
isMutable(_node) {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
|
@ -160,6 +160,11 @@ const SOURCES: Record<string, GrammarSource> = {
|
|||
'Kotlin parsing disabled: `tree-sitter-kotlin` is an optionalDependency ' +
|
||||
'and is not installed (or its native binding failed to build).',
|
||||
},
|
||||
[SupportedLanguages.Lua]: {
|
||||
load: () => _require('tree-sitter-lua'),
|
||||
unavailableNote:
|
||||
'Lua parsing requires `tree-sitter-lua`. Check the install and native binding.',
|
||||
},
|
||||
};
|
||||
|
||||
type LoadResult =
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue