mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-30 01:51:20 +00:00
Merge ab228ca611 into 6bb99767ff
This commit is contained in:
commit
0b951189ec
7 changed files with 61 additions and 19 deletions
|
|
@ -379,6 +379,11 @@ type ParsedImportSyntax =
|
|||
* deferred — `use` does not execute
|
||||
* (`LanguageProvider.importsExecuteWhereWritten`). */
|
||||
readonly runsOnlyWhenCalled?: boolean;
|
||||
/**
|
||||
* C/C++ specific. Whether the import is a system header `#include <...>` vs `#include "..."`.
|
||||
* Used during resolution to gate suffix-match fallback.
|
||||
*/
|
||||
readonly isSystem?: boolean;
|
||||
}
|
||||
/**
|
||||
* Runtime-computed target — the import path is not a static literal at
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ export function interpretCImport(captures: CaptureMatch): ParsedImport | null {
|
|||
const source = captures['@import.source']?.text;
|
||||
if (source === undefined) return null;
|
||||
|
||||
// System headers (e.g. <stdio.h>) are not resolved to local files
|
||||
if (captures['@import.system'] !== undefined) return null;
|
||||
|
||||
return { kind: 'wildcard', targetRaw: source };
|
||||
return {
|
||||
kind: 'wildcard',
|
||||
targetRaw: source,
|
||||
isSystem: captures['@import.system'] !== undefined
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -81,7 +81,16 @@ export const cScopeResolver: ScopeResolver = {
|
|||
// this process. Runs BEFORE `populateOwners`.
|
||||
applyCaptureSideChannel: applyCStaticLinkageSideChannel,
|
||||
|
||||
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig) => {
|
||||
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig, context) => {
|
||||
// A gate on the angle/quote form alone closes the reported case (#2965).
|
||||
// System headers (#include <x.h>) search only the implementation-defined
|
||||
// system paths and the configured include path. We do not parse CMake/Make
|
||||
// include paths today, so we refuse them rather than guessing across the
|
||||
// whole repo.
|
||||
if (context?.parsedImport?.kind === 'wildcard' && context.parsedImport.isSystem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Augment allFilePaths with .h files discovered via loadResolutionConfig
|
||||
// since the phase only passes .c files to the C resolver but #include
|
||||
// targets .h files classified as C++ in language detection.
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ export function interpretCppImport(captures: CaptureMatch): ParsedImport | null
|
|||
const source = captures['@import.source']?.text;
|
||||
if (source === undefined) return null;
|
||||
|
||||
// System headers are not resolved to local files
|
||||
if (captures['@import.system'] !== undefined) return null;
|
||||
|
||||
const isSystem = captures['@import.system'] !== undefined;
|
||||
const kind = captures['@import.kind']?.text;
|
||||
|
||||
if (kind === 'named') {
|
||||
|
|
@ -27,7 +25,7 @@ export function interpretCppImport(captures: CaptureMatch): ParsedImport | null
|
|||
}
|
||||
|
||||
// #include or using namespace — wildcard import
|
||||
return { kind: 'wildcard', targetRaw: source };
|
||||
return { kind: 'wildcard', targetRaw: source, isSystem };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -113,7 +113,16 @@ export const cppScopeResolver: ScopeResolver = {
|
|||
return scanCppHeaderFiles(repoPath);
|
||||
},
|
||||
|
||||
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig) => {
|
||||
resolveImportTarget: (targetRaw, fromFile, allFilePaths, resolutionConfig, context) => {
|
||||
// A gate on the angle/quote form alone closes the reported case (#2965).
|
||||
// System headers (#include <x.h>) search only the implementation-defined
|
||||
// system paths and the configured include path. We do not parse CMake/Make
|
||||
// include paths today, so we refuse them rather than guessing across the
|
||||
// whole repo.
|
||||
if (context?.parsedImport?.kind === 'wildcard' && context.parsedImport.isSystem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Augment allFilePaths with header files discovered via loadResolutionConfig.
|
||||
// C++ .h/.hpp/.hxx/.hh files may be classified differently by language
|
||||
// detection but are importable from .cpp files via #include.
|
||||
|
|
|
|||
|
|
@ -108,16 +108,20 @@ describe('C++ import interpretation (interpretCppImport)', () => {
|
|||
'@import.kind': capt('@import.kind', 'wildcard'),
|
||||
'@import.source': capt('@import.source', 'header.hpp'),
|
||||
});
|
||||
expect(result).toEqual({ kind: 'wildcard', targetRaw: 'header.hpp' });
|
||||
// isSystem is false for quoted #include "..." (no @import.system capture).
|
||||
expect(result).toEqual({ kind: 'wildcard', targetRaw: 'header.hpp', isSystem: false });
|
||||
});
|
||||
|
||||
it('returns null for system headers', () => {
|
||||
it('interprets system header as wildcard with isSystem:true', () => {
|
||||
// The interpreter no longer returns null for system headers — it returns a
|
||||
// ParsedImport with isSystem:true. The resolver (cppScopeResolver) is the
|
||||
// layer that refuses to suffix-match system headers against workspace files.
|
||||
const result = interpretCppImport({
|
||||
'@import.kind': capt('@import.kind', 'wildcard'),
|
||||
'@import.source': capt('@import.source', 'iostream'),
|
||||
'@import.system': capt('@import.system', 'true'),
|
||||
});
|
||||
expect(result).toBeNull();
|
||||
expect(result).toEqual({ kind: 'wildcard', targetRaw: 'iostream', isSystem: true });
|
||||
});
|
||||
|
||||
it('interprets named import (using std::vector)', () => {
|
||||
|
|
|
|||
|
|
@ -342,25 +342,43 @@ const CASES: ReadonlyMap<SupportedLanguages, ConformanceCase> = new Map([
|
|||
[
|
||||
SupportedLanguages.C,
|
||||
{
|
||||
// Workspace has a local `src/stdio.h` that shadows the system header.
|
||||
// `#include <stdio.h>` (angle-bracket, isSystem:true) must NOT resolve to
|
||||
// it. `#include "./stdio.h"` (quoted relative form, isSystem:false) from
|
||||
// `src/main.c` DOES reach it via sibling lookup — the decoy-reachability
|
||||
// proof. Using './stdio.h' for reachesDecoy vs 'stdio.h' for external lets
|
||||
// the parsedImport factory distinguish the two arms.
|
||||
files: ['src/stdio.h', 'include/util.h', 'src/main.c'],
|
||||
fromFile: 'src/main.c',
|
||||
resolutionConfig: undefined,
|
||||
external: 'stdio.h',
|
||||
decoy: 'src/stdio.h',
|
||||
reachesDecoy: 'util.h',
|
||||
reachesDecoy: './stdio.h',
|
||||
parsedImport: (targetRaw) => ({
|
||||
kind: 'wildcard',
|
||||
targetRaw,
|
||||
// Bare name → angle-bracket system include; relative path → quoted local.
|
||||
isSystem: !targetRaw.startsWith('.'),
|
||||
}),
|
||||
},
|
||||
],
|
||||
[
|
||||
SupportedLanguages.CPlusPlus,
|
||||
{
|
||||
// Same shape as C: a local `src/cstdio.h` that shadows the C++ system
|
||||
// header. `#include <cstdio.h>` (isSystem:true) must NOT resolve to it;
|
||||
// `#include "./cstdio.h"` (isSystem:false) from `src/main.cpp` DOES.
|
||||
files: ['src/cstdio.h', 'include/util.hpp', 'src/main.cpp'],
|
||||
fromFile: 'src/main.cpp',
|
||||
resolutionConfig: undefined,
|
||||
// `cstdio` with no extension would miss the decoy on spelling alone and
|
||||
// post a pass that measures nothing; the header spelling is the real test.
|
||||
external: 'cstdio.h',
|
||||
decoy: 'src/cstdio.h',
|
||||
reachesDecoy: 'util.hpp',
|
||||
reachesDecoy: './cstdio.h',
|
||||
parsedImport: (targetRaw) => ({
|
||||
kind: 'wildcard',
|
||||
targetRaw,
|
||||
isSystem: !targetRaw.startsWith('.'),
|
||||
}),
|
||||
},
|
||||
],
|
||||
[
|
||||
|
|
@ -417,8 +435,6 @@ const CASES: ReadonlyMap<SupportedLanguages, ConformanceCase> = new Map([
|
|||
*/
|
||||
const KNOWN_GAPS: ReadonlyMap<SupportedLanguages, string> = new Map<SupportedLanguages, string>([
|
||||
[SupportedLanguages.Dart, '`package:http/http.dart` -> `lib/http.dart`'],
|
||||
[SupportedLanguages.C, '`stdio.h` -> `src/stdio.h`'],
|
||||
[SupportedLanguages.CPlusPlus, '`cstdio.h` -> `src/cstdio.h`'],
|
||||
]);
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue