@microsoft/api-extractor
Version:
Validate, document, and review the exported API for a TypeScript library
99 lines (97 loc) • 4.56 kB
JavaScript
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
const fsx = require("fs-extra");
const path = require("path");
const node_core_library_1 = require("@microsoft/node-core-library");
const AstPackage_1 = require("./ast/AstPackage");
const DocItemLoader_1 = require("./DocItemLoader");
/**
* The main entry point for the "api-extractor" utility. The Analyzer object invokes the
* TypeScript Compiler API to analyze a project, and constructs the AstItem
* abstract syntax tree.
*/
class ExtractorContext {
constructor(options) {
this.packageJsonLookup = new node_core_library_1.PackageJsonLookup();
this.policies = options.policies;
const folder = this.packageJsonLookup.tryGetPackageFolder(options.entryPointFile);
if (!folder) {
throw new Error('Unable to find a package.json for entry point: ' + options.entryPointFile);
}
this._packageFolder = folder;
this._packageName = this.packageJsonLookup.getPackageName(this._packageFolder);
this.docItemLoader = new DocItemLoader_1.default(this._packageFolder);
this._logger = options.logger;
// This runs a full type analysis, and then augments the Abstract Syntax Tree (i.e. declarations)
// with semantic information (i.e. symbols). The "diagnostics" are a subset of the everyday
// compile errors that would result from a full compilation.
for (const diagnostic of options.program.getSemanticDiagnostics()) {
this.reportError('TypeScript: ' + diagnostic.messageText, diagnostic.file, diagnostic.start);
}
this.typeChecker = options.program.getTypeChecker();
const rootFile = options.program.getSourceFile(options.entryPointFile);
if (!rootFile) {
throw new Error('Unable to load file: ' + options.entryPointFile);
}
this.package = new AstPackage_1.default(this, rootFile); // construct members
this.package.completeInitialization(); // creates ApiDocumentation
this.package.visitTypeReferencesForAstItem();
}
/**
* Returns the full name of the package being analyzed.
*/
get packageName() {
return this._packageName;
}
/**
* Returns the folder for the package being analyzed.
*/
get packageFolder() {
return this._packageFolder;
}
/**
* Reports an error message to the registered ApiErrorHandler.
*/
reportError(message, sourceFile, start) {
if (sourceFile && start) {
const lineAndCharacter = sourceFile.getLineAndCharacterOfPosition(start);
// If the file is under the packageFolder, then show a relative path
const relativePath = path.relative(this.packageFolder, sourceFile.fileName);
const shownPath = relativePath.substr(0, 2) === '..' ? sourceFile.fileName : relativePath;
// Format the error so that VS Code can follow it. For example:
// "src\MyClass.ts(15,1): The JSDoc tag "@blah" is not supported by AEDoc"
this._logger.logError(`${shownPath}(${lineAndCharacter.line + 1},${lineAndCharacter.character + 1}): `
+ message);
}
else {
this._logger.logError(message);
}
}
/**
* Scans for external package api files and loads them into the docItemLoader member before
* any API analysis begins.
*
* @param externalJsonCollectionPath - an absolute path to to the folder that contains all the external
* api json files.
* Ex: if externalJsonPath is './resources', then in that folder
* are 'es6-collections.api.json', etc.
*/
loadExternalPackages(externalJsonCollectionPath) {
if (!externalJsonCollectionPath) {
return;
}
const files = fsx.readdirSync(externalJsonCollectionPath);
files.forEach(file => {
if (path.extname(file) === '.json') {
const externalJsonFilePath = path.join(externalJsonCollectionPath, file);
// Example: "C:\Example\my-package.json" --> "my-package"
const packageName = path.parse(file).name;
this.docItemLoader.loadPackageIntoCache(externalJsonFilePath, packageName);
}
});
}
}
exports.ExtractorContext = ExtractorContext;
//# sourceMappingURL=ExtractorContext.js.map