Skip to content

Commit

Permalink
Use wrappers for all changing APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic committed Nov 26, 2022
1 parent abed898 commit cc94824
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 33 deletions.
36 changes: 25 additions & 11 deletions packages/transformers/typescript-types/src/shake.js
Expand Up @@ -4,7 +4,13 @@ import type {TSModuleGraph} from './TSModuleGraph';

import ts from 'typescript';
import nullthrows from 'nullthrows';
import {getExportedName, isDeclaration, createImportSpecifier} from './utils';
import {getExportedName, isDeclaration} from './utils';
import {
createImportClause,
createImportDeclaration,
createImportSpecifier,
updateExportDeclaration,
} from './wrappers';

export function shake(
moduleGraph: TSModuleGraph,
Expand Down Expand Up @@ -95,12 +101,14 @@ export function shake(
}

if (exported.length > 0) {
return ts.updateExportDeclaration(
return updateExportDeclaration(
factory,
node,
undefined, // decorators
undefined, // modifiers
false, // isTypeOnly
factory.updateNamedExports(node.exportClause, exported),
undefined, // moduleSpecifier
undefined, // assertClause
);
}
}
Expand Down Expand Up @@ -258,6 +266,7 @@ function generateImports(factory: any, moduleGraph: TSModuleGraph) {
namedSpecifiers.push(
createImportSpecifier(
factory,
false,
name === imported ? undefined : factory.createIdentifier(imported),
factory.createIdentifier(name),
),
Expand All @@ -266,35 +275,40 @@ function generateImports(factory: any, moduleGraph: TSModuleGraph) {
}

if (namespaceSpecifier) {
let importClause = ts.createImportClause(
let importClause = createImportClause(
factory,
false,
defaultSpecifier,
namespaceSpecifier,
);
importStatements.push(
ts.createImportDeclaration(
undefined,
createImportDeclaration(
factory,
undefined,
importClause,
// $FlowFixMe
ts.createLiteral(specifier),
factory.createStringLiteral(specifier),
undefined,
),
);
defaultSpecifier = undefined;
}

if (defaultSpecifier || namedSpecifiers.length > 0) {
let importClause = ts.createImportClause(
let importClause = createImportClause(
factory,
false,
defaultSpecifier,
namedSpecifiers.length > 0
? factory.createNamedImports(namedSpecifiers)
: undefined,
);
importStatements.push(
ts.createImportDeclaration(
undefined,
createImportDeclaration(
factory,
undefined,
importClause,
factory.createStringLiteral(specifier),
undefined,
),
);
}
Expand Down
22 changes: 0 additions & 22 deletions packages/transformers/typescript-types/src/utils.js
@@ -1,8 +1,5 @@
// @flow
import typeof TypeScriptModule from 'typescript'; // eslint-disable-line import/no-extraneous-dependencies
import type {Identifier, ImportSpecifier} from 'typescript';

import ts from 'typescript';

export function getExportedName(ts: TypeScriptModule, node: any): ?string {
if (!node.modifiers) {
Expand All @@ -29,22 +26,3 @@ export function isDeclaration(ts: TypeScriptModule, node: any): boolean {
ts.isTypeAliasDeclaration(node)
);
}

export function createImportSpecifier(
factory: any,
propertyName: Identifier | void,
name: Identifier,
isTypeOnly: boolean = false,
): ImportSpecifier {
const [majorVersion, minorVersion] = ts.versionMajorMinor
.split('.')
.map(num => parseInt(num, 10));
// The signature of createImportSpecifier had a breaking change in Typescript 4.5.
// see: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#type-modifiers-on-import-names
if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
// $FlowFixMe
return factory.createImportSpecifier(isTypeOnly, propertyName, name);
} else {
return ts.createImportSpecifier(propertyName, name);
}
}
202 changes: 202 additions & 0 deletions packages/transformers/typescript-types/src/wrappers.js
@@ -0,0 +1,202 @@
// @flow
/* eslint-disable no-unused-vars */
import type {
ExportDeclaration,
Expression,
Identifier,
ImportClause,
ImportDeclaration,
ImportSpecifier,
Modifier,
NamedImportBindings,
} from 'typescript';

import ts from 'typescript';
import invariant from 'assert';

type AssertClause = any;
type NamedExportBindings = any;

const [majorVersion, minorVersion] = ts.versionMajorMinor
.split('.')
.map(num => parseInt(num, 10));

// Everything below was generated using https://github.com/mischnic/tsc-version-wrapper

export const createImportClause: (
factory: any,
isTypeOnly: boolean,
name: Identifier | void,
namedBindings: NamedImportBindings | void,
) => ImportClause = (() => {
if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 0)) {
return (factory, isTypeOnly, name, namedBindings) =>
factory.createImportClause(isTypeOnly, name, namedBindings);
} else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 8)) {
return (factory, isTypeOnly, name, namedBindings) =>
factory.createImportClause(name, namedBindings, isTypeOnly);
} else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
return (factory, isTypeOnly, name, namedBindings) =>
factory.createImportClause(name, namedBindings);
} else {
invariant(false);
}
})();

export const createImportDeclaration: (
factory: any,
modifiers: Modifier[] | void,
importClause: ImportClause | void,
moduleSpecifier: Expression,
assertClause: AssertClause,
) => ImportDeclaration = (() => {
if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 8)) {
return (factory, modifiers, importClause, moduleSpecifier, assertClause) =>
factory.createImportDeclaration(
modifiers,
importClause,
moduleSpecifier,
assertClause,
);
} else if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
return (factory, modifiers, importClause, moduleSpecifier, assertClause) =>
factory.createImportDeclaration(
undefined /* decorators */,
modifiers,
importClause,
moduleSpecifier,
assertClause,
);
} else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
return (factory, modifiers, importClause, moduleSpecifier, assertClause) =>
factory.createImportDeclaration(
undefined /* decorators */,
modifiers,
importClause,
moduleSpecifier,
);
} else {
invariant(false);
}
})();

export const createImportSpecifier: (
factory: any,
isTypeOnly: boolean,
propertyName: Identifier | void,
name: Identifier,
) => ImportSpecifier = (() => {
if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
return (factory, isTypeOnly, propertyName, name) =>
factory.createImportSpecifier(isTypeOnly, propertyName, name);
} else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
return (factory, isTypeOnly, propertyName, name) =>
factory.createImportSpecifier(propertyName, name);
} else {
invariant(false);
}
})();

export const updateExportDeclaration: (
factory: any,
node: ExportDeclaration,
modifiers: Modifier[] | void,
isTypeOnly: boolean,
exportClause: NamedExportBindings | void,
moduleSpecifier: Expression | void,
assertClause: AssertClause | void,
) => ExportDeclaration = (() => {
if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 8)) {
return (
factory,
node,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
) =>
factory.updateExportDeclaration(
node,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
);
} else if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 5)) {
return (
factory,
node,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
) =>
factory.updateExportDeclaration(
node,
undefined /* decorators */,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
);
} else if (majorVersion > 4 || (majorVersion === 4 && minorVersion >= 0)) {
return (
factory,
node,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
) =>
factory.updateExportDeclaration(
node,
undefined /* decorators */,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
);
} else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 8)) {
return (
factory,
node,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
) =>
factory.updateExportDeclaration(
node,
undefined /* decorators */,
modifiers,
exportClause,
moduleSpecifier,
isTypeOnly,
);
} else if (majorVersion > 3 || (majorVersion === 3 && minorVersion >= 0)) {
return (
factory,
node,
modifiers,
isTypeOnly,
exportClause,
moduleSpecifier,
assertClause,
) =>
factory.updateExportDeclaration(
node,
undefined /* decorators */,
modifiers,
exportClause,
moduleSpecifier,
);
} else {
invariant(false);
}
})();

0 comments on commit cc94824

Please sign in to comment.