Skip to content

Commit

Permalink
Minor refactors to parsing in preparation for bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kristoferbaxter committed Jan 8, 2020
1 parent fc22ced commit 4203bb5
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 183 deletions.
65 changes: 65 additions & 0 deletions src/parsing/export-details.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { ExportNamedDeclaration, ExportDefaultDeclaration } from 'estree';
import { ExportDetails, Range, ExportClosureMapping } from '../types';

export function NamedDeclaration(declaration: ExportNamedDeclaration): Array<ExportDetails> {
const range: Range = declaration.range as Range;
const source: string | null =
typeof declaration?.source?.value === 'string' ? declaration.source.value : null;

if (declaration.specifiers) {
const exportDetails: Array<ExportDetails> = [];

for (const specifier of declaration.specifiers) {
exportDetails.push({
local: specifier.local.name,
exported: specifier.exported.name,
closureName: specifier.exported.name,
type: ExportClosureMapping.NAMED_CONSTANT,
range,
source,
});
}

return exportDetails;
}

return [];
}

export function DefaultDeclaration(
defaultDeclaration: ExportDefaultDeclaration,
): Array<ExportDetails> {
const range: Range = defaultDeclaration.range as Range;
const { declaration } = defaultDeclaration;

if (declaration.type === 'Identifier' && declaration.name) {
return [
{
local: declaration.name,
exported: declaration.name,
closureName: declaration.name,
type: ExportClosureMapping.NAMED_DEFAULT_FUNCTION,
range,
source: null,
},
];
}

return [];
}
32 changes: 32 additions & 0 deletions src/parsing/literal-name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { PluginContext } from 'rollup';
import { Literal, SimpleLiteral } from 'estree';

export function literalName(context: PluginContext, literal: Literal): string {
// Literal can either be a SimpleLiteral, or RegExpLiteral
if ('regex' in literal) {
// This is a RegExpLiteral
context.warn(
'Rollup Plugin Closure Compiler found a Regex Literal Named Import. `import foo from "*/.hbs"`',
);
return '';
}

const literalValue = (literal as SimpleLiteral).value;
return typeof literalValue === 'string' ? literalValue : '';
}
6 changes: 3 additions & 3 deletions src/transformers/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
Node,
} from 'estree';
import { TransformSourceDescription } from 'rollup';
import { NamedDeclaration, DefaultDeclaration } from './parsing-utilities';
import { NamedDeclaration, DefaultDeclaration } from '../parsing/export-details';
import { isESMFormat } from '../options';
import {
Transform,
Expand Down Expand Up @@ -86,10 +86,10 @@ export default class ExportTransform extends Transform implements TransformInter

walk.simple(program, {
ExportNamedDeclaration(node: ExportNamedDeclaration) {
storeExport(NamedDeclaration(context, node));
storeExport(NamedDeclaration(node));
},
ExportDefaultDeclaration(node: ExportDefaultDeclaration) {
storeExport(DefaultDeclaration(context, node));
storeExport(DefaultDeclaration(node));
},
ExportAllDeclaration(node: ExportAllDeclaration) {
// TODO(KB): This case `export * from "./import"` is not currently supported.
Expand Down
17 changes: 15 additions & 2 deletions src/transformers/imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
IMPORT_NAMESPACE_SPECIFIER,
IMPORT_DEFAULT_SPECIFIER,
} from '../types';
import { literalName, importLocalNames } from './parsing-utilities';
import { literalName } from '../parsing/literal-name';
import { TransformSourceDescription } from 'rollup';
import MagicString from 'magic-string';
import { ImportDeclaration, Identifier, ImportSpecifier } from 'estree';
Expand All @@ -42,6 +42,19 @@ interface RangedImport {
range: Range;
}

const VALID_SPECIFIERS = [IMPORT_SPECIFIER, IMPORT_NAMESPACE_SPECIFIER, IMPORT_DEFAULT_SPECIFIER];
function importLocalNames(declaration: ImportDeclaration): Array<string> {
const returnableSpecifiers: Array<string> = [];

for (const specifier of declaration.specifiers || []) {
if (VALID_SPECIFIERS.includes(specifier.type)) {
returnableSpecifiers.push(specifier.local.name);
}
}

return returnableSpecifiers;
}

export default class ImportTransform extends Transform {
private importedExternalsSyntax: { [key: string]: string } = {};
private importedExternalsLocalNames: Array<string> = [];
Expand Down Expand Up @@ -117,7 +130,7 @@ window['${DYNAMIC_IMPORT_REPLACEMENT}'] = ${DYNAMIC_IMPORT_REPLACEMENT};`;
source.remove(...range);

self.importedExternalsLocalNames = self.importedExternalsLocalNames.concat(
importLocalNames(self.context, node),
importLocalNames(node),
);
},
Import(node: RangedImport) {
Expand Down
116 changes: 0 additions & 116 deletions src/transformers/parsing-utilities.ts

This file was deleted.

28 changes: 0 additions & 28 deletions src/transformers/replacement-utilities.ts

This file was deleted.

22 changes: 7 additions & 15 deletions src/transformers/strict.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { isESMFormat } from '../options';
import { TransformSourceDescription } from 'rollup';
import MagicString from 'magic-string';
import { walk, parse } from '../acorn';
import { ExpressionStatement } from 'estree';
import { ExpressionStatement, SimpleLiteral } from 'estree';
import { extname } from 'path';

export default class StrictTransform extends Transform {
Expand All @@ -32,25 +32,17 @@ export default class StrictTransform extends Transform {
* @return code after removing the strict mode declaration (when safe to do so)
*/
public async postCompilation(code: string): Promise<TransformSourceDescription> {
if (this.outputOptions === null) {
this.context.warn(
'Rollup Plugin Closure Compiler, OutputOptions not known before Closure Compiler invocation.',
);
} else if (
isESMFormat(this.outputOptions.format) ||
(this.outputOptions.file && extname(this.outputOptions.file) === '.mjs')
) {
const { format, file } = this.outputOptions;

if (isESMFormat(format) || (file && extname(file) === '.mjs')) {
const source = new MagicString(code);
const program = parse(code);

walk.simple(program, {
ExpressionStatement(node: ExpressionStatement) {
if (
node.expression.type === 'Literal' &&
node.expression.value === 'use strict' &&
node.range
) {
source.remove(node.range[0], node.range[1]);
const { type, value } = node.expression as SimpleLiteral;
if (type === 'Literal' && value === 'use strict' && node.range) {
source.remove(...node.range);
}
},
});
Expand Down
19 changes: 1 addition & 18 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export interface TransformInterface {
export class Transform implements TransformInterface {
protected context: PluginContext;
protected inputOptions: InputOptions;
public outputOptions: OutputOptions | null;
public outputOptions: OutputOptions;
public name: string = 'Transform';

constructor(context: PluginContext, inputOptions: InputOptions) {
Expand All @@ -92,21 +92,4 @@ export class Transform implements TransformInterface {
code,
};
}

// TODO (KB): Is this needed?
// protected isEntryPoint(id: string) {
// const inputs = (input: InputOption): Array<string> => {
// if (typeof input === 'string') {
// return [input];
// } else if (typeof input === 'object') {
// return Object.values(input);
// } else {
// return input;
// }
// };

// return inputs(this.inputOptions.input)
// .map(input => path.resolve(input))
// .includes(id);
// }
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"outDir": "transpile",
"sourceMap": true,
"moduleResolution": "node",
"target": "esnext",
"target": "es2019",
"baseUrl": ".",
"allowJs": false,
"noUnusedLocals": true,
Expand Down

0 comments on commit 4203bb5

Please sign in to comment.