Skip to content

Commit 9c3114d

Browse files
committed
fix!: isExported should use the type checker
This partially adds support for export declarations under the same name. BREAKING CHANGE: Global files previously had all declarations marked as not-exported. This was inconsistent with TypeScript's concept of visibility. Now non-modules will have all members exported.
1 parent f388b42 commit 9c3114d

File tree

34 files changed

+236
-209
lines changed

34 files changed

+236
-209
lines changed

src/lib/converter/context.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ export class Context {
151151
return nodeType;
152152
}
153153

154+
getSymbolAtLocation(node: ts.Node): ts.Symbol | undefined {
155+
let symbol = this.checker.getSymbolAtLocation(node);
156+
if (!symbol && isNamedNode(node)) {
157+
symbol = this.checker.getSymbolAtLocation(node.name);
158+
}
159+
return symbol;
160+
}
161+
154162
/**
155163
* Return the current logger instance.
156164
*
@@ -390,3 +398,10 @@ export class Context {
390398
return typeParameters;
391399
}
392400
}
401+
402+
function isNamedNode(node: ts.Node): node is ts.Node & { name: ts.Identifier | ts.ComputedPropertyName } {
403+
return node.hasOwnProperty('name') && (
404+
ts.isIdentifier(node['name']) ||
405+
ts.isComputedPropertyName(node['name'])
406+
);
407+
}

src/lib/converter/convert-expression.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ export function convertExpression(expression: ts.Expression): string {
2626
return 'true';
2727
case ts.SyntaxKind.FalseKeyword:
2828
return 'false';
29+
case ts.SyntaxKind.NullKeyword:
30+
return 'null';
2931
default:
30-
const source = expression.getSourceFile();
31-
return source.text.substring(expression.pos, expression.end);
32+
return expression.getText(expression.getSourceFile());
3233
}
3334
}

src/lib/converter/factories/declaration.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,15 @@ export function createDeclaration(context: Context, node: ts.Declaration, kind:
7171

7272
// Test whether the node is exported
7373
let isExported: boolean;
74-
if (container.kindOf([ReflectionKind.Module, ReflectionKind.ExternalModule])) {
75-
isExported = false; // Don't inherit exported state in modules and namespaces
74+
if (kind === ReflectionKind.ExternalModule || kind === ReflectionKind.Global) {
75+
isExported = true;
76+
} else if (container.kindOf([ReflectionKind.Module, ReflectionKind.ExternalModule])) {
77+
const symbol = context.getSymbolAtLocation(node);
78+
isExported = !!symbol?.parent?.exports?.get(symbol.escapedName);
7679
} else {
7780
isExported = container.flags.isExported;
7881
}
7982

80-
if (kind === ReflectionKind.ExternalModule) {
81-
isExported = true; // Always mark external modules as exported
82-
} else if (node.parent && node.parent.kind === ts.SyntaxKind.VariableDeclarationList) {
83-
const parentModifiers = ts.getCombinedModifierFlags(node.parent.parent as ts.Declaration);
84-
isExported = isExported || !!(parentModifiers & ts.ModifierFlags.Export);
85-
} else {
86-
isExported = isExported || !!(modifiers & ts.ModifierFlags.Export);
87-
}
88-
8983
if (!isExported && context.converter.excludeNotExported) {
9084
return;
9185
}

src/lib/models/reflections/abstract.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,18 @@ export class ReflectionFlags extends Array<string> {
139139
}
140140

141141
/**
142-
* Is this member exported?
142+
* True if the reflection is exported from its containing declaration. Note that if a file
143+
* has no imports or exports, then TS assumes that the file is in a global scope and *all*
144+
* declarations are exported.
145+
* ```ts
146+
* // a.ts
147+
* namespace A { // isExported = false
148+
* export const b = 1 // isExported = true, even though the container is false.
149+
* }
150+
* export const b = 2 // isExported = true
151+
* // b.ts
152+
* const c = 1 // isExported = true, no imports/exports
153+
* ```
143154
*/
144155
get isExported(): boolean {
145156
return this.hasFlag(ReflectionFlag.Exported);

src/test/converter.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ describe('Converter', function() {
6969
module: 'CommonJS',
7070
experimentalDecorators: true,
7171
jsx: 'react',
72-
name: 'typedoc'
72+
name: 'typedoc',
73+
ignoreCompilerErrors: true
7374
});
7475
});
7576

@@ -114,7 +115,8 @@ describe('Converter with categorizeByGroup=false', function() {
114115
experimentalDecorators: true,
115116
categorizeByGroup: false,
116117
jsx: 'react',
117-
name: 'typedoc'
118+
name: 'typedoc',
119+
ignoreCompilerErrors: true
118120
});
119121
});
120122

@@ -169,7 +171,8 @@ describe('Converter with excludeNotExported=true', function() {
169171
experimentalDecorators: true,
170172
excludeNotExported: true,
171173
jsx: 'react',
172-
name: 'typedoc'
174+
name: 'typedoc',
175+
ignoreCompilerErrors: true
173176
});
174177
});
175178

src/test/converter/array/specs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4057,7 +4057,7 @@
40574057
}
40584058
}
40594059
},
4060-
"defaultValue": " []"
4060+
"defaultValue": "[]"
40614061
},
40624062
{
40634063
"id": 233,
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
/**
22
* A class with constructor properties.
33
*/
4-
class Vector2
5-
{
4+
class Vector2 {
65
/**
76
* @param x X component of the Vector
87
* @param y Y component of the Vector
98
* @param name Vector name
109
*/
11-
constructor(public x:number, public y:number,
10+
constructor(public x: number, public y: number,
1211
readonly name: string) {
1312
}
1413
}
1514

16-
1715
/**
1816
* A class with inherited and overwritten constructor properties.
1917
*/
20-
class Vector3 extends Vector2
21-
{
18+
class Vector3 extends Vector2 {
2219
/**
2320
* @param x X component of the Vector
2421
* @param y Y component of the Vector
2522
* @param z Z component of the Vector
2623
* @param name Vector name
2724
*/
28-
constructor(x:number, public y:number, public z:number,
25+
constructor(x: number, public y: number, public z: number,
2926
readonly name: string) {
3027
super(x, y, name);
3128
}
3229
}
30+
31+
export {};

src/test/converter/constructor-properties/specs.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@
9393
"sources": [
9494
{
9595
"fileName": "constructor-properties.ts",
96-
"line": 5,
97-
"character": 1
96+
"line": 4,
97+
"character": 15
9898
}
9999
]
100100
},
@@ -112,7 +112,7 @@
112112
"sources": [
113113
{
114114
"fileName": "constructor-properties.ts",
115-
"line": 12,
115+
"line": 11,
116116
"character": 29
117117
}
118118
],
@@ -136,7 +136,7 @@
136136
"sources": [
137137
{
138138
"fileName": "constructor-properties.ts",
139-
"line": 11,
139+
"line": 10,
140140
"character": 24
141141
}
142142
],
@@ -160,8 +160,8 @@
160160
"sources": [
161161
{
162162
"fileName": "constructor-properties.ts",
163-
"line": 11,
164-
"character": 41
163+
"line": 10,
164+
"character": 42
165165
}
166166
],
167167
"type": {
@@ -301,8 +301,8 @@
301301
"sources": [
302302
{
303303
"fileName": "constructor-properties.ts",
304-
"line": 21,
305-
"character": 1
304+
"line": 18,
305+
"character": 31
306306
}
307307
],
308308
"overwrites": {
@@ -325,7 +325,7 @@
325325
"sources": [
326326
{
327327
"fileName": "constructor-properties.ts",
328-
"line": 29,
328+
"line": 26,
329329
"character": 29
330330
}
331331
],
@@ -354,7 +354,7 @@
354354
"sources": [
355355
{
356356
"fileName": "constructor-properties.ts",
357-
"line": 11,
357+
"line": 10,
358358
"character": 24
359359
}
360360
],
@@ -383,8 +383,8 @@
383383
"sources": [
384384
{
385385
"fileName": "constructor-properties.ts",
386-
"line": 28,
387-
"character": 34
386+
"line": 25,
387+
"character": 35
388388
}
389389
],
390390
"type": {
@@ -412,8 +412,8 @@
412412
"sources": [
413413
{
414414
"fileName": "constructor-properties.ts",
415-
"line": 28,
416-
"character": 51
415+
"line": 25,
416+
"character": 53
417417
}
418418
],
419419
"type": {
@@ -444,7 +444,7 @@
444444
"sources": [
445445
{
446446
"fileName": "constructor-properties.ts",
447-
"line": 20,
447+
"line": 18,
448448
"character": 13
449449
}
450450
],

src/test/converter/decorators/decorators.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
@decoratorWithOptions({
55
name: 'Name of class'
66
})
7-
class DecoratedClass
8-
{
7+
class DecoratedClass {
98
/**
109
* A decorated method.
1110
*/
@@ -14,35 +13,33 @@ class DecoratedClass
1413
decoratedMethod() { }
1514
}
1615

17-
1816
/**
1917
* A decorator with no options.
2018
*/
21-
function decoratorAtom(target:Object, propertyKey:string|symbol, descriptor:TypedPropertyDescriptor<any>) {
19+
function decoratorAtom(target: Object, propertyKey: string|symbol, descriptor: TypedPropertyDescriptor<any>) {
2220
target[propertyKey].writable = true;
2321
}
2422

25-
2623
/**
2724
* A decorator with a parameter.
2825
*
2926
* @param value The parameter of this decorator.
3027
*/
31-
function decoratorWithParam(value:boolean):MethodDecorator {
32-
return function (target:Object, propertyKey:string|symbol, descriptor:TypedPropertyDescriptor<any>) {
28+
function decoratorWithParam(value: boolean): MethodDecorator {
29+
return function (target: Object, propertyKey: string|symbol, descriptor: TypedPropertyDescriptor<any>) {
3330
target[propertyKey].enumerable = value;
34-
}
31+
};
3532
}
3633

37-
3834
/**
3935
* A decorator consuming an options object.
4036
*
4137
* @param options The options object of this decorator.
4238
* @param options.name A property on the options object of this decorator.
4339
*/
44-
function decoratorWithOptions(options:{name:string}): ClassDecorator {
40+
function decoratorWithOptions(options: {name: string}): ClassDecorator {
4541
return function (target) {
4642
(target as any).options = options;
4743
};
4844
}
45+
export {}

src/test/converter/decorators/specs.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
"sources": [
8484
{
8585
"fileName": "decorators.ts",
86-
"line": 14,
86+
"line": 13,
8787
"character": 19
8888
}
8989
]
@@ -188,7 +188,7 @@
188188
"sources": [
189189
{
190190
"fileName": "decorators.ts",
191-
"line": 21,
191+
"line": 19,
192192
"character": 22
193193
}
194194
]
@@ -247,8 +247,8 @@
247247
"sources": [
248248
{
249249
"fileName": "decorators.ts",
250-
"line": 44,
251-
"character": 43
250+
"line": 40,
251+
"character": 44
252252
}
253253
],
254254
"type": {
@@ -269,7 +269,7 @@
269269
"sources": [
270270
{
271271
"fileName": "decorators.ts",
272-
"line": 44,
272+
"line": 40,
273273
"character": 38
274274
}
275275
]
@@ -286,7 +286,7 @@
286286
"sources": [
287287
{
288288
"fileName": "decorators.ts",
289-
"line": 44,
289+
"line": 40,
290290
"character": 29
291291
}
292292
]
@@ -339,7 +339,7 @@
339339
"sources": [
340340
{
341341
"fileName": "decorators.ts",
342-
"line": 31,
342+
"line": 28,
343343
"character": 27
344344
}
345345
]

0 commit comments

Comments
 (0)