fix(lua): close latest resolver review findings

This commit is contained in:
taoxin 2026-09-14 12:29:44 +08:00
parent 560cdf6a23
commit a64adab8e6
6 changed files with 33 additions and 10 deletions

View file

@ -242,8 +242,15 @@ export const rubyExportChecker: ExportChecker = (_node, _name) => true;
/** Lua: `function foo()` is global (reachable from other files via require/_G);
* `local function foo()` is module-private. */
export const luaExportChecker: ExportChecker = (node, _name) =>
node.type !== 'local_function_definition_statement';
export const luaExportChecker: ExportChecker = (node, _name) => {
let current: SyntaxNode | null = node;
while (current !== null) {
if (current.type === 'local_function_definition_statement') return false;
if (current.type === 'function_definition_statement') return true;
current = current.parent;
}
return true;
};
/** Dart: public if no leading underscore (convention, same as Python). */
export const dartExportChecker: ExportChecker = (_node, name) => !name.startsWith('_');

View file

@ -42,7 +42,7 @@ const LUA_CALLABLE_CAPTURE_OPTIONS = {
'function_definition',
]),
callNodeTypes: new Set(['call']),
parameterListNodeTypes: new Set(['parameter_list', 'argument_list']),
parameterListNodeTypes: new Set(['parameters', 'parameter_list', 'argument_list']),
parameterNodeTypes: new Set(['identifier', 'vararg_expression']),
bindingNodeTypes: new Set(['local_variable_declaration']),
assignmentNodeTypes: new Set(['variable_assignment']),
@ -303,7 +303,11 @@ function addLuaArityCaptures(
functionNode: Parser.SyntaxNode,
): void {
const parameters = functionNode.childForFieldName('parameters');
if (parameters?.type !== 'parameter_list') return;
if (
parameters === null ||
!LUA_CALLABLE_CAPTURE_OPTIONS.parameterListNodeTypes.has(parameters.type)
)
return;
const hasVararg = parameters.namedChildren.some((child) => child.type === 'vararg_expression');
const fixedCount = parameters.namedChildren.filter(
(child) => child.type !== 'vararg_expression',

View file

@ -44,7 +44,7 @@ interface GrammarSource {
/**
* When true, this grammar may be disabled at runtime via
* `GITNEXUS_SKIP_OPTIONAL_GRAMMARS`. Set ONLY on genuinely-optional grammars
* (optionalDependencies / vendored — swift/dart/kotlin/zig). Required dependencies
* (optionalDependencies / vendored — swift/dart/kotlin/zig/lua). Required dependencies
* routed through the optional machinery for ABI safety (e.g. C, which is
* `optional: true` + `severity: 'error'`) must NOT set this — opting out of a
* required parser is always an install/platform problem, never a user choice.

View file

@ -27,14 +27,20 @@ describe('isLanguageAvailable', () => {
expect(isLanguageAvailable(SupportedLanguages.Swift)).toBe(true);
});
it('reports Lua availability according to the optional grammar state', () => {
it('reports Lua availability according to the optional grammar state', async () => {
const available = isLanguageAvailable(SupportedLanguages.Lua);
if (isGrammarRuntimeSkipped(SupportedLanguages.Lua)) {
expect(available).toBe(false);
} else {
// Lua is optional and may be unavailable when no matching prebuild or
// local native toolchain exists, even without an explicit skip flag.
expect(typeof available).toBe('boolean');
// Without an explicit skip, availability is install-dependent. Check
// that the boolean probe agrees with the actual optional load result.
try {
await loadLanguage(SupportedLanguages.Lua);
expect(available).toBe(true);
} catch (error) {
expect(error).toBeInstanceOf(Error);
expect(available).toBe(false);
}
}
});

View file

@ -45,11 +45,13 @@ describe('parser-loader GITNEXUS_SKIP_OPTIONAL_GRAMMARS runtime gate', () => {
});
it('a comma list can name zig on its own', async () => {
const base = await freshLoader(undefined);
const luaBase = base.isLanguageAvailable(SupportedLanguages.Lua);
const { isLanguageAvailable, isGrammarRuntimeSkipped } = await freshLoader('zig');
expect(isLanguageAvailable(SupportedLanguages.Zig)).toBe(false);
expect(isGrammarRuntimeSkipped(SupportedLanguages.Zig)).toBe(true);
expect(isGrammarRuntimeSkipped(SupportedLanguages.Swift)).toBe(false);
expect(isLanguageAvailable(SupportedLanguages.Lua)).toBe(false);
expect(isLanguageAvailable(SupportedLanguages.Lua)).toBe(luaBase);
});
it('skip=all/true/* also skip every optional grammar', async () => {

View file

@ -543,6 +543,10 @@ const FIXTURES: ReadonlyMap<SupportedLanguages, ImportTargetFixture> = new Map<
parsedImport: IGNORES_CONTEXT,
// See `minimumScans` on the interface: membership probes only.
minimumScans: 0,
minimumParsedFileReads: 0,
},
],
[
SupportedLanguages.Lua,
{
files: ['lib/models.lua', 'lib/main.lua'],