UNPKG

6.96 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var ts = require("typescript");
4var node_modules_1 = require("./node-modules");
5var namedDeclarationKinds = [
6 ts.SyntaxKind.InterfaceDeclaration,
7 ts.SyntaxKind.ClassDeclaration,
8 ts.SyntaxKind.EnumDeclaration,
9 ts.SyntaxKind.TypeAliasDeclaration,
10 ts.SyntaxKind.ModuleDeclaration,
11 ts.SyntaxKind.FunctionDeclaration,
12 ts.SyntaxKind.VariableDeclaration,
13];
14function isNodeNamedDeclaration(node) {
15 return namedDeclarationKinds.indexOf(node.kind) !== -1;
16}
17exports.isNodeNamedDeclaration = isNodeNamedDeclaration;
18function hasNodeModifier(node, modifier) {
19 return Boolean(node.modifiers && node.modifiers.some(function (nodeModifier) { return nodeModifier.kind === modifier; }));
20}
21exports.hasNodeModifier = hasNodeModifier;
22function getActualSymbol(symbol, typeChecker) {
23 if (symbol.flags & ts.SymbolFlags.Alias) {
24 symbol = typeChecker.getAliasedSymbol(symbol);
25 }
26 return symbol;
27}
28exports.getActualSymbol = getActualSymbol;
29/**
30 * @see https://github.com/Microsoft/TypeScript/blob/f7c4fefeb62416c311077a699cc15beb211c25c9/src/compiler/utilities.ts#L626-L628
31 */
32function isGlobalScopeAugmentation(module) {
33 return Boolean(module.flags & ts.NodeFlags.GlobalAugmentation);
34}
35/**
36 * Returns whether node is ambient module declaration (declare module "name" or declare global)
37 * @see https://github.com/Microsoft/TypeScript/blob/f7c4fefeb62416c311077a699cc15beb211c25c9/src/compiler/utilities.ts#L588-L590
38 */
39function isAmbientModule(node) {
40 return ts.isModuleDeclaration(node) && (node.name.kind === ts.SyntaxKind.StringLiteral || isGlobalScopeAugmentation(node));
41}
42exports.isAmbientModule = isAmbientModule;
43/**
44 * Returns whether statement is `declare module` ModuleDeclaration (not `declare global` or `namespace`)
45 */
46function isDeclareModuleStatement(statement) {
47 // `declare module ""`, `declare global` and `namespace {}` are ModuleDeclaration
48 // but here we need to check only `declare module` statements
49 return ts.isModuleDeclaration(statement) && !(statement.flags & ts.NodeFlags.Namespace) && !isGlobalScopeAugmentation(statement);
50}
51exports.isDeclareModuleStatement = isDeclareModuleStatement;
52/**
53 * Returns whether statement is `declare global` ModuleDeclaration
54 */
55function isDeclareGlobalStatement(statement) {
56 return ts.isModuleDeclaration(statement) && isGlobalScopeAugmentation(statement);
57}
58exports.isDeclareGlobalStatement = isDeclareGlobalStatement;
59/**
60 * Returns whether node is `namespace` ModuleDeclaration
61 */
62function isNamespaceStatement(node) {
63 return ts.isModuleDeclaration(node) && Boolean(node.flags & ts.NodeFlags.Namespace);
64}
65exports.isNamespaceStatement = isNamespaceStatement;
66function getDeclarationsForSymbol(symbol) {
67 var result = [];
68 // Disabling tslint is for backward compat with TypeScript < 3
69 // tslint:disable-next-line:strict-type-predicates
70 if (symbol.valueDeclaration !== undefined) {
71 result.push(symbol.valueDeclaration);
72 }
73 // Disabling tslint is for backward compat with TypeScript < 3
74 // tslint:disable-next-line:strict-type-predicates
75 if (symbol.declarations !== undefined) {
76 result.push.apply(result, symbol.declarations);
77 }
78 return result;
79}
80exports.getDeclarationsForSymbol = getDeclarationsForSymbol;
81function isDeclarationFromExternalModule(node) {
82 return node_modules_1.getLibraryName(node.getSourceFile().fileName) !== null;
83}
84exports.isDeclarationFromExternalModule = isDeclarationFromExternalModule;
85function getExportsForSourceFile(typeChecker, sourceFileSymbol) {
86 if (sourceFileSymbol.exports !== undefined) {
87 var commonJsExport = sourceFileSymbol.exports.get(ts.InternalSymbolName.ExportEquals);
88 if (commonJsExport !== undefined) {
89 return [
90 {
91 symbol: getActualSymbol(commonJsExport, typeChecker),
92 type: 0 /* CommonJS */,
93 },
94 ];
95 }
96 }
97 var result = typeChecker
98 .getExportsOfModule(sourceFileSymbol)
99 .map(function (symbol) { return ({ symbol: symbol, type: 1 /* ES6Named */ }); });
100 if (sourceFileSymbol.exports !== undefined) {
101 var defaultExportSymbol_1 = sourceFileSymbol.exports.get(ts.InternalSymbolName.Default);
102 if (defaultExportSymbol_1 !== undefined) {
103 var defaultExport = result.find(function (exp) { return exp.symbol === defaultExportSymbol_1; });
104 if (defaultExport !== undefined) {
105 defaultExport.type = 2 /* ES6Default */;
106 }
107 else {
108 // it seems that default export is always returned by getExportsOfModule
109 // but let's add it to be sure add if there is no such export
110 result.push({
111 symbol: defaultExportSymbol_1,
112 type: 2 /* ES6Default */,
113 });
114 }
115 }
116 }
117 result.forEach(function (symbol) {
118 symbol.symbol = getActualSymbol(symbol.symbol, typeChecker);
119 });
120 return result;
121}
122exports.getExportsForSourceFile = getExportsForSourceFile;
123function getExportTypeForDeclaration(exportedSymbols, typeChecker, declaration) {
124 if (ts.isVariableStatement(declaration)) {
125 if (declaration.declarationList.declarations.length === 0) {
126 return null;
127 }
128 var firstDeclarationExportType_1 = getExportTypeForName(exportedSymbols, typeChecker, declaration.declarationList.declarations[0].name);
129 var allDeclarationsHaveSameExportType = declaration.declarationList.declarations.every(function (variableDecl) {
130 // all declaration should have the same export type
131 // TODO: for now it's not supported to have different type of exports
132 return getExportTypeForName(exportedSymbols, typeChecker, variableDecl.name) === firstDeclarationExportType_1;
133 });
134 if (!allDeclarationsHaveSameExportType) {
135 // log warn?
136 return null;
137 }
138 return firstDeclarationExportType_1;
139 }
140 return getExportTypeForName(exportedSymbols, typeChecker, declaration.name);
141}
142exports.getExportTypeForDeclaration = getExportTypeForDeclaration;
143function getExportTypeForName(exportedSymbols, typeChecker, name) {
144 if (name === undefined) {
145 return null;
146 }
147 if (ts.isArrayBindingPattern(name) || ts.isObjectBindingPattern(name)) {
148 // TODO: binding patterns in variable declarations are not supported for now
149 // see https://github.com/microsoft/TypeScript/issues/30598 also
150 return null;
151 }
152 var declarationSymbol = typeChecker.getSymbolAtLocation(name);
153 var exportedSymbol = exportedSymbols.find(function (rootExport) { return rootExport.symbol === declarationSymbol; });
154 if (exportedSymbol === undefined) {
155 return null;
156 }
157 return exportedSymbol.type;
158}