Rule 2.1
Chapter 2, Sources of the surface Test
Every author-facing name must come from exactly one of three sources:
- (a) WGSL, as the specification spells it: a built-in function, a predeclared type or type-generator including the predeclared
vecNf/vecNi/vecNualiases, an attribute reached as a decorator, a built-in value passed as a string, or an extension name; - (b) ECMAScript, as TypeScript spells it: a member of
Math, a method ofconsole, a methodArray.prototypehas, written on an array (surface §63), a literal, an operator, the declaration formsclass,interface,enum, andnamespace, the standard-library declarations the ambient file restates for alib: []program, and the shapes surface §14 and §28 admit; - (c) the TypeShade extensions enumerated in §9.3 of this document, one row per name with its reason.
The rule text and the parts under it are the compiler's own English, as the design document writes them.
Rationale
a name with a source has a meaning an author can look up; a name with no source has only the compiler’s word for what it does.
Derives from
PR #166’s body, section “A design rule this lane settled” (“No TypeShade-internal helper becomes an author-facing spelling”), and Declaration and Scope.
How it is verified
Checked by a test. A test, a gate script or a CI workflow names this rule, and the traceability check fails when a file listed below stops naming it.
Where the rule says the compiler enforces it:
src/core/spec-conformance/surface-names.test.ts, which classifies every declared name against fixtures/wgsl-names.json, the running engine’s Math and console, and TYPESHADE_EXTENSIONS, and holds each method the library declares on an array to the running engine’s Array.prototype; and the front end, which resolves a name by what declares it and never by its spelling (proposal 0008): a name nothing declares is TS8022 for a value and TS8004 for a callee, in a body a call lowers and in one no call lowers alike, and TS8002 for a type wherever it is written, the base a class or an interface extends and an argument of a WGSL generic that is a type argument of a class included, once, in the compiler and in the editor alike (TypeScript’s TS2304, TS2583, TS2584, TS2591 and TS2580 merge into it), a name the file declares is the file’s whatever it spells, ahead of a type the library declares of the name, and a declaration of the file wins over a §9.3 constant of its name, and an enum, a namespace, a class or a type the file declares, read as a value, says what it is and the value it offers, once (TS8022, TypeScript’s report about its typeof merged into it), pinned by src/compiler/ts/host-names.test.ts and src/language-service/diagnostics.test.ts; the two spellings ECMAScript’s strict mode lets no declaration bind, eval and arguments, are refused once where a variable, a parameter or a function binds one, TS8068, as TypeScript’s TS1215 refuses them (TS1215, TS1210 and TS1100 merge into it, and so does what TypeScript says of a later write of the name), while a class, an enum, a namespace or a type of the name is the file’s, as TypeScript takes it, pinned by src/compiler/ts/host-names.test.ts; a new finds its class the same way, with what another block of a namespace exports, and a type annotation inside a namespace finds the class the new there builds, pinned by src/compiler/ts/new-expression.test.ts; the ambient library’s own types and values are names the compiler knows are declared, a type of its own says it is one where a type, a value or a callee is read (TypeScript’s TS2693 merges into it), and a shader type is none of them, pinned by src/language-service/ambient-parity.test.ts and src/compiler/ts/host-names.test.ts; and a member is looked up on its receiver, so a class field reverse or a method swizzle is the class’s, pinned by src/compiler/ts/class-methods.test.ts.
The files that verify it at commit 26de7be8, each at the first line that names the rule:
-
src/compiler/ts/class-methods.test.ts:200 -
src/compiler/ts/host-names.test.ts:1 -
src/compiler/ts/matrix-f-aliases.test.ts:4 -
src/compiler/ts/new-expression.test.ts:113 -
src/core/spec-conformance/surface-names.test.ts:136 -
src/language-service/ambient-parity.test.ts:238 -
src/language-service/diagnostics.test.ts:823
Explained in
The sections of the surface document that explain this rule, at commit 26de7be8:
Error codes that enforce it
The diagnostic codes the rule names under Enforced by, or whose registry text names the rule:
-
TS8002UNKNOWN_TYPE - A type name nothing declares, said once for the file wherever it is written (a parameter, a claim, a type argument,
B<vec3<Foo>>included, an alias, animplementsclause, the base a class or an interface extends, a body no call lowers), a type the library declares for TypeScript alone (Number) where the file declares none of its name, or a type this surface does not take in a position the mapper reads (Rule 2.1). -
TS8004UNKNOWN_FN - A call to a function the file neither declares nor imports.
-
TS8022UNKNOWN_NAME - Reference to a name TypeShade cannot resolve (identifier, struct field, or struct shape) that is not a function call (
UNKNOWN_FN) or a type name (UNKNOWN_TYPE), in a body a call lowers or in one no call lowers; a name the library declares for TypeScript's own use (Object,Math,Symbol), or the file declares as an enum, a namespace, a class or a type, read as a value says what it is. -
TS8068RESERVED_NAME - A declared name that a target reserves, checked on the name the emit actually carries:
halfas a struct field, which ANGLE answers with "Illegal use of reserved word" in generated text the author never wrote.
See also
- Rule 1.3 Test
- Rule 2.2 Test
- Design rules
- Error codes
Source
The rule at commit 26de7be8:
docs/language-design.md:92(the design document)reqs/rules/RULE-0201.md(its traceability item)