Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import type {Program, TransformationContext, SourceFile, Node} from 'typescript'
import type {TransformerExtras, PluginConfig} from 'ts-patch';
import {GL} from '@luma.gl/constants';

const WEBGL_CONSTANT_MODULES = new Set([
'@luma.gl/constants',
'@luma.gl/webgl/constants',
'luma.gl/constants'
]);

export default function (program: Program, pluginConfig: PluginConfig, {ts}: TransformerExtras) {
return (ctx: TransformationContext) => {
const {factory} = ctx;
Expand All @@ -25,6 +31,9 @@ export default function (program: Program, pluginConfig: PluginConfig, {ts}: Tra

return (sourceFile: SourceFile) => {
function visit(node: Node): Node {
if (ts.isImportDeclaration(node)) {
return node;
}
if (ts.isPropertyAccessExpression(node) && filterLeftIdentifier(node)) {
const key = node.getChildAt(2);
if (ts.isIdentifier(key) && key.text in GL) {
Expand All @@ -39,7 +48,79 @@ export default function (program: Program, pluginConfig: PluginConfig, {ts}: Tra
}
return ts.visitEachChild(node, visit, ctx);
}
return ts.visitNode(sourceFile, visit);

const transformedSourceFile = ts.visitEachChild(sourceFile, visit, ctx);
const runtimeIdentifiers = getRuntimeIdentifiers(transformedSourceFile);

const statements = transformedSourceFile.statements.flatMap((statement) => {
if (!ts.isImportDeclaration(statement) || !isWebGLConstantsImport(statement)) {
return [statement];
}

const importClause = statement.importClause;
const namedBindings = importClause?.namedBindings;
if (!importClause || !namedBindings || !ts.isNamedImports(namedBindings)) {
return [statement];
}

const elements = namedBindings.elements.filter((element) =>
runtimeIdentifiers.has(element.name.text)
);
if (elements.length === namedBindings.elements.length) {
return [statement];
}
if (!elements.length && !importClause.name) {
return [];
}

const updatedNamedBindings = elements.length
? factory.updateNamedImports(namedBindings, elements)
: undefined;
const updatedImportClause = factory.updateImportClause(
importClause,
importClause.isTypeOnly,
importClause.name,
updatedNamedBindings
);
return [
factory.updateImportDeclaration(
statement,
statement.modifiers,
updatedImportClause,
statement.moduleSpecifier,
statement.assertClause
)
];
});

return factory.updateSourceFile(transformedSourceFile, statements);

function getRuntimeIdentifiers(node: Node): Set<string> {
const identifiers = new Set<string>();

collectRuntimeIdentifiers(node);
return identifiers;

function collectRuntimeIdentifiers(child: Node): void {
if (ts.isImportDeclaration(child) || ts.isTypeNode(child)) {
return;
}
if (ts.isIdentifier(child)) {
identifiers.add(child.text);
}
ts.forEachChild(child, collectRuntimeIdentifiers);
}
}

function isWebGLConstantsImport(node: Node): boolean {
if (ts.isImportDeclaration(node)) {
return (
ts.isStringLiteral(node.moduleSpecifier) &&
WEBGL_CONSTANT_MODULES.has(node.moduleSpecifier.text)
);
}
return false;
}
};
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const testCases = [
{
title: 'drop GL import',
input: `\
import {GL} from '@luma.gl/webgl/constants';

device.setParametersWebGL({
blendFunc: [GL.ONE, GL.ONE_MINUS_DST_COLOR, GL.SRC_ALPHA, GL.DST_ALPHA]
});
Expand All @@ -15,6 +17,60 @@ device.setParametersWebGL({
device.setParametersWebGL({
blendFunc: [1, 775, 770, 772]
});
export {};
`
},
{
title: 'retain other named imports',
input: `\
import {GL, OTHER_CONSTANT} from '@luma.gl/webgl/constants';

console.log(GL.TRIANGLES, OTHER_CONSTANT);
`,
output: `\
import { OTHER_CONSTANT } from '@luma.gl/webgl/constants';
console.log(4, OTHER_CONSTANT);
`
},
{
title: 'retain GL import for dynamic access',
input: `\
import {GL} from '@luma.gl/webgl/constants';

const name = 'TRIANGLES';
console.log(GL[name]);
`,
output: `\
import { GL } from '@luma.gl/webgl/constants';
const name = 'TRIANGLES';
console.log(GL[name]);
`
},
{
title: 'retain GL import for direct access',
input: `\
import {GL} from '@luma.gl/webgl/constants';

console.log(GL);
`,
output: `\
import { GL } from '@luma.gl/webgl/constants';
console.log(GL);
`
},
{
title: 'drop GL import when remaining references are types',
input: `\
import {GL, GLPrimitiveTopology, type GLTextureTarget} from '@luma.gl/webgl/constants';

export function getTriangleMode(topology: GLPrimitiveTopology): GLTextureTarget | GL.TRIANGLES {
return GL.TRIANGLES;
}
`,
output: `\
export function getTriangleMode(topology) {
return 4;
}
`
},
{
Expand Down
Loading