Skip to content

Commit 362138e

Browse files
committed
feat!: Library mode
BREAKING CHANGE: Renames external modules to modules, and modules to namespaces. Closes #109.
1 parent f2d9c18 commit 362138e

File tree

13 files changed

+63
-23
lines changed

13 files changed

+63
-23
lines changed

scripts/rebuild_specs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ const conversions = [
4242
() => app.options.setValue('categorizeByGroup', false),
4343
() => app.options.setValue('categorizeByGroup', true)
4444
],
45+
['specs.lib',
46+
() => app.options.setValue('mode', 'library'),
47+
() => app.options.setValue('mode', 'modules'),
48+
]
4549
];
4650

4751
/**

src/lib/converter/converter.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Reflection, Type, ProjectReflection } from '../models/index';
77
import { Context } from './context';
88
import { ConverterComponent, ConverterNodeComponent, ConverterTypeComponent, TypeTypeConverter, TypeNodeConverter } from './components';
99
import { Component, ChildableComponent, ComponentClass } from '../utils/component';
10-
import { BindOption } from '../utils';
10+
import { BindOption, SourceFileMode } from '../utils';
1111
import { normalizePath } from '../utils/fs';
1212
import { createMinimatch } from '../utils/paths';
1313

@@ -366,9 +366,20 @@ export class Converter extends ChildableComponent<Application, ConverterComponen
366366
.filter(file => !isExcluded(file));
367367
const isRelevantError = ({ file }: ts.Diagnostic) => !file || includedSourceFiles.includes(file);
368368

369-
includedSourceFiles.forEach((sourceFile) => {
370-
this.convertNode(context, sourceFile);
371-
});
369+
if (this.application.options.getValue('mode') === SourceFileMode.Library) {
370+
for (const fileName of context.fileNames) {
371+
const sourceFile = includedSourceFiles.find(file => fileName === file.fileName);
372+
if (sourceFile) {
373+
this.convertNode(context, sourceFile);
374+
} else {
375+
this.application.logger.warn(`Failed to find source file of entry point ${fileName}`);
376+
}
377+
}
378+
} else {
379+
includedSourceFiles.forEach((sourceFile) => {
380+
this.convertNode(context, sourceFile);
381+
});
382+
}
372383

373384
if (this.application.ignoreCompilerErrors) {
374385
return [];

src/lib/converter/factories/declaration.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { createReferenceType } from './reference';
1111
const nonStaticKinds = [
1212
ReflectionKind.Class,
1313
ReflectionKind.Interface,
14-
ReflectionKind.Module
14+
ReflectionKind.Namespace
1515
];
1616

1717
/**
@@ -71,12 +71,12 @@ export function createDeclaration(context: Context, node: ts.Declaration, kind:
7171

7272
// Test whether the node is exported
7373
let isExported: boolean;
74-
if (kind === ReflectionKind.ExternalModule || kind === ReflectionKind.Global) {
74+
if (kind === ReflectionKind.Module || kind === ReflectionKind.Global) {
7575
isExported = true;
7676
} else if (container.kind === ReflectionKind.Global) {
7777
// In file mode, everything is exported.
7878
isExported = true;
79-
} else if (container.kindOf([ReflectionKind.Module, ReflectionKind.ExternalModule])) {
79+
} else if (container.kindOf([ReflectionKind.Namespace, ReflectionKind.Module])) {
8080
const symbol = context.getSymbolAtLocation(node);
8181
if (!symbol) {
8282
isExported = false;
@@ -213,7 +213,7 @@ function canMergeReflectionsByKind(kind1: ReflectionKind, kind2: ReflectionKind)
213213
*/
214214
function mergeDeclarations(context: Context, reflection: DeclarationReflection, node: ts.Node, kind: ReflectionKind) {
215215
if (reflection.kind !== kind) {
216-
const weights = [ReflectionKind.Module, ReflectionKind.Enum, ReflectionKind.Class];
216+
const weights = [ReflectionKind.Namespace, ReflectionKind.Enum, ReflectionKind.Class];
217217
const kindWeight = weights.indexOf(kind);
218218
const childKindWeight = weights.indexOf(reflection.kind);
219219
if (kindWeight > childKindWeight) {

src/lib/converter/nodes/block.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,17 @@ export class BlockConverter extends ConverterNodeComponent<ts.SourceFile|ts.Bloc
5555

5656
context.withSourceFile(node, () => {
5757
if (this.mode === SourceFileMode.Modules) {
58-
result = createDeclaration(context, node, ReflectionKind.ExternalModule, node.fileName);
58+
result = createDeclaration(context, node, ReflectionKind.Module, node.fileName);
5959
context.withScope(result, () => {
6060
this.convertStatements(context, node);
6161
result!.setFlag(ReflectionFlag.Exported);
6262
});
63+
} else if (this.mode === SourceFileMode.Library) {
64+
result = createDeclaration(context, node, ReflectionKind.Module, node.fileName);
65+
context.withScope(result, () => {
66+
this.convertVisibleDeclarations(context, node);
67+
result!.setFlag(ReflectionFlag.Exported);
68+
});
6369
} else {
6470
this.convertStatements(context, node);
6571
}
@@ -85,4 +91,18 @@ export class BlockConverter extends ConverterNodeComponent<ts.SourceFile|ts.Bloc
8591
});
8692
}
8793
}
94+
95+
private convertVisibleDeclarations(context: Context, node: ts.SourceFile) {
96+
const moduleSymbol = context.getSymbolAtLocation(node);
97+
if (!moduleSymbol) {
98+
this.application.logger.warn(`File ${node.fileName} is not a module and cannot be converted in library mode`);
99+
return;
100+
}
101+
102+
for (const symbol of context.checker.getExportsOfModule(moduleSymbol)) {
103+
for (const declaration of symbol.declarations) {
104+
this.owner.convertNode(context, declaration);
105+
}
106+
}
107+
}
88108
}

src/lib/converter/nodes/module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class ModuleConverter extends ConverterNodeComponent<ts.ModuleDeclaration
2424
convert(context: Context, node: ts.ModuleDeclaration): Reflection | undefined {
2525
const reflection = context.isInherit && context.inheritParent === node
2626
? <DeclarationReflection> context.scope
27-
: createDeclaration(context, node, ReflectionKind.Module);
27+
: createDeclaration(context, node, ReflectionKind.Namespace);
2828
context.withScope(reflection, () => {
2929
if (node.body) {
3030
this.owner.convertNode(context, node.body);

src/lib/converter/plugins/CommentPlugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export class CommentPlugin extends ConverterComponent {
111111
CommentPlugin.removeTags(comment, 'event');
112112
}
113113

114-
if (reflection.kindOf(ReflectionKind.ExternalModule)) {
114+
if (reflection.kindOf(ReflectionKind.Module)) {
115115
CommentPlugin.removeTags(comment, 'packagedocumentation');
116116
}
117117
}
@@ -172,7 +172,7 @@ export class CommentPlugin extends ConverterComponent {
172172
if (reflection.kindOf(ReflectionKind.FunctionOrMethod) || (reflection.kindOf(ReflectionKind.Event) && reflection['signatures'])) {
173173
const comment = parseComment(rawComment, reflection.comment);
174174
this.applyModifiers(reflection, comment);
175-
} else if (reflection.kindOf(ReflectionKind.Module)) {
175+
} else if (reflection.kindOf(ReflectionKind.Namespace)) {
176176
this.storeModuleComment(rawComment, reflection);
177177
} else {
178178
const comment = parseComment(rawComment, reflection.comment);

src/lib/converter/plugins/DynamicModulePlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class DynamicModulePlugin extends ConverterComponent {
5252
* @param node The node that is currently processed if available.
5353
*/
5454
private onDeclaration(context: Context, reflection: Reflection, node?: ts.Node) {
55-
if (reflection.kindOf(ReflectionKind.ExternalModule)) {
55+
if (reflection.kindOf(ReflectionKind.Module)) {
5656
let name = reflection.name;
5757
if (!name.includes('/')) {
5858
return;

src/lib/converter/plugins/GroupPlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export class GroupPlugin extends ConverterComponent {
1717
*/
1818
static WEIGHTS = [
1919
ReflectionKind.Global,
20-
ReflectionKind.ExternalModule,
2120
ReflectionKind.Module,
21+
ReflectionKind.Namespace,
2222
ReflectionKind.Enum,
2323
ReflectionKind.EnumMember,
2424
ReflectionKind.Class,

src/lib/models/reflections/abstract.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ export function resetReflectionID() {
3636
*/
3737
export enum ReflectionKind {
3838
Global = 0,
39-
ExternalModule = 1 << 0,
40-
Module = 1 << 1,
39+
Module = 1 << 0,
40+
Namespace = 1 << 1,
4141
Enum = 1 << 2,
4242
EnumMember = 1 << 4,
4343
Variable = 1 << 5,
@@ -66,7 +66,7 @@ export enum ReflectionKind {
6666
FunctionOrMethod = ReflectionKind.Function | Method,
6767
ClassMember = Accessor | Constructor | Method | Property | Event,
6868
SomeSignature = CallSignature | IndexSignature | ConstructorSignature | GetSignature | SetSignature,
69-
SomeModule = Module | ExternalModule,
69+
SomeModule = Namespace | Module,
7070
SomeType = Interface | TypeLiteral | TypeParameter | TypeAlias,
7171
SomeValue = Variable | Function | ObjectLiteral
7272
}

src/lib/output/themes/DefaultTheme.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class DefaultTheme extends Theme {
6161
directory: 'enums',
6262
template: 'reflection.hbs'
6363
}, {
64-
kind: [ReflectionKind.Module, ReflectionKind.ExternalModule],
64+
kind: [ReflectionKind.Namespace, ReflectionKind.Module],
6565
isLeaf: false,
6666
directory: 'modules',
6767
template: 'reflection.hbs'
@@ -375,7 +375,7 @@ export class NavigationBuilder {
375375
let target = someModule.parent;
376376
let inScope = (someModule === this.entryPoint);
377377
while (target) {
378-
if (target.kindOf(ReflectionKind.ExternalModule)) {
378+
if (target.kindOf(ReflectionKind.Module)) {
379379
return;
380380
}
381381
if (this.entryPoint === target) {

src/lib/utils/options/declaration.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export type TypeDocAndTSOptions = TypeDocOptions
3131
& Pick<CompilerOptions, Exclude<KnownKeys<CompilerOptions>, IgnoredTsOptionKeys>>;
3232

3333
export enum SourceFileMode {
34-
File, Modules
34+
File, Modules, Library
3535
}
3636

3737
/**
@@ -43,7 +43,7 @@ export interface TypeDocOptionMap {
4343
tsconfig: string;
4444

4545
inputFiles: string[];
46-
mode: { file: SourceFileMode.File, modules: SourceFileMode.Modules };
46+
mode: { file: SourceFileMode.File, modules: SourceFileMode.Modules, library: SourceFileMode.Library };
4747
includeDeclarations: boolean;
4848
entryPoint: string;
4949
exclude: string[];

src/lib/utils/options/sources/typedoc.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ export function addTypeDocOptions(options: Options) {
2626
help: "Specifies the output mode the project is used to be compiled with: 'file' or 'modules'",
2727
type: ParameterType.Map,
2828
map: {
29-
'file': SourceFileMode.File,
30-
'modules': SourceFileMode.Modules
29+
file: SourceFileMode.File,
30+
modules: SourceFileMode.Modules,
31+
library: SourceFileMode.Library
3132
},
3233
defaultValue: SourceFileMode.Modules
3334
});

src/test/converter.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ describe('Converter', function() {
3535
['specs-with-lump-categories',
3636
() => app.options.setValue('categorizeByGroup', false),
3737
() => app.options.setValue('categorizeByGroup', true)
38+
],
39+
['specs.lib',
40+
() => app.options.setValue('mode', 'library'),
41+
() => app.options.setValue('mode', 'modules')
3842
]
3943
];
4044

0 commit comments

Comments
 (0)