You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -91,75 +91,271 @@ new Base(); // Should error - cannot instantiate abstract class
91
91
```
92
92
93
93
94
-
# Fourslash Testing
95
-
96
-
> Fourslash is our testing system for language service functionality
97
-
98
-
Fourslash tests are interactive TypeScript language service tests. They validate IDE features like completions, quick info, navigation, and refactoring. You create a new fourslash test by putting a file in `tests/cases/fourslash`.
99
-
100
-
They have a "user code" section, prefixed by four slashes per line, followed by one or more instructions for what to do with the code. Within the code, a `/**/` comment creates an anonymous "marker"; named markers use alphanumeric text between the stars (`/*here*/`). You can use the markers to refer to specific positions in the code:
101
-
```typescript
102
-
////function foo(x: number) {
103
-
//// return x + 1;
104
-
////}
105
-
////let result = foo(/**/42);
106
-
107
-
goTo.marker();
108
-
verify.baselineSignatureHelp();
109
-
```
110
-
111
-
Use `// @Filename:` to define multiple files:
112
-
```typescript
113
-
// @Filename: /a.ts
114
-
////export const value = 42;
115
-
116
-
// @Filename: /b.ts
117
-
////import { value } from './a';
118
-
////console.log(/*marker*/value);
119
-
```
120
-
121
-
Use `[|text|]` to define text ranges, which can be used for selecting text or describing expected Find All References results.
122
-
```typescript
123
-
////function test() {
124
-
//// [|return 42;|]
125
-
////}
126
-
```
127
-
128
-
More code examples:
129
-
```typescript
130
-
// Moving the virtual caret around
131
-
goTo.marker("markerName"); // Navigate to marker
132
-
goTo.marker(); // Navigate to anonymous marker /**/
133
-
134
-
// Verifying expected results (generally preferred over baselines in these tests)
> Technical overview of how symbols in TypeScript work
97
+
98
+
TypeScript's binder creates symbols that represent declarations in your code, and the checker uses these symbols for type checking and name resolution. Understanding this system is crucial for debugging complex issues and understanding how TypeScript resolves names and types.
99
+
100
+
## What are Symbols?
101
+
102
+
Symbols are TypeScript's internal representation of declarations. Each symbol has:
103
+
104
+
-**flags**: A bitmask from `SymbolFlags` enum that describes what kind of declaration it represents
105
+
-**escapedName**: The internal string representation of the symbol's name
106
+
-**declarations**: Array of AST nodes that declare this symbol
107
+
-**members**: SymbolTable for nested symbols (class members, interface properties, etc.)
108
+
-**exports**: SymbolTable for module exports
109
+
- Internal tracking fields for type checking and resolution
110
+
111
+
```ts
112
+
// From types.ts
113
+
exportinterfaceSymbol {
114
+
flags:SymbolFlags; // Symbol flags
115
+
escapedName:__String; // Name of symbol
116
+
declarations?:Declaration[]; // Declarations associated with this symbol
117
+
valueDeclaration?:Declaration; // First value declaration of the symbol
118
+
members?:SymbolTable; // Class, interface or object literal instance members
119
+
exports?:SymbolTable; // Module exports
120
+
// ... additional internal fields
121
+
}
122
+
```
123
+
124
+
## SymbolFlags
125
+
126
+
SymbolFlags is a bitmask enum that categorizes what kinds of declarations a symbol represents:
- Scope hierarchy determines which symbol is found
269
+
- The binder creates appropriate symbol tables for different scopes
270
+
271
+
## Symbol Merging
272
+
273
+
Some declarations can merge their symbols:
274
+
- Multiple `var` declarations with same name
275
+
- `interface` declarations merge their members
276
+
- `namespace` and `enum` can merge with compatible declarations
277
+
- Classes and interfaces can merge (declaration merging)
278
+
279
+
The binder handles this by checking `excludes` flags and either merging with existing symbols or creating conflicts.
280
+
281
+
## Debugging Tips
282
+
283
+
When debugging symbol-related issues:
284
+
1. Check what SymbolFlags a symbol has using `symbol.flags&SymbolFlags.SomeFlag`
285
+
2. Print symbol names with `symbolToString()` or `symbol.escapedName`
286
+
3. Examine symbol.declarations to see all AST nodes for that symbol
287
+
4. Use checker's `getSymbolAtLocation()` to see what symbol a node resolves to
288
+
5. Check if you're looking for the right meaning (Type vs Value vs Namespace)
289
+
290
+
# Fourslash Testing
291
+
292
+
> Fourslash is our testing system for language service functionality
293
+
294
+
Fourslash tests are interactive TypeScript language service tests. They validate IDE features like completions, quick info, navigation, and refactoring. You create a new fourslash test by putting a file in `tests/cases/fourslash`.
295
+
296
+
They have a "user code" section, prefixed by four slashes per line, followed by one or more instructions for what to do with the code. Within the code, a `/**/` comment creates an anonymous "marker"; named markers use alphanumeric text between the stars (`/*here*/`). You can use the markers to refer to specific positions in the code:
297
+
```typescript
298
+
////function foo(x: number) {
299
+
//// return x + 1;
300
+
////}
301
+
////let result = foo(/**/42);
302
+
303
+
goTo.marker();
304
+
verify.baselineSignatureHelp();
305
+
```
306
+
307
+
Use `// @Filename:` to define multiple files:
308
+
```typescript
309
+
// @Filename: /a.ts
310
+
////export const value = 42;
311
+
312
+
// @Filename: /b.ts
313
+
////import { value } from './a';
314
+
////console.log(/*marker*/value);
315
+
```
316
+
317
+
Use `[|text|]` to define text ranges, which can be used for selecting text or describing expected Find All References results.
318
+
```typescript
319
+
////function test() {
320
+
//// [|return 42;|]
321
+
////}
322
+
```
323
+
324
+
More code examples:
325
+
```typescript
326
+
// Moving the virtual caret around
327
+
goTo.marker("markerName"); // Navigate to marker
328
+
goTo.marker(); // Navigate to anonymous marker /**/
329
+
330
+
// Verifying expected results (generally preferred over baselines in these tests)
Questions I have that I think the developers of this project can help me with:
2
-
* How does control flow analysis represent a circular graph? I checked the documentation server for "cfa" and "control flow"
3
-
* How do I tell if a symbol is in the global scope? I checked the documentation server for topics referencing "symbol" and "global"
4
-
* What is an `EscapedName`, exactly?
1
+
Questions I have that I think the developers of this project can help me with:
2
+
* How does control flow analysis represent a circular graph? I checked the documentation server for "cfa" and "control flow"
3
+
* How do I tell if a symbol is in the global scope? I checked the documentation server for topics referencing "symbol" and "global"
4
+
* What is an `EscapedName`, exactly?
5
+
* How does the binder handle complex symbol merging scenarios like when a namespace merges with a class that merges with an interface? I searched for "symbol merging", "declaration merging", and "namespace class interface merge" but want to understand the exact algorithm.
0 commit comments