Skip to content

Commit

Permalink
Merge pull request #2725 from microsoft/octogonz/typescript-4.3
Browse files Browse the repository at this point in the history
[api-extractor] Upgrade the TypeScript engine to 4.3
  • Loading branch information
octogonz authored Jun 4, 2021
2 parents af2bcf9 + c3cc2a9 commit c5a98d8
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 35 deletions.
2 changes: 1 addition & 1 deletion apps/api-extractor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"resolve": "~1.17.0",
"semver": "~7.3.0",
"source-map": "~0.6.1",
"typescript": "~4.2.4"
"typescript": "~4.3.2"
},
"devDependencies": {
"@rushstack/eslint-config": "workspace:*",
Expand Down
44 changes: 24 additions & 20 deletions apps/api-extractor/src/analyzer/AstSymbolTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,12 +480,12 @@ export class AstSymbolTable {
const followedSymbol: ts.Symbol = options.followedSymbol;

// Filter out symbols representing constructs that we don't care about
if (!TypeScriptHelpers.hasAnyDeclarations(followedSymbol)) {
const arbitraryDeclaration: ts.Declaration | undefined =
TypeScriptHelpers.tryGetADeclaration(followedSymbol);
if (!arbitraryDeclaration) {
return undefined;
}

const arbitraryDeclaration: ts.Declaration = followedSymbol.declarations[0];

if (
// eslint-disable-next-line no-bitwise
followedSymbol.flags &
Expand Down Expand Up @@ -557,24 +557,28 @@ export class AstSymbolTable {
// - but P1 and P2 may be different (e.g. merged namespaces containing merged interfaces)

// Is there a parent AstSymbol? First we check to see if there is a parent declaration:
const arbitraryParentDeclaration: ts.Node | undefined = this._tryFindFirstAstDeclarationParent(
followedSymbol.declarations[0]
);

if (arbitraryParentDeclaration) {
const parentSymbol: ts.Symbol = TypeScriptHelpers.getSymbolForDeclaration(
arbitraryParentDeclaration as ts.Declaration,
this._typeChecker
);
const arbitraryDeclaration: ts.Node | undefined =
TypeScriptHelpers.tryGetADeclaration(followedSymbol);

if (arbitraryDeclaration) {
const arbitraryParentDeclaration: ts.Node | undefined =
this._tryFindFirstAstDeclarationParent(arbitraryDeclaration);

parentAstSymbol = this._fetchAstSymbol({
followedSymbol: parentSymbol,
isExternal: options.isExternal,
includeNominalAnalysis: false,
addIfMissing: true
});
if (!parentAstSymbol) {
throw new InternalError('Unable to construct a parent AstSymbol for ' + followedSymbol.name);
if (arbitraryParentDeclaration) {
const parentSymbol: ts.Symbol = TypeScriptHelpers.getSymbolForDeclaration(
arbitraryParentDeclaration as ts.Declaration,
this._typeChecker
);

parentAstSymbol = this._fetchAstSymbol({
followedSymbol: parentSymbol,
isExternal: options.isExternal,
includeNominalAnalysis: false,
addIfMissing: true
});
if (!parentAstSymbol) {
throw new InternalError('Unable to construct a parent AstSymbol for ' + followedSymbol.name);
}
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions apps/api-extractor/src/analyzer/ExportAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ export class ExportAnalyzer {
);

// Ignore virtual symbols that don't have any declarations
if (TypeScriptHelpers.hasAnyDeclarations(followedSymbol)) {
const arbitraryDeclaration: ts.Declaration | undefined =
TypeScriptHelpers.tryGetADeclaration(followedSymbol);
if (arbitraryDeclaration) {
const astSymbol: AstSymbol | undefined = this._astSymbolTable.fetchAstSymbol({
followedSymbol: followedSymbol,
isExternal: astModule.isExternal,
Expand All @@ -142,7 +144,7 @@ export class ExportAnalyzer {
if (!astSymbol) {
throw new Error(
`Unsupported export ${JSON.stringify(exportedSymbol.name)}:\n` +
SourceFileLocationFormatter.formatDeclaration(followedSymbol.declarations[0])
SourceFileLocationFormatter.formatDeclaration(arbitraryDeclaration)
);
}

Expand Down
9 changes: 9 additions & 0 deletions apps/api-extractor/src/analyzer/Span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,16 @@ export class Span {

let previousChildSpan: Span | undefined = undefined;

const visitedChildren: Set<ts.Node> = new Set();

for (const childNode of this.node.getChildren() || []) {
// FIX ME: This is a temporary workaround for a problem introduced by TypeScript 4.3.
// https://github.com/microsoft/TypeScript/issues/44422
if (visitedChildren.has(childNode)) {
continue;
}
visitedChildren.add(childNode);

const childSpan: Span = new Span(childNode);
childSpan._parent = this;
childSpan._previousSibling = previousChildSpan;
Expand Down
17 changes: 9 additions & 8 deletions apps/api-extractor/src/analyzer/TypeScriptHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ export class TypeScriptHelpers {
* sometimes return a "prototype" symbol for an object, even though there is no corresponding declaration in the
* source code. API Extractor generally ignores such symbols.
*/
public static hasAnyDeclarations(symbol: ts.Symbol): boolean {
return symbol.declarations && symbol.declarations.length > 0;
public static tryGetADeclaration(symbol: ts.Symbol): ts.Declaration | undefined {
if (symbol.declarations && symbol.declarations.length > 0) {
return symbol.declarations[0];
}
return undefined;
}

/**
Expand Down Expand Up @@ -272,13 +275,11 @@ export class TypeScriptHelpers {
{
onEmitNode(
hint: ts.EmitHint,
node: ts.Node | undefined,
emit: (hint: ts.EmitHint, node: ts.Node | undefined) => void
node: ts.Node,
emitCallback: (hint: ts.EmitHint, node: ts.Node) => void
): void {
if (node) {
ts.setEmitFlags(declarationName, ts.EmitFlags.NoIndentation | ts.EmitFlags.SingleLine);
}
emit(hint, node);
ts.setEmitFlags(declarationName, ts.EmitFlags.NoIndentation | ts.EmitFlags.SingleLine);
emitCallback(hint, node);
}
}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@microsoft/api-extractor",
"comment": "Upgrade the bundled compiler engine to TypeScript 4.3",
"type": "minor"
}
],
"packageName": "@microsoft/api-extractor",
"email": "[email protected]"
}
2 changes: 1 addition & 1 deletion common/config/rush/common-versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
* For example, allow some projects to use an older TypeScript compiler
* (in addition to whatever "usual" version is being used by other projects in the repo):
*/
"typescript": ["~2.4.2", "~2.9.2", "~4.2.4"],
"typescript": ["~2.4.2", "~2.9.2", "~4.2.4", "~4.3.2"],

"source-map": [
"~0.6.1" // API Extractor is using an older version of source-map because newer versions are async
Expand Down
10 changes: 8 additions & 2 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion common/config/rush/repo-state.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush.
{
"pnpmShrinkwrapHash": "c7f96d34a06a3bf954c5b2f32777981c2a21717f",
"pnpmShrinkwrapHash": "99943da203445c1a464347d118d09c72903e7e73",
"preferredVersionsHash": "6a96c5550f3ce50aa19e8d1141c6c5d4176953ff"
}

0 comments on commit c5a98d8

Please sign in to comment.