mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-11 02:15:10 -05:00
Removed tree rewriting code
This commit is contained in:
@@ -2744,249 +2744,6 @@ module ts {
|
||||
emitObjectLiteralBody(node, properties.length);
|
||||
}
|
||||
|
||||
function createSynthesizedNode(kind: SyntaxKind): Node {
|
||||
var node = createNode(kind);
|
||||
node.pos = -1;
|
||||
node.end = -1;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function emitDownlevelObjectLiteralWithComputedPropertiesThroughRewrite(node: ObjectLiteralExpression, firstComputedPropertyIndex: number): void {
|
||||
var parenthesizedObjectLiteral = createDownlevelObjectLiteralWithComputedProperties(node, firstComputedPropertyIndex);
|
||||
return emit(parenthesizedObjectLiteral);
|
||||
}
|
||||
|
||||
function createDownlevelObjectLiteralWithComputedProperties(originalObjectLiteral: ObjectLiteralExpression, firstComputedPropertyIndex: number): ParenthesizedExpression {
|
||||
// For computed properties, we need to create a unique handle to the object
|
||||
// literal so we can modify it without risking internal assignments tainting the object.
|
||||
var tempVar = createAndRecordTempVariable(originalObjectLiteral);
|
||||
|
||||
// Hold onto the initial non-computed properties in a new object literal,
|
||||
// then create the rest through property accesses on the temp variable.
|
||||
var initialObjectLiteral = <ObjectLiteralExpression>createSynthesizedNode(SyntaxKind.ObjectLiteralExpression);
|
||||
initialObjectLiteral.properties = <NodeArray<ObjectLiteralElement>>originalObjectLiteral.properties.slice(0, firstComputedPropertyIndex);
|
||||
initialObjectLiteral.flags |= NodeFlags.MultiLine;
|
||||
|
||||
// The comma expressions that will patch the object literal.
|
||||
// This will end up being something like '_a = { ... }, _a.x = 10, _a.y = 20, _a'.
|
||||
var propertyPatches = createBinaryExpression(tempVar, SyntaxKind.EqualsToken, initialObjectLiteral);
|
||||
|
||||
ts.forEach(originalObjectLiteral.properties, property => {
|
||||
var patchedProperty = tryCreatePatchingPropertyAssignment(originalObjectLiteral, tempVar, property);
|
||||
if (patchedProperty) {
|
||||
// TODO(drosen): Preserve comments
|
||||
//var leadingComments = getLeadingCommentRanges(currentSourceFile.text, property.pos);
|
||||
//var trailingComments = getTrailingCommentRanges(currentSourceFile.text, property.end);
|
||||
//addCommentsToSynthesizedNode(patchedProperty, leadingComments, trailingComments);
|
||||
|
||||
propertyPatches = createBinaryExpression(propertyPatches, SyntaxKind.CommaToken, patchedProperty);
|
||||
}
|
||||
});
|
||||
|
||||
// Finally, return the temp variable.
|
||||
propertyPatches = createBinaryExpression(propertyPatches, SyntaxKind.CommaToken, tempVar);
|
||||
|
||||
var result = createParenthesizedExpression(propertyPatches);
|
||||
|
||||
// TODO(drosen): Preserve comments
|
||||
// var leadingComments = getLeadingCommentRanges(currentSourceFile.text, originalObjectLiteral.pos);
|
||||
// var trailingComments = getTrailingCommentRanges(currentSourceFile.text, originalObjectLiteral.end);
|
||||
//addCommentsToSynthesizedNode(result, leadingComments, trailingComments);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function addCommentsToSynthesizedNode(node: SynthesizedNode, leadingCommentRanges: CommentRange[], trailingCommentRanges: CommentRange[]): void {
|
||||
node.leadingCommentRanges = leadingCommentRanges;
|
||||
node.trailingCommentRanges = trailingCommentRanges;
|
||||
}
|
||||
|
||||
// Returns 'undefined' if a property has already been accounted for
|
||||
// (e.g. a 'get' accessor which has already been emitted along with its 'set' accessor).
|
||||
function tryCreatePatchingPropertyAssignment(objectLiteral: ObjectLiteralExpression, tempVar: Identifier, property: ObjectLiteralElement): Expression {
|
||||
var leftHandSide = createMemberAccessForPropertyName(tempVar, property.name);
|
||||
var maybeRightHandSide = tryGetRightHandSideOfPatchingPropertyAssignment(objectLiteral, property);
|
||||
|
||||
return maybeRightHandSide && createBinaryExpression(leftHandSide, SyntaxKind.EqualsToken, maybeRightHandSide);
|
||||
}
|
||||
|
||||
function tryGetRightHandSideOfPatchingPropertyAssignment(objectLiteral: ObjectLiteralExpression, property: ObjectLiteralElement) {
|
||||
switch (property.kind) {
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return (<PropertyAssignment>property).initializer;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
// TODO: (andersh) Technically it isn't correct to make an identifier here since getExpressionNamePrefix returns
|
||||
// a string containing a dotted name. In general I'm not a fan of mini tree rewriters as this one, elsewhere we
|
||||
// manage by just emitting strings (which is a lot more performant).
|
||||
//var prefix = createIdentifier(resolver.getExpressionNamePrefix((<ShorthandPropertyAssignment>property).name));
|
||||
//return createPropertyAccessExpression(prefix, (<ShorthandPropertyAssignment>property).name);
|
||||
return createIdentifier(resolver.getExpressionNameSubstitution((<ShorthandPropertyAssignment>property).name));
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return createFunctionExpression((<MethodDeclaration>property).parameters, (<MethodDeclaration>property).body);
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
var { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(objectLiteral.properties, <AccessorDeclaration>property);
|
||||
|
||||
// Only emit the first accessor.
|
||||
if (firstAccessor !== property) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var propertyDescriptor = <ObjectLiteralExpression>createSynthesizedNode(SyntaxKind.ObjectLiteralExpression);
|
||||
|
||||
var descriptorProperties = <NodeArray<ObjectLiteralElement>>[];
|
||||
if (getAccessor) {
|
||||
var getProperty = createPropertyAssignment(createIdentifier("get"), createFunctionExpression(getAccessor.parameters, getAccessor.body));
|
||||
descriptorProperties.push(getProperty);
|
||||
}
|
||||
if (setAccessor) {
|
||||
var setProperty = createPropertyAssignment(createIdentifier("set"), createFunctionExpression(setAccessor.parameters, setAccessor.body));
|
||||
descriptorProperties.push(setProperty);
|
||||
}
|
||||
|
||||
var trueExpr = <PrimaryExpression>createSynthesizedNode(SyntaxKind.TrueKeyword);
|
||||
|
||||
var enumerableTrue = createPropertyAssignment(createIdentifier("enumerable"), trueExpr);
|
||||
descriptorProperties.push(enumerableTrue);
|
||||
|
||||
var configurableTrue = createPropertyAssignment(createIdentifier("configurable"), trueExpr);
|
||||
descriptorProperties.push(configurableTrue);
|
||||
|
||||
propertyDescriptor.properties = descriptorProperties;
|
||||
|
||||
var objectDotDefineProperty = createPropertyAccessExpression(createIdentifier("Object"), createIdentifier("defineProperty"));
|
||||
return createCallExpression(objectDotDefineProperty, createNodeArray(propertyDescriptor));
|
||||
|
||||
default:
|
||||
Debug.fail(`ObjectLiteralElement kind ${property.kind} not accounted for.`);
|
||||
}
|
||||
}
|
||||
|
||||
function createParenthesizedExpression(expression: Expression) {
|
||||
var result = <ParenthesizedExpression>createSynthesizedNode(SyntaxKind.ParenthesizedExpression);
|
||||
result.expression = expression;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createNodeArray<T extends Node>(...elements: T[]): NodeArray<T> {
|
||||
var result = <NodeArray<T>>elements;
|
||||
result.pos = -1;
|
||||
result.end = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createBinaryExpression(left: Expression, operator: SyntaxKind, right: Expression): BinaryExpression {
|
||||
var result = <BinaryExpression>createSynthesizedNode(SyntaxKind.BinaryExpression);
|
||||
result.operatorToken = createSynthesizedNode(operator);
|
||||
result.left = left;
|
||||
result.right = right;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createMemberAccessForPropertyName(expression: LeftHandSideExpression, memberName: DeclarationName): PropertyAccessExpression | ElementAccessExpression {
|
||||
if (memberName.kind === SyntaxKind.Identifier) {
|
||||
return createPropertyAccessExpression(expression, <Identifier>memberName);
|
||||
}
|
||||
else if (memberName.kind === SyntaxKind.StringLiteral || memberName.kind === SyntaxKind.NumericLiteral) {
|
||||
return createElementAccessExpression(expression, <LiteralExpression>memberName);
|
||||
}
|
||||
else if (memberName.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return createElementAccessExpression(expression, (<ComputedPropertyName>memberName).expression);
|
||||
}
|
||||
else {
|
||||
Debug.fail(`Kind '${memberName.kind}' not accounted for.`);
|
||||
}
|
||||
}
|
||||
|
||||
function createPropertyAssignment(name: LiteralExpression | Identifier, initializer: Expression) {
|
||||
var result = <PropertyAssignment>createSynthesizedNode(SyntaxKind.PropertyAssignment);
|
||||
result.name = name;
|
||||
result.initializer = initializer;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createFunctionExpression(parameters: NodeArray<ParameterDeclaration>, body: Block): FunctionExpression {
|
||||
var result = <FunctionExpression>createSynthesizedNode(SyntaxKind.FunctionExpression);
|
||||
result.parameters = parameters;
|
||||
result.body = body;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createPropertyAccessExpression(expression: LeftHandSideExpression, name: Identifier): PropertyAccessExpression {
|
||||
var result = <PropertyAccessExpression>createSynthesizedNode(SyntaxKind.PropertyAccessExpression);
|
||||
result.expression = expression;
|
||||
result.name = name;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createElementAccessExpression(expression: LeftHandSideExpression, argumentExpression: Expression): ElementAccessExpression {
|
||||
var result = <ElementAccessExpression>createSynthesizedNode(SyntaxKind.ElementAccessExpression);
|
||||
result.expression = expression;
|
||||
result.argumentExpression = argumentExpression;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createIdentifier(name: string) {
|
||||
var result = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||
result.text = name;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createCallExpression(invokedExpression: MemberExpression, arguments: NodeArray<Expression>) {
|
||||
var result = <CallExpression>createSynthesizedNode(SyntaxKind.CallExpression);
|
||||
result.expression = invokedExpression;
|
||||
result.arguments = arguments;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function emitObjectLiteralThroughRewrite(node: ObjectLiteralExpression): void {
|
||||
var properties = node.properties;
|
||||
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
var numProperties = properties.length;
|
||||
|
||||
// Find the first computed property.
|
||||
// Everything until that point can be emitted as part of the initial object literal.
|
||||
var numInitialNonComputedProperties = numProperties;
|
||||
for (var i = 0, n = properties.length; i < n; i++) {
|
||||
if (properties[i].name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
numInitialNonComputedProperties = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var hasComputedProperty = numInitialNonComputedProperties !== properties.length;
|
||||
if (hasComputedProperty) {
|
||||
emitDownlevelObjectLiteralWithComputedPropertiesThroughRewrite(node, numInitialNonComputedProperties);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Ordinary case: either the object has no computed properties
|
||||
// or we're compiling with an ES6+ target.
|
||||
write("{");
|
||||
|
||||
var properties = node.properties;
|
||||
if (properties.length) {
|
||||
emitLinePreservingList(node, properties, /*allowTrailingComma:*/ languageVersion >= ScriptTarget.ES5, /*spacesBetweenBraces:*/ true)
|
||||
}
|
||||
|
||||
write("}");
|
||||
}
|
||||
|
||||
function emitComputedPropertyName(node: ComputedPropertyName) {
|
||||
write("[");
|
||||
emit(node.expression);
|
||||
|
||||
Reference in New Issue
Block a user