ucn 5.5.3 → 5.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/ucn/SKILL.md +37 -12
- package/.claude/skills/ucn/references/commands.md +18 -14
- package/.claude/skills/ucn/references/resolution-rules.md +4 -0
- package/.claude/skills/ucn/references/trust-contract.md +4 -4
- package/CHANGELOG.md +485 -0
- package/README.md +66 -29
- package/cli/flags.js +184 -0
- package/cli/index.js +137 -324
- package/core/account.js +44 -87
- package/core/analysis.js +274 -108
- package/core/ast-analysis.js +2 -0
- package/core/bridge.js +14 -0
- package/core/cache.js +103 -16
- package/core/call-fit.js +130 -0
- package/core/callers.js +353 -71
- package/core/capture.js +363 -0
- package/core/change-kinds.js +1107 -0
- package/core/check.js +1150 -139
- package/core/command-contracts.js +8 -7
- package/core/constructed-class.js +1195 -0
- package/core/contract-membership.js +142 -0
- package/core/deadcode.js +455 -106
- package/core/deletion.js +421 -0
- package/core/discovery.js +104 -9
- package/core/entrypoint-toml.js +110 -0
- package/core/entrypoints.js +12 -6
- package/core/evidence-bands.js +68 -0
- package/core/evidence-bands.json +44 -0
- package/core/execute.js +172 -161
- package/core/hot-summary.js +241 -0
- package/core/index-ir.js +5 -3
- package/core/ir.js +6 -2
- package/core/member-signatures.js +789 -0
- package/core/outgoing-check.js +116 -0
- package/core/output/analysis-ext.js +20 -10
- package/core/output/analysis.js +98 -60
- package/core/output/check.js +101 -37
- package/core/output/doctor.js +34 -1
- package/core/output/find.js +2 -1
- package/core/output/lines.js +63 -3
- package/core/output/public.js +29 -11
- package/core/output/refactoring.js +32 -0
- package/core/output/reporting.js +19 -2
- package/core/output/search.js +14 -2
- package/core/output/tracing.js +36 -8
- package/core/output-budget.js +146 -61
- package/core/parallel-build.js +3 -3
- package/core/project.js +106 -23
- package/core/provenance-type.js +12 -5
- package/core/public-command.js +35 -9
- package/core/python-binding-identity.js +707 -0
- package/core/python-modules.js +6 -0
- package/core/reflection.js +248 -31
- package/core/registry.js +623 -72
- package/core/reporting.js +69 -34
- package/core/review-items.js +75 -0
- package/core/runtime-entrypoints.js +159 -0
- package/core/search.js +148 -164
- package/core/shared.js +0 -45
- package/core/snapshot.js +350 -0
- package/core/source-universe.js +707 -0
- package/core/test-units.js +3698 -0
- package/core/tracing.js +270 -658
- package/core/verify.js +63 -22
- package/languages/adapter.js +8 -3
- package/languages/c-family.js +12 -0
- package/languages/csharp.js +634 -0
- package/languages/go.js +120 -0
- package/languages/index.js +466 -4
- package/languages/java.js +712 -0
- package/languages/javascript.js +1498 -6
- package/languages/lexical-scope.js +68 -0
- package/languages/python.js +1708 -3
- package/languages/rust.js +209 -104
- package/languages/static-js.js +88 -0
- package/mcp/server.js +44 -110
- package/package.json +11 -5
package/languages/index.js
CHANGED
|
@@ -104,6 +104,14 @@ const JAVA_LANG_NOT_SERIALIZABLE = ['Object', 'Runnable', 'AutoCloseable', 'Comp
|
|
|
104
104
|
|
|
105
105
|
const STRUCTURAL_TRAITS = {
|
|
106
106
|
typeSystem: 'structural',
|
|
107
|
+
// How a callable's return contract can come from its body instead of its
|
|
108
|
+
// header. 'unannotated': a callable with no return annotation takes the
|
|
109
|
+
// type its body returns; 'placeholder': a written placeholder type is
|
|
110
|
+
// deduced from the body; 'opaque': a declared opaque type still exposes
|
|
111
|
+
// properties of the concrete value. Empty: the header is the contract.
|
|
112
|
+
inferredReturnForms: ['unannotated'],
|
|
113
|
+
// Callable kinds a body statement alone selects, with no header change.
|
|
114
|
+
callableKindFromBody: [],
|
|
107
115
|
// A write on the instance can replace an inherited method with a
|
|
108
116
|
// callable value, including a wrapper of the previous method.
|
|
109
117
|
instanceAttributesShadowMethods: true,
|
|
@@ -131,6 +139,7 @@ const STRUCTURAL_TRAITS = {
|
|
|
131
139
|
physicalCallTokenSyntax: true,
|
|
132
140
|
scopeAlternativeBindings: false,
|
|
133
141
|
nameReferenceFamily: 'js',
|
|
142
|
+
discardIdentifierNames: [],
|
|
134
143
|
staticValueImportSyntax: null,
|
|
135
144
|
implicitEnumCaseLabels: false,
|
|
136
145
|
valuePatternConstants: false,
|
|
@@ -154,6 +163,10 @@ const STRUCTURAL_TRAITS = {
|
|
|
154
163
|
// 'namespace-usings' (C#: enclosing namespaces, then using directives,
|
|
155
164
|
// global usings and project-file <Using> items), or null.
|
|
156
165
|
typeNameScoping: null,
|
|
166
|
+
// The platform's generic types a language writes with a syntax of its
|
|
167
|
+
// own: { nullable, tuple }, each the type's qualified name (C#:
|
|
168
|
+
// `System.Nullable<T>` is `T?`). Two spellings of one type.
|
|
169
|
+
platformTypeForms: null,
|
|
157
170
|
typeNameSourceCanonical: null,
|
|
158
171
|
typeNameOwnersAt: null,
|
|
159
172
|
implementationOwnerSyntax: null,
|
|
@@ -184,6 +197,13 @@ const STRUCTURAL_TRAITS = {
|
|
|
184
197
|
memberHidingModifier: null,
|
|
185
198
|
virtualMemberModifiers: null,
|
|
186
199
|
hasArityOverloads: false,
|
|
200
|
+
// Bounded literal proofs for changed project calls; absent means unknown.
|
|
201
|
+
checkLiteralArguments: null,
|
|
202
|
+
checkDirectiveComment: null,
|
|
203
|
+
checkFileDirectiveComment: null,
|
|
204
|
+
checkDirectiveTarget: null,
|
|
205
|
+
checkDirectiveBarrier: null,
|
|
206
|
+
checkTypedComment: null,
|
|
187
207
|
userDefinedConversions: null,
|
|
188
208
|
overloadPhases: null,
|
|
189
209
|
overloadFileSymbols: false,
|
|
@@ -256,6 +276,9 @@ const STRUCTURAL_TRAITS = {
|
|
|
256
276
|
constructorArgumentNodes: { delegation: { nodeType: 'call_expression', argsField: 'arguments' } },
|
|
257
277
|
functionalTypeConstruction: false,
|
|
258
278
|
constructorInheritance: { order: 'single', classNodes: ['class_declaration', 'class'], headerNode: 'class_heritage' },
|
|
279
|
+
// Methods whose result a context-manager statement binds (`with X() as
|
|
280
|
+
// v` binds `X().__enter__()`), or null when the language has none.
|
|
281
|
+
contextEnterMethods: null,
|
|
259
282
|
implicitBaseConstruction: null,
|
|
260
283
|
// Whether a constructor delegation is spelled by a keyword (`this(..)`,
|
|
261
284
|
// `super(..)`, `base(..)`) rather than by the type's name (C++
|
|
@@ -303,6 +326,123 @@ const STRUCTURAL_TRAITS = {
|
|
|
303
326
|
// text dependencies; no other language checks a test function's name
|
|
304
327
|
// against a declaration.
|
|
305
328
|
nameBoundTestFunctions: null,
|
|
329
|
+
// Methods a type declares to satisfy a standard-library contract it
|
|
330
|
+
// never names (interfaces satisfied implicitly): name -> parameter
|
|
331
|
+
// count. A zero textual use of one is not evidence that it is unused.
|
|
332
|
+
implicitStandardContracts: null,
|
|
333
|
+
// Is this project type a contract a value can satisfy WITHOUT naming it
|
|
334
|
+
// (assigned, passed or returned as the type with no implements clause)?
|
|
335
|
+
// null: types are satisfied by declaration only, or the language has
|
|
336
|
+
// its own model (Go's method sets). A type that satisfies such a
|
|
337
|
+
// contract by its member names keeps the members the contract requires.
|
|
338
|
+
structuralContract: null,
|
|
339
|
+
// Can another file import ANY module-level name of a module, declared
|
|
340
|
+
// or merely imported there, with no export syntax (Python)? Removing
|
|
341
|
+
// such a name, an import included, takes it from its importers.
|
|
342
|
+
moduleNamesImportable: false,
|
|
343
|
+
// Is a directory importable as a package without its package file
|
|
344
|
+
// (Python namespace packages)? Then deleting that file takes away the
|
|
345
|
+
// names it declared, not the package.
|
|
346
|
+
packageFileOptional: false,
|
|
347
|
+
// Module-level names that let a module supply names it does not write
|
|
348
|
+
// (Python: a module `__getattr__`, a rewritten package `__path__`). A
|
|
349
|
+
// package that declares one cannot be shown to lack a submodule.
|
|
350
|
+
moduleSupplyHooks: [],
|
|
351
|
+
// Is a member's type whatever the class's methods assign to it (Python
|
|
352
|
+
// instance attributes)? Then an assignment to a receiver member in any
|
|
353
|
+
// method is part of the class's contract.
|
|
354
|
+
memberTypesFromAssignments: false,
|
|
355
|
+
// Does an async function's anonymous future expose properties of its
|
|
356
|
+
// body to callers (Rust auto traits: Send, Sync)?
|
|
357
|
+
asyncReturnIsOpaque: false,
|
|
358
|
+
// Modifiers that let the compiler run a callable and hand callers its
|
|
359
|
+
// VALUE (C++ constexpr/consteval, Rust `const fn`): the body is then
|
|
360
|
+
// part of what a caller relies on. null: no such callables.
|
|
361
|
+
compileTimeCallableMarkers: null,
|
|
362
|
+
// Callable names the language supplies with no import and no
|
|
363
|
+
// declaration (builtins, globals): a bare call of one always means
|
|
364
|
+
// something. null: every callable name is declared or imported.
|
|
365
|
+
ambientCallables: null,
|
|
366
|
+
// Builtins among `ambientCallables` that never return (Python `exit`),
|
|
367
|
+
// and global objects whose every member returns (`console`).
|
|
368
|
+
ambientNeverCallables: null,
|
|
369
|
+
ambientReturningNamespaces: null,
|
|
370
|
+
// How a declaration says "a call of this never returns" (`never`,
|
|
371
|
+
// `NoReturn`): a type checker ends the caller's path at a call of one,
|
|
372
|
+
// and only at a declared one. []: the language has no such type; null:
|
|
373
|
+
// no return contract is read from a body in this language.
|
|
374
|
+
neverReturnTypes: null,
|
|
375
|
+
// Can a type checker decide a condition from the names in it (Python:
|
|
376
|
+
// `sys.version_info`, `sys.platform`, `TYPE_CHECKING`, constants its
|
|
377
|
+
// configuration defines)? Then a condition that guards part of what a
|
|
378
|
+
// body returns is part of it; elsewhere only a condition that names
|
|
379
|
+
// nothing (`while (true)`) is decided.
|
|
380
|
+
namedConditionsDecidable: false,
|
|
381
|
+
// Do files without module syntax share one global scope (classic
|
|
382
|
+
// JavaScript scripts)? Then a top-level name of one is visible in all.
|
|
383
|
+
scriptGlobalScope: false,
|
|
384
|
+
// Are the members of a class compared and enumerated by SHAPE
|
|
385
|
+
// (TypeScript)? Then the trait answers whether anything with the
|
|
386
|
+
// class's members is a value of it: `(classNode, ignoredLines) =>
|
|
387
|
+
// boolean`, true unless the class itself declares a private or
|
|
388
|
+
// protected instance member (members starting on `ignoredLines` left
|
|
389
|
+
// out). null: a class is its declaration, and its members are reached
|
|
390
|
+
// by name only.
|
|
391
|
+
classComparedByShape: null,
|
|
392
|
+
// How a class member takes part in the class's type: `(classNode,
|
|
393
|
+
// name, line) => { role: 'instance' | 'optional' | 'static', hidden }
|
|
394
|
+
// | null`; hidden: private, protected or `#`.
|
|
395
|
+
classMemberRole: null,
|
|
396
|
+
// Members of an object literal declared as a type, read from syntax:
|
|
397
|
+
// `(root, line) => { names, open } | null` (languages/javascript.js).
|
|
398
|
+
typedLiteralMembers: null,
|
|
399
|
+
// The interface whose members every object has (`Object`): a project
|
|
400
|
+
// that declares one adds members to every literal.
|
|
401
|
+
universalObjectInterface: null,
|
|
402
|
+
// Has the language's checker been told not to report a break, as its
|
|
403
|
+
// own scanner reads comments (`// @ts-ignore` above the line the break
|
|
404
|
+
// is reported on, `# type: ignore` on a line of the reported range, a
|
|
405
|
+
// rule turned off for the file)? `(site) => boolean` with site
|
|
406
|
+
// { lines, root, line, kind: 'arity' | 'import-name' | 'import-module'
|
|
407
|
+
// | 'undefined-name' | 'literal', name, most, memo }. A break at such a
|
|
408
|
+
// site is one the toolchain will not show: check lists it and does not
|
|
409
|
+
// block on it.
|
|
410
|
+
checkSuppressedAt: null,
|
|
411
|
+
// The tests a file declares, as its runner collects them:
|
|
412
|
+
// `(fileEntry, helpers) => { units, inheriting }` where a unit is
|
|
413
|
+
// { kind: 'test' | 'suite', name, suite: [names], line, endLine } plus
|
|
414
|
+
// what a selector needs (core/test-units.js). Null: the language's
|
|
415
|
+
// tests are not read, and nothing is said about them.
|
|
416
|
+
testUnits: null,
|
|
417
|
+
// (fileEntry, helpers) => boolean: does this file hold code the runner
|
|
418
|
+
// asks at run time that may leave tests out (a conftest hook, a TestMain).
|
|
419
|
+
testGate: null,
|
|
420
|
+
// `(fileEntry, projectDeclaresType) => { marked, bases }` or null: can
|
|
421
|
+
// a file hold test code, from the index alone (no tree)? Asked before
|
|
422
|
+
// a file whose name is no test file's is read for the tests in it.
|
|
423
|
+
testCodeGate: null,
|
|
424
|
+
// Which family of runners executes the language's tests; the family's
|
|
425
|
+
// manifests are the evidence a runner is named on. Null: none modeled.
|
|
426
|
+
testRunnerFamily: null,
|
|
427
|
+
// Modules whose import in a test file names its runner: `() => Map` of
|
|
428
|
+
// module name to runner id; null where an import says nothing of it.
|
|
429
|
+
testRunnerModules: null,
|
|
430
|
+
// What a module of the language exports under a name, as far as
|
|
431
|
+
// declaring tests goes: `(fileEntry, helpers, name) => binding | null`.
|
|
432
|
+
// A test file that takes its runner through a project module is read
|
|
433
|
+
// through it. Null: imports are not followed.
|
|
434
|
+
testExport: null,
|
|
435
|
+
// How the language's runners name a test file. A test-path file that
|
|
436
|
+
// declares no test and is not named like one is support code.
|
|
437
|
+
testFileNames: [],
|
|
438
|
+
// Is the import of `module` written on a line one the project's judge
|
|
439
|
+
// resolves (an import statement), not a call it never looks into?
|
|
440
|
+
// `(root, line, module) => boolean`; null: every import of the language
|
|
441
|
+
// is a statement.
|
|
442
|
+
checkedImportAt: null,
|
|
443
|
+
// Does a virtual member change what a type IS to existing code (C++: a
|
|
444
|
+
// class with one is no aggregate, so `T t{1, 2}` stops compiling)?
|
|
445
|
+
virtualMemberChangesShape: false,
|
|
306
446
|
// Whether a top-level type is declared in a source file named after it
|
|
307
447
|
// (fix #386): javac requires `public class Widget` in Widget.java, so a
|
|
308
448
|
// type rename renames that file too.
|
|
@@ -350,7 +490,15 @@ const STRUCTURAL_TRAITS = {
|
|
|
350
490
|
// class literals. `hintPattern` locates vocabulary spellings whose
|
|
351
491
|
// enclosing call nodes are inspected (the AST decides); `namespaceLookups` are module-namespace lookups by
|
|
352
492
|
// name (eval, globals()[k]). `family` groups languages sharing one
|
|
353
|
-
// runtime.
|
|
493
|
+
// runtime. `unnamed` are reflective calls that carry no member name and
|
|
494
|
+
// `codeExecution` calls and constructions that run code built at
|
|
495
|
+
// runtime: both are counted per file with the rest of the vocabulary
|
|
496
|
+
// (fileEntry.reflectionUses / evalUses, what `repo` and the completeness
|
|
497
|
+
// footer disclose) and never matched against names. Such a rule is
|
|
498
|
+
// `{ callee }` (the callee as written; `qualified` when it has a
|
|
499
|
+
// receiver), `{ package }` (a call qualified by a local name the file's
|
|
500
|
+
// imports bind to that module) or `{ construct }` (the constructed
|
|
501
|
+
// class). null = no runtime reflection.
|
|
354
502
|
reflectionApi: null,
|
|
355
503
|
// Members every class inherits from the implicit root supertype, keyed by
|
|
356
504
|
// name with their parameter count (Java Object.toString/equals/...,
|
|
@@ -371,6 +519,9 @@ const STRUCTURAL_TRAITS = {
|
|
|
371
519
|
};
|
|
372
520
|
const NOMINAL_TRAITS = {
|
|
373
521
|
typeSystem: 'nominal',
|
|
522
|
+
// See STRUCTURAL_TRAITS: a declared return type is the whole contract.
|
|
523
|
+
inferredReturnForms: [],
|
|
524
|
+
callableKindFromBody: [],
|
|
374
525
|
instanceAttributesShadowMethods: false,
|
|
375
526
|
inherentMethodsPrecedeTraitImpls: false,
|
|
376
527
|
derefFieldAccess: false,
|
|
@@ -381,6 +532,7 @@ const NOMINAL_TRAITS = {
|
|
|
381
532
|
hasConstructors: false,
|
|
382
533
|
fixedConstructorName: null,
|
|
383
534
|
constructorInheritance: null,
|
|
535
|
+
contextEnterMethods: null,
|
|
384
536
|
implicitBaseConstruction: null,
|
|
385
537
|
keywordConstructorDelegation: false,
|
|
386
538
|
constructorUsesAreTypeReferences: false,
|
|
@@ -393,6 +545,7 @@ const NOMINAL_TRAITS = {
|
|
|
393
545
|
physicalCallTokenSyntax: true,
|
|
394
546
|
scopeAlternativeBindings: false,
|
|
395
547
|
nameReferenceFamily: null,
|
|
548
|
+
discardIdentifierNames: [],
|
|
396
549
|
staticValueImportSyntax: null,
|
|
397
550
|
implicitEnumCaseLabels: false,
|
|
398
551
|
valuePatternConstants: false,
|
|
@@ -403,6 +556,7 @@ const NOMINAL_TRAITS = {
|
|
|
403
556
|
moduleTypeIdentity: false,
|
|
404
557
|
standardPathRoots: [],
|
|
405
558
|
typeNameScoping: null,
|
|
559
|
+
platformTypeForms: null,
|
|
406
560
|
typeNameSourceCanonical: null,
|
|
407
561
|
typeNameOwnersAt: null,
|
|
408
562
|
implicitTypeImport: null,
|
|
@@ -444,6 +598,13 @@ const NOMINAL_TRAITS = {
|
|
|
444
598
|
// the caller contract: a pinned overload is only confirmed when the call
|
|
445
599
|
// site provably binds it.
|
|
446
600
|
hasArityOverloads: false,
|
|
601
|
+
// Bounded literal proofs for changed project calls; absent means unknown.
|
|
602
|
+
checkLiteralArguments: null,
|
|
603
|
+
checkDirectiveComment: null,
|
|
604
|
+
checkFileDirectiveComment: null,
|
|
605
|
+
checkDirectiveTarget: null,
|
|
606
|
+
checkDirectiveBarrier: null,
|
|
607
|
+
checkTypedComment: null,
|
|
447
608
|
// User-defined conversions keep otherwise incompatible argument types
|
|
448
609
|
// possible; selecting an overload still needs a positive conversion proof.
|
|
449
610
|
userDefinedConversions: null,
|
|
@@ -516,6 +677,123 @@ const NOMINAL_TRAITS = {
|
|
|
516
677
|
// Test functions the toolchain binds to a declared identifier by NAME
|
|
517
678
|
// (fix #383); see GO_EXAMPLE_NAMES. null: no such convention.
|
|
518
679
|
nameBoundTestFunctions: null,
|
|
680
|
+
// Methods a type declares to satisfy a standard-library contract it
|
|
681
|
+
// never names (interfaces satisfied implicitly): name -> parameter
|
|
682
|
+
// count. A zero textual use of one is not evidence that it is unused.
|
|
683
|
+
implicitStandardContracts: null,
|
|
684
|
+
// Is this project type a contract a value can satisfy WITHOUT naming it
|
|
685
|
+
// (assigned, passed or returned as the type with no implements clause)?
|
|
686
|
+
// null: types are satisfied by declaration only, or the language has
|
|
687
|
+
// its own model (Go's method sets). A type that satisfies such a
|
|
688
|
+
// contract by its member names keeps the members the contract requires.
|
|
689
|
+
structuralContract: null,
|
|
690
|
+
// Can another file import ANY module-level name of a module, declared
|
|
691
|
+
// or merely imported there, with no export syntax (Python)? Removing
|
|
692
|
+
// such a name, an import included, takes it from its importers.
|
|
693
|
+
moduleNamesImportable: false,
|
|
694
|
+
// Is a directory importable as a package without its package file
|
|
695
|
+
// (Python namespace packages)? Then deleting that file takes away the
|
|
696
|
+
// names it declared, not the package.
|
|
697
|
+
packageFileOptional: false,
|
|
698
|
+
// Module-level names that let a module supply names it does not write
|
|
699
|
+
// (Python: a module `__getattr__`, a rewritten package `__path__`). A
|
|
700
|
+
// package that declares one cannot be shown to lack a submodule.
|
|
701
|
+
moduleSupplyHooks: [],
|
|
702
|
+
// Is a member's type whatever the class's methods assign to it (Python
|
|
703
|
+
// instance attributes)? Then an assignment to a receiver member in any
|
|
704
|
+
// method is part of the class's contract.
|
|
705
|
+
memberTypesFromAssignments: false,
|
|
706
|
+
// Does an async function's anonymous future expose properties of its
|
|
707
|
+
// body to callers (Rust auto traits: Send, Sync)?
|
|
708
|
+
asyncReturnIsOpaque: false,
|
|
709
|
+
// Modifiers that let the compiler run a callable and hand callers its
|
|
710
|
+
// VALUE (C++ constexpr/consteval, Rust `const fn`): the body is then
|
|
711
|
+
// part of what a caller relies on. null: no such callables.
|
|
712
|
+
compileTimeCallableMarkers: null,
|
|
713
|
+
// Callable names the language supplies with no import and no
|
|
714
|
+
// declaration (builtins, globals): a bare call of one always means
|
|
715
|
+
// something. null: every callable name is declared or imported.
|
|
716
|
+
ambientCallables: null,
|
|
717
|
+
// Builtins among `ambientCallables` that never return (Python `exit`),
|
|
718
|
+
// and global objects whose every member returns (`console`).
|
|
719
|
+
ambientNeverCallables: null,
|
|
720
|
+
ambientReturningNamespaces: null,
|
|
721
|
+
// How a declaration says "a call of this never returns" (`never`,
|
|
722
|
+
// `NoReturn`): a type checker ends the caller's path at a call of one,
|
|
723
|
+
// and only at a declared one. []: the language has no such type; null:
|
|
724
|
+
// no return contract is read from a body in this language.
|
|
725
|
+
neverReturnTypes: null,
|
|
726
|
+
// Can a type checker decide a condition from the names in it (Python:
|
|
727
|
+
// `sys.version_info`, `sys.platform`, `TYPE_CHECKING`, constants its
|
|
728
|
+
// configuration defines)? Then a condition that guards part of what a
|
|
729
|
+
// body returns is part of it; elsewhere only a condition that names
|
|
730
|
+
// nothing (`while (true)`) is decided.
|
|
731
|
+
namedConditionsDecidable: false,
|
|
732
|
+
// Do files without module syntax share one global scope (classic
|
|
733
|
+
// JavaScript scripts)? Then a top-level name of one is visible in all.
|
|
734
|
+
scriptGlobalScope: false,
|
|
735
|
+
// Are the members of a class compared and enumerated by SHAPE
|
|
736
|
+
// (TypeScript)? Then the trait answers whether anything with the
|
|
737
|
+
// class's members is a value of it: `(classNode, ignoredLines) =>
|
|
738
|
+
// boolean`, true unless the class itself declares a private or
|
|
739
|
+
// protected instance member (members starting on `ignoredLines` left
|
|
740
|
+
// out). null: a class is its declaration, and its members are reached
|
|
741
|
+
// by name only.
|
|
742
|
+
classComparedByShape: null,
|
|
743
|
+
// How a class member takes part in the class's type: `(classNode,
|
|
744
|
+
// name, line) => { role: 'instance' | 'optional' | 'static', hidden }
|
|
745
|
+
// | null`; hidden: private, protected or `#`.
|
|
746
|
+
classMemberRole: null,
|
|
747
|
+
// Members of an object literal declared as a type, read from syntax:
|
|
748
|
+
// `(root, line) => { names, open } | null` (languages/javascript.js).
|
|
749
|
+
typedLiteralMembers: null,
|
|
750
|
+
// The interface whose members every object has (`Object`): a project
|
|
751
|
+
// that declares one adds members to every literal.
|
|
752
|
+
universalObjectInterface: null,
|
|
753
|
+
// Has the language's checker been told not to report a break, as its
|
|
754
|
+
// own scanner reads comments (`// @ts-ignore` above the line the break
|
|
755
|
+
// is reported on, `# type: ignore` on a line of the reported range, a
|
|
756
|
+
// rule turned off for the file)? `(site) => boolean` with site
|
|
757
|
+
// { lines, root, line, kind: 'arity' | 'import-name' | 'import-module'
|
|
758
|
+
// | 'undefined-name' | 'literal', name, most, memo }. A break at such a
|
|
759
|
+
// site is one the toolchain will not show: check lists it and does not
|
|
760
|
+
// block on it.
|
|
761
|
+
checkSuppressedAt: null,
|
|
762
|
+
// The tests a file declares, as its runner collects them:
|
|
763
|
+
// `(fileEntry, helpers) => { units, inheriting }` where a unit is
|
|
764
|
+
// { kind: 'test' | 'suite', name, suite: [names], line, endLine } plus
|
|
765
|
+
// what a selector needs (core/test-units.js). Null: the language's
|
|
766
|
+
// tests are not read, and nothing is said about them.
|
|
767
|
+
testUnits: null,
|
|
768
|
+
// (fileEntry, helpers) => boolean: does this file hold code the runner
|
|
769
|
+
// asks at run time that may leave tests out (a conftest hook, a TestMain).
|
|
770
|
+
testGate: null,
|
|
771
|
+
// `(fileEntry, projectDeclaresType) => { marked, bases }` or null: can
|
|
772
|
+
// a file hold test code, from the index alone (no tree)? Asked before
|
|
773
|
+
// a file whose name is no test file's is read for the tests in it.
|
|
774
|
+
testCodeGate: null,
|
|
775
|
+
// Which family of runners executes the language's tests; the family's
|
|
776
|
+
// manifests are the evidence a runner is named on. Null: none modeled.
|
|
777
|
+
testRunnerFamily: null,
|
|
778
|
+
// Modules whose import in a test file names its runner: `() => Map` of
|
|
779
|
+
// module name to runner id; null where an import says nothing of it.
|
|
780
|
+
testRunnerModules: null,
|
|
781
|
+
// What a module of the language exports under a name, as far as
|
|
782
|
+
// declaring tests goes: `(fileEntry, helpers, name) => binding | null`.
|
|
783
|
+
// A test file that takes its runner through a project module is read
|
|
784
|
+
// through it. Null: imports are not followed.
|
|
785
|
+
testExport: null,
|
|
786
|
+
// How the language's runners name a test file. A test-path file that
|
|
787
|
+
// declares no test and is not named like one is support code.
|
|
788
|
+
testFileNames: [],
|
|
789
|
+
// Is the import of `module` written on a line one the project's judge
|
|
790
|
+
// resolves (an import statement), not a call it never looks into?
|
|
791
|
+
// `(root, line, module) => boolean`; null: every import of the language
|
|
792
|
+
// is a statement.
|
|
793
|
+
checkedImportAt: null,
|
|
794
|
+
// Does a virtual member change what a type IS to existing code (C++: a
|
|
795
|
+
// class with one is no aggregate, so `T t{1, 2}` stops compiling)?
|
|
796
|
+
virtualMemberChangesShape: false,
|
|
519
797
|
// A top-level type lives in a file named after it (fix #386, Java).
|
|
520
798
|
typeNamedSourceFile: false,
|
|
521
799
|
// Compiler-resolved doc references (fix #390, C# crefs).
|
|
@@ -543,6 +821,21 @@ const NOMINAL_TRAITS = {
|
|
|
543
821
|
* lower-case letter is a suffix, not a member. Renaming the identifier or
|
|
544
822
|
* member without the example fails vet ("refers to unknown field or method").
|
|
545
823
|
*/
|
|
824
|
+
// Go satisfies interfaces implicitly, so no `implements` edge exists for
|
|
825
|
+
// compiler/stdlib callbacks. A zero textual usage for one of these exact
|
|
826
|
+
// method shapes is not evidence of deadness (sort.Interface, http.Handler,
|
|
827
|
+
// io.Reader, encoding marshalers, database/sql contracts, errors helpers).
|
|
828
|
+
const GO_STANDARD_CONTRACT_METHODS = new Map([
|
|
829
|
+
['Len', 0], ['Less', 2], ['Swap', 2], ['ServeHTTP', 2],
|
|
830
|
+
['Error', 0], ['String', 0], ['Read', 1], ['Write', 1], ['Close', 0],
|
|
831
|
+
['Seek', 2], ['ReadAt', 2], ['WriteAt', 2], ['ReadByte', 0],
|
|
832
|
+
['WriteByte', 1], ['ReadRune', 0], ['UnreadByte', 0], ['UnreadRune', 0],
|
|
833
|
+
['MarshalJSON', 0], ['UnmarshalJSON', 1], ['MarshalText', 0],
|
|
834
|
+
['UnmarshalText', 1], ['MarshalBinary', 0], ['UnmarshalBinary', 1],
|
|
835
|
+
['Scan', 1], ['Value', 0], ['LogValue', 0], ['Unwrap', 0],
|
|
836
|
+
['Is', 1], ['As', 1],
|
|
837
|
+
]);
|
|
838
|
+
|
|
546
839
|
const GO_EXAMPLE_NAMES = {
|
|
547
840
|
kind: 'go-example',
|
|
548
841
|
prefix: 'Example',
|
|
@@ -581,14 +874,57 @@ const JS_PROTOCOL_MEMBERS = protocolMembers([
|
|
|
581
874
|
{ pattern: /^\[Symbol\.[A-Za-z]+\]$/, member: true },
|
|
582
875
|
]);
|
|
583
876
|
const JS_REFLECTION_API = {
|
|
584
|
-
hintPattern: /\
|
|
877
|
+
hintPattern: /\b(?:Reflect|eval|Function)\b/,
|
|
585
878
|
functions: [{ callee: /^(?:globalThis\.)?Reflect\.(?:get|set|has|deleteProperty)$/,
|
|
586
879
|
nameArg: 1, receiverArg: 0, qualified: true }],
|
|
587
880
|
computedMembers: true,
|
|
588
881
|
namespaceLookups: { calls: /^eval$/ },
|
|
882
|
+
// Every other operation of the Reflect namespace (apply, construct,
|
|
883
|
+
// ownKeys, defineProperty, a decorator's Reflect.metadata).
|
|
884
|
+
unnamed: [{ callee: /^(?:globalThis\.)?Reflect\.\w+$/, qualified: true }],
|
|
885
|
+
// `eval` reached through the global object, and `new Function(code)`.
|
|
886
|
+
codeExecution: [
|
|
887
|
+
{ callee: /^(?:globalThis|window|self)\.eval$/, qualified: true },
|
|
888
|
+
{ construct: /^Function$/ },
|
|
889
|
+
],
|
|
589
890
|
family: 'javascript',
|
|
590
891
|
};
|
|
591
892
|
|
|
893
|
+
// Python's builtin callables: names a bare call can mean with nothing
|
|
894
|
+
// declared or imported.
|
|
895
|
+
const PY_AMBIENT_CALLABLES = new Set([
|
|
896
|
+
'abs', 'aiter', 'all', 'anext', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes',
|
|
897
|
+
'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict',
|
|
898
|
+
'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset',
|
|
899
|
+
'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance',
|
|
900
|
+
'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next',
|
|
901
|
+
'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed',
|
|
902
|
+
'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type',
|
|
903
|
+
'vars', 'zip', '__import__',
|
|
904
|
+
]);
|
|
905
|
+
// Global functions of the JavaScript runtimes (ECMAScript, Node, browsers).
|
|
906
|
+
const JS_AMBIENT_CALLABLES = new Set([
|
|
907
|
+
'parseInt', 'parseFloat', 'isNaN', 'isFinite', 'encodeURI', 'encodeURIComponent', 'decodeURI',
|
|
908
|
+
'decodeURIComponent', 'escape', 'unescape', 'eval', 'require', 'fetch', 'setTimeout', 'setInterval',
|
|
909
|
+
'setImmediate', 'clearTimeout', 'clearInterval', 'clearImmediate', 'queueMicrotask', 'structuredClone',
|
|
910
|
+
'requestAnimationFrame', 'cancelAnimationFrame', 'requestIdleCallback', 'alert', 'confirm', 'prompt',
|
|
911
|
+
'atob', 'btoa', 'postMessage', 'importScripts', 'close', 'open', 'print', 'stop', 'focus', 'blur',
|
|
912
|
+
'scroll', 'scrollTo', 'scrollBy', 'getComputedStyle', 'matchMedia', 'reportError', 'describe', 'it',
|
|
913
|
+
'test', 'expect', 'beforeEach', 'afterEach', 'beforeAll', 'afterAll',
|
|
914
|
+
]);
|
|
915
|
+
|
|
916
|
+
// Global objects of the JavaScript runtimes whose members all return.
|
|
917
|
+
const JS_RETURNING_NAMESPACES = new Set(['console', 'Math', 'JSON', 'Object', 'Array', 'Reflect', 'Number', 'String']);
|
|
918
|
+
|
|
919
|
+
// A TypeScript interface or object type is satisfied by shape: any class or
|
|
920
|
+
// object with its members is one.
|
|
921
|
+
const TS_STRUCTURAL_CONTRACT = typeDef => typeDef.type === 'interface' || typeDef.type === 'type';
|
|
922
|
+
// A Python class that lists Protocol among its bases is a protocol class:
|
|
923
|
+
// type checkers accept any object with its members (PEP 544). A class that
|
|
924
|
+
// only inherits from a protocol is an implementation, not a protocol. The
|
|
925
|
+
// parser records the fact (`protocolClass`), import aliases resolved.
|
|
926
|
+
const PY_STRUCTURAL_CONTRACT = typeDef => typeDef.protocolClass === true;
|
|
927
|
+
|
|
592
928
|
// Language configurations
|
|
593
929
|
const LANGUAGES = {
|
|
594
930
|
javascript: {
|
|
@@ -599,9 +935,25 @@ const LANGUAGES = {
|
|
|
599
935
|
treeSitterModule: () => require('tree-sitter-javascript'),
|
|
600
936
|
traits: {
|
|
601
937
|
...STRUCTURAL_TRAITS,
|
|
938
|
+
checkTypedComment: text => /@ts-check\b|@(?:param|type|returns?)\s*\{/.test(text),
|
|
939
|
+
checkDirectiveComment: text => require('./javascript').checkDirectiveComment(text),
|
|
940
|
+
checkFileDirectiveComment: text => require('./javascript').checkFileDirectiveComment(text),
|
|
941
|
+
checkDirectiveTarget: 'next-line',
|
|
942
|
+
checkDirectiveBarrier: text => text.startsWith('/*'),
|
|
943
|
+
testUnits: (fileEntry, helpers) => require('./javascript').testUnits(fileEntry, helpers),
|
|
944
|
+
testRunnerModules: () => require('./javascript').TEST_RUNNER_MODULES,
|
|
945
|
+
testExport: (fileEntry, helpers, name) => require('./javascript').testExport(fileEntry, helpers, name),
|
|
946
|
+
testRunnerFamily: 'javascript',
|
|
947
|
+
testFileNames: [/\.(test|spec)\.[cm]?[jt]sx?$/, /(^|\/)(test|spec)\.[cm]?[jt]sx?$/, /[-_]test\.[cm]?[jt]sx?$/, /(^|\/)test-[^/]*\.[cm]?[jt]sx?$/],
|
|
602
948
|
selfParam: ['this'],
|
|
603
949
|
reflectionApi: JS_REFLECTION_API,
|
|
604
950
|
languageProtocolMember: JS_PROTOCOL_MEMBERS,
|
|
951
|
+
structuralContract: TS_STRUCTURAL_CONTRACT,
|
|
952
|
+
ambientCallables: JS_AMBIENT_CALLABLES,
|
|
953
|
+
ambientReturningNamespaces: JS_RETURNING_NAMESPACES,
|
|
954
|
+
neverReturnTypes: [],
|
|
955
|
+
checkedImportAt: (root, line, module) => require('./javascript').checkedImportAt(root, line, false, module),
|
|
956
|
+
scriptGlobalScope: true,
|
|
605
957
|
storedPromises: true,
|
|
606
958
|
knownAsyncGlobals: ['fetch'],
|
|
607
959
|
lenientCallArity: true,
|
|
@@ -617,9 +969,30 @@ const LANGUAGES = {
|
|
|
617
969
|
treeSitterModule: () => require('tree-sitter-typescript').typescript,
|
|
618
970
|
traits: {
|
|
619
971
|
...STRUCTURAL_TRAITS,
|
|
972
|
+
checkLiteralArguments: { smallInteger: ['number'], string: ['string'], boolean: ['boolean'] },
|
|
973
|
+
checkDirectiveComment: text => require('./javascript').checkDirectiveComment(text),
|
|
974
|
+
checkFileDirectiveComment: text => require('./javascript').checkFileDirectiveComment(text),
|
|
975
|
+
checkDirectiveTarget: 'next-line',
|
|
976
|
+
checkDirectiveBarrier: text => text.startsWith('/*'),
|
|
977
|
+
testUnits: (fileEntry, helpers) => require('./javascript').testUnits(fileEntry, helpers),
|
|
978
|
+
testRunnerModules: () => require('./javascript').TEST_RUNNER_MODULES,
|
|
979
|
+
testExport: (fileEntry, helpers, name) => require('./javascript').testExport(fileEntry, helpers, name),
|
|
980
|
+
testRunnerFamily: 'javascript',
|
|
981
|
+
testFileNames: [/\.(test|spec)\.[cm]?[jt]sx?$/, /(^|\/)(test|spec)\.[cm]?[jt]sx?$/, /[-_]test\.[cm]?[jt]sx?$/, /(^|\/)test-[^/]*\.[cm]?[jt]sx?$/],
|
|
620
982
|
selfParam: ['this'],
|
|
621
983
|
reflectionApi: JS_REFLECTION_API,
|
|
622
984
|
languageProtocolMember: JS_PROTOCOL_MEMBERS,
|
|
985
|
+
classComparedByShape: (classNode, ignoredLines) => !require('./javascript').classHasNominalMember(classNode, ignoredLines),
|
|
986
|
+
classMemberRole: (classNode, name, line) => require('./javascript').classMemberRole(classNode, name, line),
|
|
987
|
+
typedLiteralMembers: (root, line) => require('./javascript').typedLiteralMembers(root, line),
|
|
988
|
+
universalObjectInterface: 'Object',
|
|
989
|
+
checkSuppressedAt: site => require('./javascript').checkSuppressedAt(site),
|
|
990
|
+
checkedImportAt: (root, line, module) => require('./javascript').checkedImportAt(root, line, true, module),
|
|
991
|
+
structuralContract: TS_STRUCTURAL_CONTRACT,
|
|
992
|
+
ambientCallables: JS_AMBIENT_CALLABLES,
|
|
993
|
+
ambientReturningNamespaces: JS_RETURNING_NAMESPACES,
|
|
994
|
+
neverReturnTypes: ['never'],
|
|
995
|
+
scriptGlobalScope: true,
|
|
623
996
|
storedPromises: true,
|
|
624
997
|
knownAsyncGlobals: ['fetch'],
|
|
625
998
|
testFileCandidates: (base, ext) => [`${base}.test${ext}`, `${base}.spec${ext}`, `${base}.test.ts`, `${base}.test.js`, `${base}.spec.ts`, `${base}.spec.js`],
|
|
@@ -634,9 +1007,30 @@ const LANGUAGES = {
|
|
|
634
1007
|
treeSitterModule: () => require('tree-sitter-typescript').tsx,
|
|
635
1008
|
traits: {
|
|
636
1009
|
...STRUCTURAL_TRAITS,
|
|
1010
|
+
checkLiteralArguments: { smallInteger: ['number'], string: ['string'], boolean: ['boolean'] },
|
|
1011
|
+
checkDirectiveComment: text => require('./javascript').checkDirectiveComment(text),
|
|
1012
|
+
checkFileDirectiveComment: text => require('./javascript').checkFileDirectiveComment(text),
|
|
1013
|
+
checkDirectiveTarget: 'next-line',
|
|
1014
|
+
checkDirectiveBarrier: text => text.startsWith('/*'),
|
|
1015
|
+
testUnits: (fileEntry, helpers) => require('./javascript').testUnits(fileEntry, helpers),
|
|
1016
|
+
testRunnerModules: () => require('./javascript').TEST_RUNNER_MODULES,
|
|
1017
|
+
testExport: (fileEntry, helpers, name) => require('./javascript').testExport(fileEntry, helpers, name),
|
|
1018
|
+
testRunnerFamily: 'javascript',
|
|
1019
|
+
testFileNames: [/\.(test|spec)\.[cm]?[jt]sx?$/, /(^|\/)(test|spec)\.[cm]?[jt]sx?$/, /[-_]test\.[cm]?[jt]sx?$/, /(^|\/)test-[^/]*\.[cm]?[jt]sx?$/],
|
|
637
1020
|
selfParam: ['this'],
|
|
638
1021
|
reflectionApi: JS_REFLECTION_API,
|
|
639
1022
|
languageProtocolMember: JS_PROTOCOL_MEMBERS,
|
|
1023
|
+
classComparedByShape: (classNode, ignoredLines) => !require('./javascript').classHasNominalMember(classNode, ignoredLines),
|
|
1024
|
+
classMemberRole: (classNode, name, line) => require('./javascript').classMemberRole(classNode, name, line),
|
|
1025
|
+
typedLiteralMembers: (root, line) => require('./javascript').typedLiteralMembers(root, line),
|
|
1026
|
+
universalObjectInterface: 'Object',
|
|
1027
|
+
checkSuppressedAt: site => require('./javascript').checkSuppressedAt(site),
|
|
1028
|
+
checkedImportAt: (root, line, module) => require('./javascript').checkedImportAt(root, line, true, module),
|
|
1029
|
+
structuralContract: TS_STRUCTURAL_CONTRACT,
|
|
1030
|
+
ambientCallables: JS_AMBIENT_CALLABLES,
|
|
1031
|
+
ambientReturningNamespaces: JS_RETURNING_NAMESPACES,
|
|
1032
|
+
neverReturnTypes: ['never'],
|
|
1033
|
+
scriptGlobalScope: true,
|
|
640
1034
|
storedPromises: true,
|
|
641
1035
|
knownAsyncGlobals: ['fetch'],
|
|
642
1036
|
testFileCandidates: (base, ext) => [`${base}.test${ext}`, `${base}.spec${ext}`, `${base}.test.ts`, `${base}.test.js`, `${base}.spec.ts`, `${base}.spec.js`],
|
|
@@ -651,7 +1045,26 @@ const LANGUAGES = {
|
|
|
651
1045
|
treeSitterModule: () => require('tree-sitter-python'),
|
|
652
1046
|
traits: {
|
|
653
1047
|
...STRUCTURAL_TRAITS,
|
|
1048
|
+
checkLiteralArguments: { smallInteger: ['int', 'float'], string: ['str'], boolean: ['bool'] },
|
|
1049
|
+
checkDirectiveComment: text => require('./python').checkDirectiveComment(text),
|
|
1050
|
+
checkFileDirectiveComment: text => require('./python').checkFileDirectiveComment(text),
|
|
1051
|
+
testUnits: (fileEntry, helpers) => require('./python').testUnits(fileEntry, helpers),
|
|
1052
|
+
testRunnerFamily: 'python',
|
|
1053
|
+
testFileNames: [/^test_[^/]*\.py$/, /_test\.py$/],
|
|
1054
|
+
// `yield` in the body makes the callable a generator.
|
|
1055
|
+
callableKindFromBody: ['generator'],
|
|
654
1056
|
selfParam: ['self', 'cls'],
|
|
1057
|
+
structuralContract: PY_STRUCTURAL_CONTRACT,
|
|
1058
|
+
moduleNamesImportable: true,
|
|
1059
|
+
moduleSupplyHooks: ['__getattr__', '__path__'],
|
|
1060
|
+
packageFileOptional: true,
|
|
1061
|
+
memberTypesFromAssignments: true,
|
|
1062
|
+
ambientCallables: PY_AMBIENT_CALLABLES,
|
|
1063
|
+
ambientNeverCallables: new Set(['exit', 'quit']),
|
|
1064
|
+
neverReturnTypes: ['NoReturn', 'Never'],
|
|
1065
|
+
namedConditionsDecidable: true,
|
|
1066
|
+
checkSuppressedAt: site => require('./python').checkSuppressedAt(site),
|
|
1067
|
+
checkedImportAt: (root, line, module) => require('./python').checkedImportAt(root, line, module),
|
|
655
1068
|
// `cls(..)` in a classmethod (or an implicit one), `type(self)(..)`
|
|
656
1069
|
// and `self.__class__(..)` in an instance method construct the
|
|
657
1070
|
// method's class through its first parameter (fix #434).
|
|
@@ -677,8 +1090,10 @@ const LANGUAGES = {
|
|
|
677
1090
|
classesCallableWithoutNew: true,
|
|
678
1091
|
constructorInheritance: { order: 'c3', classNodes: ['class_definition'], headerField: 'superclasses', keywordNode: 'keyword_argument' },
|
|
679
1092
|
constructorProtocol: { initializer: '__init__', allocator: '__new__', metaclass: 'metaclass', builtinRoot: 'object',
|
|
1093
|
+
metaclassMethods: ['__call__', '__new__', '__init__'], identityMembers: ['__class__', '__getattribute__', '__getattr__'], identityOverrides: ['__getattribute__', '__setattr__', '__delattr__'],
|
|
680
1094
|
functionNode: 'function_definition', classNode: 'class_definition',
|
|
681
1095
|
headerField: 'superclasses', keywordNode: 'keyword_argument' },
|
|
1096
|
+
contextEnterMethods: ['__enter__', '__aenter__'],
|
|
682
1097
|
// Call sites bind by parameter name (f(x=1)); signatures carry
|
|
683
1098
|
// keyword-only (`*`) and positional-only (`/`) markers (fix #281).
|
|
684
1099
|
keywordArguments: true,
|
|
@@ -748,9 +1163,13 @@ const LANGUAGES = {
|
|
|
748
1163
|
owners: ['Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag', 'ReprEnum'] },
|
|
749
1164
|
]),
|
|
750
1165
|
reflectionApi: {
|
|
751
|
-
|
|
1166
|
+
pythonBindingIdentity: true,
|
|
1167
|
+
hintPattern: /\b(?:getattr|setattr|hasattr|delattr|eval|exec|globals|vars|patch|MonkeyPatch)\b/,
|
|
752
1168
|
functions: [{ callee: /^(?:getattr|setattr|hasattr|delattr)$/, nameArg: 1, receiverArg: 0 }],
|
|
753
1169
|
namespaceLookups: { calls: /^eval$/, subscriptOf: /^(?:globals|vars)\(\)$/ },
|
|
1170
|
+
// `exec(code)` runs statements; it names nothing a lookup
|
|
1171
|
+
// could be matched against.
|
|
1172
|
+
codeExecution: [{ callee: /^exec$/ }],
|
|
754
1173
|
},
|
|
755
1174
|
testFileCandidates: (base, ext) => [`test_${base}.py`, `${base}_test.py`],
|
|
756
1175
|
testDirs: ['tests'],
|
|
@@ -764,9 +1183,15 @@ const LANGUAGES = {
|
|
|
764
1183
|
treeSitterModule: () => require('tree-sitter-go'),
|
|
765
1184
|
traits: {
|
|
766
1185
|
...NOMINAL_TRAITS,
|
|
1186
|
+
checkLiteralArguments: { smallInteger: ['int', 'int8', 'int16', 'int32', 'int64', 'uint', 'uint8', 'uint16', 'uint32', 'uint64', 'uintptr', 'float32', 'float64'], string: ['string'], boolean: ['bool'] },
|
|
1187
|
+
testUnits: (fileEntry, helpers) => require('./go').testUnits(fileEntry, helpers),
|
|
1188
|
+
testGate: (fileEntry, helpers) => require('./go').testGate(fileEntry, helpers),
|
|
1189
|
+
testRunnerFamily: 'go',
|
|
1190
|
+
testFileNames: [/_test\.go$/],
|
|
767
1191
|
selfParam: null,
|
|
768
1192
|
packageScope: 'directory',
|
|
769
1193
|
nameReferenceFamily: 'go',
|
|
1194
|
+
discardIdentifierNames: ['_'],
|
|
770
1195
|
closedQueryBodies: ['function_declaration', 'method_declaration', 'func_literal'],
|
|
771
1196
|
hasReceiverPackageCalls: true,
|
|
772
1197
|
exportVisibility: 'capitalization',
|
|
@@ -778,9 +1203,13 @@ const LANGUAGES = {
|
|
|
778
1203
|
members: [{ member: /^(?:MethodByName|FieldByName)$/, nameArg: 0 }],
|
|
779
1204
|
membersOnly: true,
|
|
780
1205
|
formatCalls: { 'fmt.Sprintf': 'percent' },
|
|
1206
|
+
// Every function of the reflect package, under whatever
|
|
1207
|
+
// name the file imports it.
|
|
1208
|
+
unnamed: [{ package: 'reflect' }],
|
|
781
1209
|
},
|
|
782
1210
|
testFileCandidates: (base, ext) => [`${base}_test.go`],
|
|
783
1211
|
nameBoundTestFunctions: GO_EXAMPLE_NAMES,
|
|
1212
|
+
implicitStandardContracts: GO_STANDARD_CONTRACT_METHODS,
|
|
784
1213
|
// One package-level name declared in files of one package under
|
|
785
1214
|
// different build constraints is one item (fix #425).
|
|
786
1215
|
conditionalDefinitions: 'build-constraint',
|
|
@@ -794,6 +1223,16 @@ const LANGUAGES = {
|
|
|
794
1223
|
treeSitterModule: () => require('tree-sitter-rust'),
|
|
795
1224
|
traits: {
|
|
796
1225
|
...NOMINAL_TRAITS,
|
|
1226
|
+
checkLiteralArguments: { smallInteger: ['i8', 'i16', 'i32', 'i64', 'i128', 'isize', 'u8', 'u16', 'u32', 'u64', 'u128', 'usize'], string: ['&str'], boolean: ['bool'] },
|
|
1227
|
+
testUnits: (fileEntry, helpers) => require('./rust').testUnits(fileEntry, helpers),
|
|
1228
|
+
testRunnerFamily: 'rust',
|
|
1229
|
+
testFileNames: [/(^|\/)tests\/[^/]+\.rs$/],
|
|
1230
|
+
// `-> impl Trait` hides the type but leaks the value's auto traits.
|
|
1231
|
+
inferredReturnForms: ['opaque', 'evaluated'],
|
|
1232
|
+
// `async fn` returns an anonymous future whose auto traits
|
|
1233
|
+
// (Send, Sync) come from what the body holds across an await.
|
|
1234
|
+
asyncReturnIsOpaque: true,
|
|
1235
|
+
compileTimeCallableMarkers: ['const'],
|
|
797
1236
|
selfParam: ['self', '&self', '&mut self', 'mut self'],
|
|
798
1237
|
inherentMethodsPrecedeTraitImpls: true,
|
|
799
1238
|
derefFieldAccess: true,
|
|
@@ -870,6 +1309,10 @@ const LANGUAGES = {
|
|
|
870
1309
|
parseRecovery: () => require('./java').recoverTypeAnnotatedVarargs,
|
|
871
1310
|
traits: {
|
|
872
1311
|
...NOMINAL_TRAITS,
|
|
1312
|
+
testUnits: (fileEntry, helpers) => require('./java').testUnits(fileEntry, helpers),
|
|
1313
|
+
testCodeGate: (fileEntry, projectDeclaresType) => require('./java').testCodeGate(fileEntry, projectDeclaresType),
|
|
1314
|
+
testRunnerFamily: 'java',
|
|
1315
|
+
testFileNames: [/^Test[^/]*\.java$/, /Tests?\.java$/, /TestCase\.java$/, /IT\.java$/],
|
|
873
1316
|
// A method overrides/implements every supertype's same-signature
|
|
874
1317
|
// member, an inherited one included (JLS 8.4.8) (fix #426).
|
|
875
1318
|
memberFillsSupertypeSlots: true,
|
|
@@ -958,12 +1401,14 @@ const LANGUAGES = {
|
|
|
958
1401
|
possibleViaExternal: { except: JAVA_LANG_NOT_SERIALIZABLE, shape: javaSerializationShape } },
|
|
959
1402
|
]),
|
|
960
1403
|
reflectionApi: {
|
|
961
|
-
hintPattern: /\b(?:getMethod|getDeclaredMethod|getField|getDeclaredField)\b/,
|
|
1404
|
+
hintPattern: /\b(?:getMethod|getDeclaredMethod|getField|getDeclaredField|forName)\b/,
|
|
962
1405
|
members: [{ member: /^(?:getMethod|getDeclaredMethod|getField|getDeclaredField)$/, nameArg: 0 }],
|
|
963
1406
|
membersOnly: true,
|
|
964
1407
|
formatCalls: { 'String.format': 'percent' },
|
|
965
1408
|
selfTypeCalls: ['getClass'],
|
|
966
1409
|
typeLiteralNodes: ['class_literal'],
|
|
1410
|
+
// A class loaded by its name.
|
|
1411
|
+
unnamed: [{ callee: /^(?:java\.lang\.)?Class\.forName$/, qualified: true }],
|
|
967
1412
|
},
|
|
968
1413
|
bareCallReachesMethods: true,
|
|
969
1414
|
testFileCandidates: (base, ext) => [`${base}Test.java`, `${base}Tests.java`, `${base}TestCase.java`],
|
|
@@ -977,6 +1422,7 @@ const LANGUAGES = {
|
|
|
977
1422
|
treeSitterModule: () => require('tree-sitter-c'),
|
|
978
1423
|
traits: {
|
|
979
1424
|
...NOMINAL_TRAITS,
|
|
1425
|
+
checkLiteralArguments: { smallInteger: ['int', 'short', 'long', 'long long', 'unsigned', 'unsigned int', 'unsigned short', 'unsigned long', 'unsigned long long', 'float', 'double'] },
|
|
980
1426
|
selfParam: null,
|
|
981
1427
|
packageScope: 'file',
|
|
982
1428
|
nameReferenceFamily: 'c',
|
|
@@ -1007,6 +1453,12 @@ const LANGUAGES = {
|
|
|
1007
1453
|
treeSitterModule: () => require('tree-sitter-cpp'),
|
|
1008
1454
|
traits: {
|
|
1009
1455
|
...NOMINAL_TRAITS,
|
|
1456
|
+
// `auto` / `decltype(auto)` return types are deduced from the body.
|
|
1457
|
+
// 'instantiated': a template's body is checked against each
|
|
1458
|
+
// caller's arguments.
|
|
1459
|
+
inferredReturnForms: ['placeholder', 'instantiated', 'evaluated'],
|
|
1460
|
+
virtualMemberChangesShape: true,
|
|
1461
|
+
compileTimeCallableMarkers: ['constexpr', 'consteval'],
|
|
1010
1462
|
// An override overrides every base's virtual of its signature; an
|
|
1011
1463
|
// inherited member never implements another base's pure virtual
|
|
1012
1464
|
// (fix #426).
|
|
@@ -1076,6 +1528,10 @@ const LANGUAGES = {
|
|
|
1076
1528
|
treeSitterModule: () => require('tree-sitter-c-sharp'),
|
|
1077
1529
|
traits: {
|
|
1078
1530
|
...NOMINAL_TRAITS,
|
|
1531
|
+
testUnits: (fileEntry, helpers) => require('./csharp').testUnits(fileEntry, helpers),
|
|
1532
|
+
testCodeGate: (fileEntry, projectDeclaresType) => require('./csharp').testCodeGate(fileEntry, projectDeclaresType),
|
|
1533
|
+
testRunnerFamily: 'dotnet',
|
|
1534
|
+
testFileNames: [/Tests?\.cs$/],
|
|
1079
1535
|
// Interface mapping takes inherited members (C# spec 18.6.5); a
|
|
1080
1536
|
// `new` member hides the inherited one, starting a slot of its
|
|
1081
1537
|
// own (fix #426).
|
|
@@ -1110,6 +1566,7 @@ const LANGUAGES = {
|
|
|
1110
1566
|
standardPathRoots: ['System'],
|
|
1111
1567
|
conditionalDefinitions: 'preprocessor',
|
|
1112
1568
|
typeNameScoping: 'namespace-usings',
|
|
1569
|
+
platformTypeForms: { nullable: 'System.Nullable', tuple: 'System.ValueTuple' },
|
|
1113
1570
|
constructorArgumentNodes: { delegation: { nodeType: 'constructor_initializer', argsNodeType: 'argument_list' } },
|
|
1114
1571
|
genericArityIsIdentity: true,
|
|
1115
1572
|
typeArgumentsFromArgumentsOnly: true,
|
|
@@ -1178,6 +1635,11 @@ const LANGUAGES = {
|
|
|
1178
1635
|
treeSitterModule: () => require('tree-sitter-html'),
|
|
1179
1636
|
traits: {
|
|
1180
1637
|
...STRUCTURAL_TRAITS,
|
|
1638
|
+
checkTypedComment: text => /@ts-check\b|@(?:param|type|returns?)\s*\{/.test(text),
|
|
1639
|
+
checkDirectiveComment: text => require('./javascript').checkDirectiveComment(text),
|
|
1640
|
+
checkFileDirectiveComment: text => require('./javascript').checkFileDirectiveComment(text),
|
|
1641
|
+
checkDirectiveTarget: 'next-line',
|
|
1642
|
+
checkDirectiveBarrier: text => text.startsWith('/*'),
|
|
1181
1643
|
lenientCallArity: true,
|
|
1182
1644
|
// Embedded scripts supply their own parse trees.
|
|
1183
1645
|
physicalCallTokenSyntax: false,
|