Skip to content

Commit 4203bb5

Browse files
Minor refactors to parsing in preparation for bug fixes
1 parent fc22ced commit 4203bb5

File tree

9 files changed

+124
-183
lines changed

9 files changed

+124
-183
lines changed

src/parsing/export-details.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS-IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { ExportNamedDeclaration, ExportDefaultDeclaration } from 'estree';
18+
import { ExportDetails, Range, ExportClosureMapping } from '../types';
19+
20+
export function NamedDeclaration(declaration: ExportNamedDeclaration): Array<ExportDetails> {
21+
const range: Range = declaration.range as Range;
22+
const source: string | null =
23+
typeof declaration?.source?.value === 'string' ? declaration.source.value : null;
24+
25+
if (declaration.specifiers) {
26+
const exportDetails: Array<ExportDetails> = [];
27+
28+
for (const specifier of declaration.specifiers) {
29+
exportDetails.push({
30+
local: specifier.local.name,
31+
exported: specifier.exported.name,
32+
closureName: specifier.exported.name,
33+
type: ExportClosureMapping.NAMED_CONSTANT,
34+
range,
35+
source,
36+
});
37+
}
38+
39+
return exportDetails;
40+
}
41+
42+
return [];
43+
}
44+
45+
export function DefaultDeclaration(
46+
defaultDeclaration: ExportDefaultDeclaration,
47+
): Array<ExportDetails> {
48+
const range: Range = defaultDeclaration.range as Range;
49+
const { declaration } = defaultDeclaration;
50+
51+
if (declaration.type === 'Identifier' && declaration.name) {
52+
return [
53+
{
54+
local: declaration.name,
55+
exported: declaration.name,
56+
closureName: declaration.name,
57+
type: ExportClosureMapping.NAMED_DEFAULT_FUNCTION,
58+
range,
59+
source: null,
60+
},
61+
];
62+
}
63+
64+
return [];
65+
}

src/parsing/literal-name.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS-IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { PluginContext } from 'rollup';
18+
import { Literal, SimpleLiteral } from 'estree';
19+
20+
export function literalName(context: PluginContext, literal: Literal): string {
21+
// Literal can either be a SimpleLiteral, or RegExpLiteral
22+
if ('regex' in literal) {
23+
// This is a RegExpLiteral
24+
context.warn(
25+
'Rollup Plugin Closure Compiler found a Regex Literal Named Import. `import foo from "*/.hbs"`',
26+
);
27+
return '';
28+
}
29+
30+
const literalValue = (literal as SimpleLiteral).value;
31+
return typeof literalValue === 'string' ? literalValue : '';
32+
}

src/transformers/exports.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
Node,
2323
} from 'estree';
2424
import { TransformSourceDescription } from 'rollup';
25-
import { NamedDeclaration, DefaultDeclaration } from './parsing-utilities';
25+
import { NamedDeclaration, DefaultDeclaration } from '../parsing/export-details';
2626
import { isESMFormat } from '../options';
2727
import {
2828
Transform,
@@ -86,10 +86,10 @@ export default class ExportTransform extends Transform implements TransformInter
8686

8787
walk.simple(program, {
8888
ExportNamedDeclaration(node: ExportNamedDeclaration) {
89-
storeExport(NamedDeclaration(context, node));
89+
storeExport(NamedDeclaration(node));
9090
},
9191
ExportDefaultDeclaration(node: ExportDefaultDeclaration) {
92-
storeExport(DefaultDeclaration(context, node));
92+
storeExport(DefaultDeclaration(node));
9393
},
9494
ExportAllDeclaration(node: ExportAllDeclaration) {
9595
// TODO(KB): This case `export * from "./import"` is not currently supported.

src/transformers/imports.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
IMPORT_NAMESPACE_SPECIFIER,
2222
IMPORT_DEFAULT_SPECIFIER,
2323
} from '../types';
24-
import { literalName, importLocalNames } from './parsing-utilities';
24+
import { literalName } from '../parsing/literal-name';
2525
import { TransformSourceDescription } from 'rollup';
2626
import MagicString from 'magic-string';
2727
import { ImportDeclaration, Identifier, ImportSpecifier } from 'estree';
@@ -42,6 +42,19 @@ interface RangedImport {
4242
range: Range;
4343
}
4444

45+
const VALID_SPECIFIERS = [IMPORT_SPECIFIER, IMPORT_NAMESPACE_SPECIFIER, IMPORT_DEFAULT_SPECIFIER];
46+
function importLocalNames(declaration: ImportDeclaration): Array<string> {
47+
const returnableSpecifiers: Array<string> = [];
48+
49+
for (const specifier of declaration.specifiers || []) {
50+
if (VALID_SPECIFIERS.includes(specifier.type)) {
51+
returnableSpecifiers.push(specifier.local.name);
52+
}
53+
}
54+
55+
return returnableSpecifiers;
56+
}
57+
4558
export default class ImportTransform extends Transform {
4659
private importedExternalsSyntax: { [key: string]: string } = {};
4760
private importedExternalsLocalNames: Array<string> = [];
@@ -117,7 +130,7 @@ window['${DYNAMIC_IMPORT_REPLACEMENT}'] = ${DYNAMIC_IMPORT_REPLACEMENT};`;
117130
source.remove(...range);
118131

119132
self.importedExternalsLocalNames = self.importedExternalsLocalNames.concat(
120-
importLocalNames(self.context, node),
133+
importLocalNames(node),
121134
);
122135
},
123136
Import(node: RangedImport) {

src/transformers/parsing-utilities.ts

Lines changed: 0 additions & 116 deletions
This file was deleted.

src/transformers/replacement-utilities.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/transformers/strict.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { isESMFormat } from '../options';
1919
import { TransformSourceDescription } from 'rollup';
2020
import MagicString from 'magic-string';
2121
import { walk, parse } from '../acorn';
22-
import { ExpressionStatement } from 'estree';
22+
import { ExpressionStatement, SimpleLiteral } from 'estree';
2323
import { extname } from 'path';
2424

2525
export default class StrictTransform extends Transform {
@@ -32,25 +32,17 @@ export default class StrictTransform extends Transform {
3232
* @return code after removing the strict mode declaration (when safe to do so)
3333
*/
3434
public async postCompilation(code: string): Promise<TransformSourceDescription> {
35-
if (this.outputOptions === null) {
36-
this.context.warn(
37-
'Rollup Plugin Closure Compiler, OutputOptions not known before Closure Compiler invocation.',
38-
);
39-
} else if (
40-
isESMFormat(this.outputOptions.format) ||
41-
(this.outputOptions.file && extname(this.outputOptions.file) === '.mjs')
42-
) {
35+
const { format, file } = this.outputOptions;
36+
37+
if (isESMFormat(format) || (file && extname(file) === '.mjs')) {
4338
const source = new MagicString(code);
4439
const program = parse(code);
4540

4641
walk.simple(program, {
4742
ExpressionStatement(node: ExpressionStatement) {
48-
if (
49-
node.expression.type === 'Literal' &&
50-
node.expression.value === 'use strict' &&
51-
node.range
52-
) {
53-
source.remove(node.range[0], node.range[1]);
43+
const { type, value } = node.expression as SimpleLiteral;
44+
if (type === 'Literal' && value === 'use strict' && node.range) {
45+
source.remove(...node.range);
5446
}
5547
},
5648
});

src/types.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export interface TransformInterface {
6969
export class Transform implements TransformInterface {
7070
protected context: PluginContext;
7171
protected inputOptions: InputOptions;
72-
public outputOptions: OutputOptions | null;
72+
public outputOptions: OutputOptions;
7373
public name: string = 'Transform';
7474

7575
constructor(context: PluginContext, inputOptions: InputOptions) {
@@ -92,21 +92,4 @@ export class Transform implements TransformInterface {
9292
code,
9393
};
9494
}
95-
96-
// TODO (KB): Is this needed?
97-
// protected isEntryPoint(id: string) {
98-
// const inputs = (input: InputOption): Array<string> => {
99-
// if (typeof input === 'string') {
100-
// return [input];
101-
// } else if (typeof input === 'object') {
102-
// return Object.values(input);
103-
// } else {
104-
// return input;
105-
// }
106-
// };
107-
108-
// return inputs(this.inputOptions.input)
109-
// .map(input => path.resolve(input))
110-
// .includes(id);
111-
// }
11295
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"outDir": "transpile",
88
"sourceMap": true,
99
"moduleResolution": "node",
10-
"target": "esnext",
10+
"target": "es2019",
1111
"baseUrl": ".",
1212
"allowJs": false,
1313
"noUnusedLocals": true,

0 commit comments

Comments
 (0)