Adds ES5 to ES3 transformer for reserved words

This commit is contained in:
Ron Buckton
2016-10-13 17:53:44 -07:00
parent 65b1cf665e
commit e97368bb3f
50 changed files with 267 additions and 206 deletions

View File

@@ -4,6 +4,7 @@
/// <reference path="transformers/es2017.ts" />
/// <reference path="transformers/es2016.ts" />
/// <reference path="transformers/es2015.ts" />
/// <reference path="transformers/es5.ts" />
/// <reference path="transformers/generators.ts" />
/// <reference path="transformers/module/module.ts" />
/// <reference path="transformers/module/system.ts" />
@@ -129,6 +130,10 @@ namespace ts {
transformers.push(transformGenerators);
}
if (languageVersion < ScriptTarget.ES5) {
transformers.push(transformES5);
}
return transformers;
}

View File

@@ -0,0 +1,83 @@
/// <reference path="../factory.ts" />
/// <reference path="../visitor.ts" />
/*@internal*/
namespace ts {
/**
* Transforms ES5 syntax into ES3 syntax.
*
* @param context Context and state information for the transformation.
*/
export function transformES5(context: TransformationContext) {
const previousOnSubstituteNode = context.onSubstituteNode;
context.onSubstituteNode = onSubstituteNode;
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
context.enableSubstitution(SyntaxKind.PropertyAssignment);
return transformSourceFile;
/**
* Transforms an ES5 source file to ES3.
*
* @param node A SourceFile
*/
function transformSourceFile(node: SourceFile) {
return node;
}
/**
* Hooks node substitutions.
*
* @param emitContext The context for the emitter.
* @param node The node to substitute.
*/
function onSubstituteNode(emitContext: EmitContext, node: Node) {
node = previousOnSubstituteNode(emitContext, node);
if (isPropertyAccessExpression(node)) {
return substitutePropertyAccessExpression(node);
}
else if (isPropertyAssignment(node)) {
return substitutePropertyAssignment(node);
}
return node;
}
/**
* Substitutes a PropertyAccessExpression whose name is a reserved word.
*
* @param node A PropertyAccessExpression
*/
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
const literalName = trySubstituteReservedName(node.name);
if (literalName) {
return createElementAccess(node.expression, literalName, /*location*/ node);
}
return node;
}
/**
* Substitutes a PropertyAssignment whose name is a reserved word.
*
* @param node A PropertyAssignment
*/
function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment {
const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name);
if (literalName) {
return updatePropertyAssignment(node, literalName, node.initializer);
}
return node;
}
/**
* If an identifier name is a reserved word, returns a string literal for the name.
*
* @param name An Identifier
*/
function trySubstituteReservedName(name: Identifier) {
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
return createLiteral(name, /*location*/ name);
}
return undefined;
}
}
}

View File

@@ -958,39 +958,19 @@ namespace ts {
const declaration = resolver.getReferencedImportDeclaration(node);
if (declaration) {
if (isImportClause(declaration)) {
if (languageVersion >= ScriptTarget.ES5) {
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent),
createIdentifier("default"),
/*location*/ node
);
}
else {
// TODO: ES3 transform to handle x.default -> x["default"]
return createElementAccess(
getGeneratedNameForNode(declaration.parent),
createLiteral("default"),
/*location*/ node
);
}
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent),
createIdentifier("default"),
/*location*/ node
);
}
else if (isImportSpecifier(declaration)) {
const name = declaration.propertyName || declaration.name;
if (name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion <= ScriptTarget.ES3) {
// TODO: ES3 transform to handle x.default -> x["default"]
return createElementAccess(
getGeneratedNameForNode(declaration.parent.parent.parent),
createLiteral(name.text),
/*location*/ node
);
}
else {
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent.parent.parent),
getSynthesizedClone(name),
/*location*/ node
);
}
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent.parent.parent),
getSynthesizedClone(name),
/*location*/ node
);
}
}
}
@@ -1027,15 +1007,10 @@ namespace ts {
function createExportAssignment(name: Identifier, value: Expression) {
return createAssignment(
name.originalKeywordKind === SyntaxKind.DefaultKeyword && languageVersion === ScriptTarget.ES3
? createElementAccess(
createIdentifier("exports"),
createLiteral(name.text)
)
: createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(name)
),
createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(name)
),
value
);
}

View File

@@ -19,7 +19,6 @@ namespace ts {
const compilerOptions = context.getCompilerOptions();
const resolver = context.getEmitResolver();
const host = context.getEmitHost();
const languageVersion = getEmitScriptTarget(compilerOptions);
const previousOnSubstituteNode = context.onSubstituteNode;
const previousOnEmitNode = context.onEmitNode;
context.onSubstituteNode = onSubstituteNode;
@@ -1317,12 +1316,7 @@ namespace ts {
return undefined;
}
if (name.originalKeywordKind && languageVersion === ScriptTarget.ES3) {
return createElementAccess(importAlias, createLiteral(name.text));
}
else {
return createPropertyAccess(importAlias, getSynthesizedClone(name));
}
return createPropertyAccess(importAlias, getSynthesizedClone(name));
}
function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) {

View File

@@ -27,6 +27,7 @@
"transformers/es2017.ts",
"transformers/es2016.ts",
"transformers/es2015.ts",
"transformers/es5.ts",
"transformers/generators.ts",
"transformers/destructuring.ts",
"transformers/module/module.ts",

View File

@@ -29,6 +29,7 @@
"../compiler/transformers/es2017.ts",
"../compiler/transformers/es2016.ts",
"../compiler/transformers/es2015.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/generators.ts",
"../compiler/transformers/destructuring.ts",
"../compiler/transformers/module/module.ts",

View File

@@ -28,6 +28,7 @@
"../compiler/transformers/es2017.ts",
"../compiler/transformers/es2016.ts",
"../compiler/transformers/es2015.ts",
"../compiler/transformers/es5.ts",
"../compiler/transformers/generators.ts",
"../compiler/transformers/destructuring.ts",
"../compiler/transformers/module/module.ts",