UNPKG

9.77 kBJavaScriptView Raw
1"use strict";
2var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6 return c > 3 && r && Object.defineProperty(target, key, r), r;
7};
8var Converter_1;
9Object.defineProperty(exports, "__esModule", { value: true });
10const ts = require("typescript");
11const _ = require("lodash");
12const context_1 = require("./context");
13const components_1 = require("./components");
14const component_1 = require("../utils/component");
15const utils_1 = require("../utils");
16const fs_1 = require("../utils/fs");
17const paths_1 = require("../utils/paths");
18let Converter = Converter_1 = class Converter extends component_1.ChildableComponent {
19 initialize() {
20 this.nodeConverters = {};
21 this.typeTypeConverters = [];
22 this.typeNodeConverters = [];
23 }
24 addComponent(name, componentClass) {
25 const component = super.addComponent(name, componentClass);
26 if (component instanceof components_1.ConverterNodeComponent) {
27 this.addNodeConverter(component);
28 }
29 else if (component instanceof components_1.ConverterTypeComponent) {
30 this.addTypeConverter(component);
31 }
32 return component;
33 }
34 addNodeConverter(converter) {
35 for (const supports of converter.supports) {
36 this.nodeConverters[supports] = converter;
37 }
38 }
39 addTypeConverter(converter) {
40 if ('supportsNode' in converter && 'convertNode' in converter) {
41 this.typeNodeConverters.push(converter);
42 this.typeNodeConverters.sort((a, b) => b.priority - a.priority);
43 }
44 if ('supportsType' in converter && 'convertType' in converter) {
45 this.typeTypeConverters.push(converter);
46 this.typeTypeConverters.sort((a, b) => b.priority - a.priority);
47 }
48 }
49 removeComponent(name) {
50 const component = super.removeComponent(name);
51 if (component instanceof components_1.ConverterNodeComponent) {
52 this.removeNodeConverter(component);
53 }
54 else if (component instanceof components_1.ConverterTypeComponent) {
55 this.removeTypeConverter(component);
56 }
57 return component;
58 }
59 removeNodeConverter(converter) {
60 const converters = this.nodeConverters;
61 const keys = _.keys(this.nodeConverters);
62 for (const key of keys) {
63 if (converters[key] === converter) {
64 delete converters[key];
65 }
66 }
67 }
68 removeTypeConverter(converter) {
69 const typeIndex = this.typeTypeConverters.indexOf(converter);
70 if (typeIndex !== -1) {
71 this.typeTypeConverters.splice(typeIndex, 1);
72 }
73 const nodeIndex = this.typeNodeConverters.indexOf(converter);
74 if (nodeIndex !== -1) {
75 this.typeNodeConverters.splice(nodeIndex, 1);
76 }
77 }
78 removeAllComponents() {
79 super.removeAllComponents();
80 this.nodeConverters = {};
81 this.typeTypeConverters = [];
82 this.typeNodeConverters = [];
83 }
84 convert(fileNames) {
85 const normalizedFiles = fileNames.map(fs_1.normalizePath);
86 const program = ts.createProgram(normalizedFiles, this.application.options.getCompilerOptions());
87 const checker = program.getTypeChecker();
88 const context = new context_1.Context(this, normalizedFiles, checker, program);
89 this.trigger(Converter_1.EVENT_BEGIN, context);
90 const errors = this.compile(context);
91 const project = this.resolve(context);
92 const dangling = project.getDanglingReferences();
93 if (dangling.length) {
94 this.owner.logger.warn([
95 'Some names refer to reflections that do not exist.',
96 'This can be caused by exporting a reflection only under a different name than it is declared when excludeNotExported is set',
97 'or by a plugin removing reflections without removing references. The names that cannot be resolved are:',
98 ...dangling
99 ].join('\n'));
100 }
101 this.trigger(Converter_1.EVENT_END, context);
102 return {
103 errors: errors,
104 project: project
105 };
106 }
107 convertNode(context, node) {
108 if (context.visitStack.includes(node)) {
109 return;
110 }
111 const oldVisitStack = context.visitStack;
112 context.visitStack = oldVisitStack.slice();
113 context.visitStack.push(node);
114 let result;
115 if (node.kind in this.nodeConverters) {
116 result = this.nodeConverters[node.kind].convert(context, node);
117 }
118 context.visitStack = oldVisitStack;
119 return result;
120 }
121 convertType(context, node, type) {
122 if (node) {
123 type = type || context.getTypeAtLocation(node);
124 for (const converter of this.typeNodeConverters) {
125 if (converter.supportsNode(context, node, type)) {
126 return converter.convertNode(context, node, type);
127 }
128 }
129 }
130 if (type) {
131 for (const converter of this.typeTypeConverters) {
132 if (converter.supportsType(context, type)) {
133 return converter.convertType(context, type);
134 }
135 }
136 }
137 }
138 convertTypes(context, nodes = [], types = []) {
139 const result = [];
140 _.zip(nodes, types).forEach(([node, type]) => {
141 const converted = this.convertType(context, node, type);
142 if (converted) {
143 result.push(converted);
144 }
145 });
146 return result;
147 }
148 compile(context) {
149 const program = context.program;
150 const exclude = paths_1.createMinimatch(this.application.exclude || []);
151 const isExcluded = (file) => exclude.some(mm => mm.match(file.fileName));
152 const includedSourceFiles = program.getSourceFiles()
153 .filter(file => !isExcluded(file));
154 const errors = this.getCompilerErrors(program, includedSourceFiles);
155 if (errors.length) {
156 return errors;
157 }
158 includedSourceFiles.forEach((sourceFile) => {
159 this.convertNode(context, sourceFile);
160 });
161 return [];
162 }
163 resolve(context) {
164 this.trigger(Converter_1.EVENT_RESOLVE_BEGIN, context);
165 const project = context.project;
166 for (const id in project.reflections) {
167 if (!project.reflections.hasOwnProperty(id)) {
168 continue;
169 }
170 this.trigger(Converter_1.EVENT_RESOLVE, context, project.reflections[id]);
171 }
172 this.trigger(Converter_1.EVENT_RESOLVE_END, context);
173 return project;
174 }
175 getCompilerErrors(program, includedSourceFiles) {
176 if (this.application.ignoreCompilerErrors) {
177 return [];
178 }
179 const isRelevantError = ({ file }) => !file || includedSourceFiles.includes(file);
180 let diagnostics = program.getOptionsDiagnostics().filter(isRelevantError);
181 if (diagnostics.length) {
182 return diagnostics;
183 }
184 diagnostics = program.getSyntacticDiagnostics().filter(isRelevantError);
185 if (diagnostics.length) {
186 return diagnostics;
187 }
188 diagnostics = program.getGlobalDiagnostics().filter(isRelevantError);
189 if (diagnostics.length) {
190 return diagnostics;
191 }
192 diagnostics = program.getSemanticDiagnostics().filter(isRelevantError);
193 if (diagnostics.length) {
194 return diagnostics;
195 }
196 return [];
197 }
198 getDefaultLib() {
199 return ts.getDefaultLibFileName(this.application.options.getCompilerOptions());
200 }
201};
202Converter.EVENT_BEGIN = 'begin';
203Converter.EVENT_END = 'end';
204Converter.EVENT_FILE_BEGIN = 'fileBegin';
205Converter.EVENT_CREATE_DECLARATION = 'createDeclaration';
206Converter.EVENT_CREATE_SIGNATURE = 'createSignature';
207Converter.EVENT_CREATE_PARAMETER = 'createParameter';
208Converter.EVENT_CREATE_TYPE_PARAMETER = 'createTypeParameter';
209Converter.EVENT_FUNCTION_IMPLEMENTATION = 'functionImplementation';
210Converter.EVENT_RESOLVE_BEGIN = 'resolveBegin';
211Converter.EVENT_RESOLVE = 'resolveReflection';
212Converter.EVENT_RESOLVE_END = 'resolveEnd';
213__decorate([
214 utils_1.BindOption('name')
215], Converter.prototype, "name", void 0);
216__decorate([
217 utils_1.BindOption('externalPattern')
218], Converter.prototype, "externalPattern", void 0);
219__decorate([
220 utils_1.BindOption('includeDeclarations')
221], Converter.prototype, "includeDeclarations", void 0);
222__decorate([
223 utils_1.BindOption('excludeExternals')
224], Converter.prototype, "excludeExternals", void 0);
225__decorate([
226 utils_1.BindOption('excludeNotExported')
227], Converter.prototype, "excludeNotExported", void 0);
228__decorate([
229 utils_1.BindOption('excludeNotDocumented')
230], Converter.prototype, "excludeNotDocumented", void 0);
231__decorate([
232 utils_1.BindOption('excludePrivate')
233], Converter.prototype, "excludePrivate", void 0);
234__decorate([
235 utils_1.BindOption('excludeProtected')
236], Converter.prototype, "excludeProtected", void 0);
237Converter = Converter_1 = __decorate([
238 component_1.Component({ name: 'converter', internal: true, childClass: components_1.ConverterComponent })
239], Converter);
240exports.Converter = Converter;
241//# sourceMappingURL=converter.js.map
\No newline at end of file