Merge branch 'master' into emitHelper

This commit is contained in:
Ron Buckton 2016-11-16 10:14:20 -08:00
commit 9a1a605f7c
3 changed files with 20 additions and 43 deletions

View file

@ -78,7 +78,7 @@ namespace ts {
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult {
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
let scopeModificationDisabled = false;
let lexicalEnvironmentDisabled = false;
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
@ -118,7 +118,7 @@ namespace ts {
const transformed = map(sourceFiles, transformSourceFile);
// Disable modification of the lexical environment.
scopeModificationDisabled = true;
lexicalEnvironmentDisabled = true;
return {
transformed,
@ -213,7 +213,7 @@ namespace ts {
* Records a hoisted variable declaration for the provided name within a lexical environment.
*/
function hoistVariableDeclaration(name: Identifier): void {
Debug.assert(!scopeModificationDisabled, "Cannot modify the lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
const decl = createVariableDeclaration(name);
if (!lexicalEnvironmentVariableDeclarations) {
lexicalEnvironmentVariableDeclarations = [decl];
@ -227,7 +227,7 @@ namespace ts {
* Records a hoisted function declaration within a lexical environment.
*/
function hoistFunctionDeclaration(func: FunctionDeclaration): void {
Debug.assert(!scopeModificationDisabled, "Cannot modify the lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
if (!lexicalEnvironmentFunctionDeclarations) {
lexicalEnvironmentFunctionDeclarations = [func];
}
@ -241,7 +241,7 @@ namespace ts {
* are pushed onto a stack, and the related storage variables are reset.
*/
function startLexicalEnvironment(): void {
Debug.assert(!scopeModificationDisabled, "Cannot start a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot start a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
// Save the current lexical environment. Rather than resizing the array we adjust the
@ -257,14 +257,14 @@ namespace ts {
/** Suspends the current lexical environment, usually after visiting a parameter list. */
function suspendLexicalEnvironment(): void {
Debug.assert(!scopeModificationDisabled, "Cannot suspend a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot suspend a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
lexicalEnvironmentSuspended = true;
}
/** Resumes a suspended lexical environment, usually before visiting a function body. */
function resumeLexicalEnvironment(): void {
Debug.assert(!scopeModificationDisabled, "Cannot resume a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot resume a lexical environment during the print phase.");
Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
lexicalEnvironmentSuspended = false;
}
@ -274,7 +274,7 @@ namespace ts {
* any hoisted declarations added in this environment are returned.
*/
function endLexicalEnvironment(): Statement[] {
Debug.assert(!scopeModificationDisabled, "Cannot end a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot end a lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
let statements: Statement[];
@ -310,13 +310,13 @@ namespace ts {
}
function requestEmitHelper(helper: EmitHelper): void {
Debug.assert(!scopeModificationDisabled, "Cannot modify the lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
emitHelpers = append(emitHelpers, helper);
}
function readEmitHelpers(): EmitHelper[] | undefined {
Debug.assert(!scopeModificationDisabled, "Cannot modify the lexical environment during the print phase.");
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
const helpers = emitHelpers;
emitHelpers = undefined;
return helpers;

View file

@ -6,7 +6,7 @@ namespace ts {
interface FlattenContext {
context: TransformationContext;
level: FlattenLevel;
doNotRecordTempVariablesInLine: boolean;
hoistTempVariables: boolean;
emitExpression: (value: Expression) => void;
emitBindingOrAssignment: (target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) => void;
createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern;
@ -57,7 +57,7 @@ namespace ts {
const flattenContext: FlattenContext = {
context,
level,
doNotRecordTempVariablesInLine: true,
hoistTempVariables: true,
emitExpression,
emitBindingOrAssignment,
createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern,
@ -126,7 +126,7 @@ namespace ts {
* @param context The transformation context.
* @param boundValue The value bound to the declaration.
* @param skipInitializer A value indicating whether to ignore the initializer of `node`.
* @param doNotRecordTempVariablesInLine Indicates whether temporary variables should not be recored in-line.
* @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line.
* @param level Indicates the extent to which flattening should occur.
*/
export function flattenDestructuringBinding(
@ -135,16 +135,15 @@ namespace ts {
context: TransformationContext,
level: FlattenLevel,
rval?: Expression,
doNotRecordTempVariablesInLine?: boolean,
hoistTempVariables?: boolean,
skipInitializer?: boolean): VariableDeclaration[] {
let pendingExpressions: Expression[];
const pendingDeclarations: { pendingExpressions?: Expression[], name: BindingName, value: Expression, location?: TextRange, original?: Node; }[] = [];
const declarations: VariableDeclaration[] = [];
const flattenContext: FlattenContext = {
context,
level,
doNotRecordTempVariablesInLine,
hoistTempVariables,
emitExpression,
emitBindingOrAssignment,
createArrayBindingOrAssignmentPattern: makeArrayBindingPattern,
@ -152,12 +151,10 @@ namespace ts {
createArrayBindingOrAssignmentElement: makeBindingElement,
visitor
};
flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
if (pendingExpressions) {
const temp = createTempVariable(/*recordTempVariable*/ undefined);
if (doNotRecordTempVariablesInLine) {
if (hoistTempVariables) {
const value = inlineExpressions(pendingExpressions);
pendingExpressions = undefined;
emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined);
@ -173,7 +170,6 @@ namespace ts {
pendingDeclaration.value = temp;
}
}
for (const { pendingExpressions, name, value, location, original } of pendingDeclarations) {
const variable = createVariableDeclaration(
name,
@ -187,7 +183,6 @@ namespace ts {
aggregateTransformFlags(variable);
declarations.push(variable);
}
return declarations;
function emitExpression(value: Expression) {
@ -330,7 +325,7 @@ namespace ts {
// can perform the ObjectRest destructuring in a different declaration
if (element.transformFlags & TransformFlags.ContainsObjectRest) {
const temp = createTempVariable(/*recordTempVariable*/ undefined);
if (flattenContext.doNotRecordTempVariablesInLine) {
if (flattenContext.hoistTempVariables) {
flattenContext.context.hoistVariableDeclaration(temp);
}
@ -419,7 +414,7 @@ namespace ts {
}
else {
const temp = createTempVariable(/*recordTempVariable*/ undefined);
if (flattenContext.doNotRecordTempVariablesInLine) {
if (flattenContext.hoistTempVariables) {
flattenContext.context.hoistVariableDeclaration(temp);
flattenContext.emitExpression(createAssignment(temp, value, location));
}
@ -430,46 +425,28 @@ namespace ts {
}
}
/**
* Creates an ArrayBindingPattern from an array of BindingOrAssignmentElement nodes.
*/
function makeArrayBindingPattern(elements: BindingOrAssignmentElement[]) {
Debug.assertEachNode(elements, isArrayBindingElement);
return createArrayBindingPattern(<ArrayBindingElement[]>elements);
}
/**
* Creates an ArrayLiteralExpression assignment pattern from an array of BindingOrAssignmentElement nodes.
*/
function makeArrayAssignmentPattern(elements: BindingOrAssignmentElement[]) {
return createArrayLiteral(map(elements, convertToArrayAssignmentElement));
}
/**
* Creates an ObjectBindingPattern from an array of BindingOrAssignmentElement nodes.
*/
function makeObjectBindingPattern(elements: BindingOrAssignmentElement[]) {
Debug.assertEachNode(elements, isBindingElement);
return createObjectBindingPattern(<BindingElement[]>elements);
}
/**
* Creates an ObjectLiteralExpression assignment pattern from an array of BindingOrAssignmentElement nodes.
*/
function makeObjectAssignmentPattern(elements: BindingOrAssignmentElement[]) {
return createObjectLiteral(map(elements, convertToObjectAssignmentElement));
}
/**
* Creates a BindingElement for a name.
*/
function makeBindingElement(name: Identifier) {
return createBindingElement(/*propertyName*/ undefined, /*dotDotDotToken*/ undefined, name);
}
/**
* Creates an assignment element for a name.
*/
function makeAssignmentElement(name: Identifier) {
return name;
}

View file

@ -1907,7 +1907,7 @@ namespace ts {
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
// If we are here it is because the name contains a binding pattern.
if (isBindingPattern(node.name)) {
const doNotRecordTempVariablesInLine = enclosingVariableStatement
const hoistTempVariables = enclosingVariableStatement
&& hasModifier(enclosingVariableStatement, ModifierFlags.Export);
return flattenDestructuringBinding(
node,
@ -1915,7 +1915,7 @@ namespace ts {
context,
FlattenLevel.All,
/*value*/ undefined,
doNotRecordTempVariablesInLine
hoistTempVariables
);
}