mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-25 20:12:11 +08:00
fix(pascal): Delphi calls to compiler intrinsics and plain data no longer link namesakes (#2803)
A Pascal call to a name the compiler or the System unit gives meaning
to (SizeOf, TypeInfo, High, Low, Length, Inc, Dec, Assigned, Ord, Exit,
Include, Move, Assert, typecasts like Pointer(P)) went to name
matching, which linked any project member of that name: mORMot's
TRttiProp.TypeInfo, a record's length or high field, a property named
Pointer. The built-in name check compared case, so length(S) and dec(N)
got through too. And a call that resolved to a field, property or
variable linked whatever data had the name.
Now a bare call to a System name links only to a declaration its scope
reaches: the class and its ancestors, the unit, the units it uses last
first, skipping a unit's stand-in declared under {$IFDEF} or {$IF}. A
call resolved to data stands only when the data's declared type is a
routine type (written out, a project alias to one, generic or on two
lines, or an RTL procedural type by name), retargeted to what the scope
declares. A name the calling routine declares itself links nothing; a
name the scope doesn't declare at all (a with object's member, a
declaration the parse misplaced) links to the one routine-holding field
or variable of that name. Built-in names compare without case; the RTL
namespaces keep their spelling, except system. Scope lookups now see a
unit whose unit header the parser lost, by its file name (its indented,
lost class members aren't taken for its routines), and an include file
shares its unit's scope and uses clauses. A with body's bare call to a
System name is not extracted, since it may be the with object's.
Validation, edges removed/added against origin/main: SynEdit -243/+50,
HeidiSQL -858/+296, mORMot2 -9039/+987, DelphiMVCFramework -2420/+242,
DWScript -705/+222; leveldb and SDWebImage byte-identical. Sampled
precision of calls to data, before and after: 20/50 and 50/50; of calls
to System names: 2/50 and 47/47. Sampled removed edges: 40/40 wrong.
Follow-up to #2514.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d82a4adc9d
commit
7b50ca8321
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* The names Delphi's compiler and System unit give meaning to, lowercased:
|
||||
* intrinsics (`SizeOf`, `TypeInfo`, `High`, `Inc`, `Assigned`, `Exit`), the
|
||||
* System and SysUtils routines everyone calls (`Move`, `FillChar`, `Copy`,
|
||||
* `Format`, `WriteLn`), and the built-in types a typecast names (`Pointer(P)`,
|
||||
* `Integer(X)`). Pascal names ignore case: `length(S)` is `Length(S)`. A call
|
||||
* to one is the System unit's unless a declaration in its scope shadows it
|
||||
* (see resolution/pascal-scope).
|
||||
*/
|
||||
export const PASCAL_SYSTEM_NAMES: ReadonlySet<string> = new Set([
|
||||
// Intrinsics and System routines
|
||||
'abs', 'addr', 'arctan', 'assert', 'assigned', 'assignfile', 'atomiccmpexchange', 'atomicdecrement',
|
||||
'atomicexchange', 'atomicincrement', 'blockread', 'blockwrite', 'break', 'chdir', 'chr', 'closefile', 'concat',
|
||||
'continue', 'copy', 'cos', 'dec', 'default', 'delete', 'dispose', 'eof', 'eoln', 'exclude', 'exit', 'exp',
|
||||
'fail', 'filepos', 'filesize', 'fillchar', 'finalize', 'frac', 'freemem', 'getdir', 'getmem', 'gettypekind',
|
||||
'halt', 'hasweakref', 'hi', 'high', 'inc', 'include', 'initialize', 'insert', 'int', 'ioresult',
|
||||
'isconstvalue', 'ismanagedtype', 'length', 'ln', 'lo', 'low', 'mkdir', 'move', 'new', 'odd', 'ord',
|
||||
'paramcount', 'paramstr', 'pi', 'pred', 'ptr', 'random', 'randomize', 'read', 'readln', 'reallocmem',
|
||||
'returnaddress', 'rmdir', 'round', 'runerror', 'setlength', 'setstring', 'sin', 'sizeof', 'slice', 'sqr',
|
||||
'sqrt', 'str', 'succ', 'swap', 'trunc', 'typehandle', 'typeinfo', 'typeof', 'uniquestring', 'upcase', 'val',
|
||||
'vararrayredim', 'write', 'writeln',
|
||||
// SysUtils routines the resolver has always taken for the RTL's
|
||||
'abort', 'date', 'datetostr', 'floattostr', 'format', 'freeandnil', 'inttostr', 'lowercase', 'now', 'pos',
|
||||
'strtodate', 'strtofloat', 'strtoint', 'time', 'trim', 'uppercase',
|
||||
// Built-in types, called as typecasts
|
||||
'ansichar', 'ansistring', 'boolean', 'byte', 'bytebool', 'cardinal', 'char', 'comp', 'currency', 'double',
|
||||
'extended', 'int16', 'int32', 'int64', 'int8', 'integer', 'longbool', 'longint', 'longword', 'nativeint',
|
||||
'nativeuint', 'olevariant', 'pansichar', 'pchar', 'pointer', 'pwidechar', 'rawbytestring', 'real',
|
||||
'shortint', 'shortstring', 'single', 'smallint', 'string', 'uint16', 'uint32', 'uint64', 'uint8',
|
||||
'unicodestring', 'utf8string', 'variant', 'widechar', 'widestring', 'word', 'wordbool',
|
||||
]);
|
||||
@@ -32,6 +32,7 @@ import { RazorExtractor } from './razor-extractor';
|
||||
import { SvelteExtractor } from './svelte-extractor';
|
||||
import { AstroExtractor } from './astro-extractor';
|
||||
import { DfmExtractor } from './dfm-extractor';
|
||||
import { PASCAL_SYSTEM_NAMES } from './languages/pascal-system';
|
||||
import { VueExtractor } from './vue-extractor';
|
||||
import { MyBatisExtractor } from './mybatis-extractor';
|
||||
import { CfmlExtractor } from './cfml-extractor';
|
||||
@@ -8834,7 +8835,11 @@ export class TreeSitterExtractor {
|
||||
}
|
||||
|
||||
const vagueLink = receiverLink && firstChild.type === 'exprDot' && !calleeName.includes('.');
|
||||
if (calleeName && !vagueLink) {
|
||||
// In a `with` body a bare `Delete(I)` or `Assign(X)` may be the `with`
|
||||
// object's member rather than the System unit's or the class's: which one
|
||||
// the object's type would have to say (see resolution/pascal-scope).
|
||||
const withMember = this.pascalWithDepth > 0 && firstChild.type === 'identifier' && PASCAL_SYSTEM_NAMES.has(calleeName.toLowerCase());
|
||||
if (calleeName && !vagueLink && !withMember) {
|
||||
this.unresolvedReferences.push({
|
||||
fromNodeId: callerId,
|
||||
referenceName: calleeName,
|
||||
|
||||
Reference in New Issue
Block a user