Adjusts source map emit for members

This commit is contained in:
Ron Buckton
2016-04-26 15:29:46 -07:00
parent 6e9eb35244
commit 58125279cd
14 changed files with 427 additions and 382 deletions
+15 -6
View File
@@ -1989,7 +1989,7 @@ namespace ts {
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
// These nodes are ES6 syntax.
transformFlags = TransformFlags.AssertES6;
transformFlags = TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern;
break;
case SyntaxKind.Decorator:
@@ -2068,9 +2068,14 @@ namespace ts {
return computeVariableDeclaration(<VariableDeclaration>node, subtreeFlags);
case SyntaxKind.VariableDeclarationList:
excludeFlags = TransformFlags.VariableDeclarationListExcludes;
if (subtreeFlags & TransformFlags.ContainsBindingPattern) {
transformFlags |= TransformFlags.AssertES6;
}
// If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
if (node.flags & NodeFlags.BlockScoped) {
transformFlags = TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding;
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsBlockScopedBinding;
}
break;
@@ -2172,7 +2177,7 @@ namespace ts {
// A GetAccessor or SetAccessor is TypeScript syntax if it is either abstract,
// or has a decorator.
if ((<AccessorDeclaration>node).body === undefined
|| hasModifier(node, ModifierFlags.Abstract)
|| hasModifier(node, ModifierFlags.Async | ModifierFlags.Abstract)
|| subtreeFlags & TransformFlags.ContainsDecorators) {
transformFlags = TransformFlags.AssertTypeScript;
}
@@ -2279,11 +2284,11 @@ namespace ts {
// If a parameter has an initializer, a binding pattern or a dotDotDot token, then
// it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
if (isDefined(node.initializer) || isDefined(node.dotDotDotToken) || isBindingPattern(node.name)) {
if (subtreeFlags & TransformFlags.ContainsBindingPattern || isDefined(node.initializer) || isDefined(node.dotDotDotToken)) {
transformFlags |= TransformFlags.AssertES6 | TransformFlags.ContainsDefaultValueAssignments;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ParameterExcludes);
}
function computeParenthesizedExpression(node: ParenthesizedExpression, subtreeFlags: TransformFlags) {
@@ -2426,7 +2431,7 @@ namespace ts {
// A VariableDeclaration with a binding pattern is ES6 syntax.
if (isBindingPattern((<VariableDeclaration>node).name)) {
transformFlags = TransformFlags.AssertES6;
transformFlags = TransformFlags.AssertES6 | TransformFlags.ContainsBindingPattern;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
@@ -2446,6 +2451,10 @@ namespace ts {
transformFlags = TransformFlags.AssertES6 | TransformFlags.AssertTypeScript;
}
if (node.declarationList.transformFlags & TransformFlags.ContainsBindingPattern) {
transformFlags |= TransformFlags.AssertES6;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.None);
}
+27 -17
View File
@@ -5,12 +5,13 @@ namespace ts {
export interface CommentWriter {
reset(): void;
setSourceFile(sourceFile: SourceFile): void;
getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
getLeadingComments(range: TextRange): CommentRange[];
getLeadingCommentsOfPosition(pos: number): CommentRange[];
getTrailingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
getTrailingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
getTrailingComments(range: TextRange): CommentRange[];
getTrailingCommentsOfPosition(pos: number): CommentRange[];
emitLeadingComments(range: Node, comments: CommentRange[], getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): void;
emitLeadingComments(range: TextRange, comments: CommentRange[]): void;
emitTrailingComments(range: TextRange, comments: CommentRange[]): void;
emitLeadingDetachedComments(range: TextRange): void;
@@ -43,11 +44,11 @@ namespace ts {
return {
reset,
setSourceFile,
getLeadingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[] { return undefined; },
getLeadingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[] { return undefined; },
getLeadingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
getTrailingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[] { return undefined; },
getTrailingComments(range: TextRange, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[] { return undefined; },
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
emitLeadingComments(range: TextRange, comments: CommentRange[]): void { },
emitLeadingComments(range: Node | TextRange, comments: CommentRange[], getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): void { },
emitTrailingComments(range: TextRange, comments: CommentRange[]): void { },
emitLeadingDetachedComments,
emitTrailingDetachedComments(node: TextRange, contextNode?: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): void {}
@@ -78,11 +79,11 @@ namespace ts {
};
function getLeadingComments(range: TextRange): CommentRange[];
function getLeadingComments(node: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
function getLeadingComments(nodeOrRange: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange) {
function getLeadingComments(node: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
function getLeadingComments(nodeOrRange: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange) {
let range = nodeOrRange;
if (getCustomCommentRangeForNodeCallback) {
range = getCustomCommentRangeForNodeCallback(<Node>nodeOrRange) || range;
if (getCustomTextRangeForNodeCallback) {
range = getCustomTextRangeForNodeCallback(<Node>nodeOrRange) || range;
}
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(<Node>nodeOrRange)) {
@@ -125,15 +126,15 @@ namespace ts {
}
function getTrailingComments(range: TextRange): CommentRange[];
function getTrailingComments(node: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
function getTrailingComments(nodeOrRange: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomCommentRangeForNodeCallback?: (node: Node) => TextRange) {
function getTrailingComments(node: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): CommentRange[];
function getTrailingComments(nodeOrRange: TextRange | Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean, getCustomTextRangeForNodeCallback?: (node: Node) => TextRange) {
let range = <TextRange>nodeOrRange;
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(<Node>nodeOrRange)) {
return undefined;
}
if (getCustomCommentRangeForNodeCallback) {
range = getCustomCommentRangeForNodeCallback(<Node>nodeOrRange) || range;
if (getCustomTextRangeForNodeCallback) {
range = getCustomTextRangeForNodeCallback(<Node>nodeOrRange) || range;
}
return getTrailingCommentsOfPosition(range.end);
@@ -161,11 +162,20 @@ namespace ts {
return consumeCommentRanges(comments);
}
function emitLeadingComments(range: TextRange, comments: CommentRange[]) {
emitNewLineBeforeLeadingComments(currentLineMap, writer, range, comments);
function emitLeadingComments(range: Node, comments: CommentRange[], getCustomTextRangeForNodeCallback?: (node: Node) => TextRange): void;
function emitLeadingComments(range: TextRange, comments: CommentRange[]): void;
function emitLeadingComments(nodeOrRange: Node | TextRange, comments: CommentRange[], getCustomTextRangeForNodeCallback?: (node: Node) => TextRange) {
if (comments && comments.length > 0) {
let range = <TextRange>nodeOrRange;
if (getCustomTextRangeForNodeCallback) {
range = getCustomTextRangeForNodeCallback(<Node>nodeOrRange);
}
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
emitNewLineBeforeLeadingComments(currentLineMap, writer, range, comments);
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
}
}
function emitTrailingComments(range: TextRange, comments: CommentRange[]) {
+11 -108
View File
@@ -205,10 +205,11 @@ namespace ts {
// Type members
export function createMethod(modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
export function createMethod(modifiers: Modifier[], asteriskToken: Node, name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <MethodDeclaration>createNode(SyntaxKind.MethodDeclaration, location);
node.decorators = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.asteriskToken = asteriskToken;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.parameters = createNodeArray(parameters);
@@ -227,24 +228,24 @@ namespace ts {
return node;
}
export function createGetAccessor(modifiers: Modifier[], name: string | PropertyName, body: Block, location?: TextRange) {
export function createGetAccessor(modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <GetAccessorDeclaration>createNode(SyntaxKind.GetAccessor, location);
node.decorators = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.parameters = createNodeArray<ParameterDeclaration>();
node.parameters = createNodeArray(parameters);
node.body = body;
return node;
}
export function createSetAccessor(modifiers: Modifier[], name: string | PropertyName, parameter: ParameterDeclaration, body: Block, location?: TextRange) {
export function createSetAccessor(modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block, location?: TextRange) {
const node = <SetAccessorDeclaration>createNode(SyntaxKind.SetAccessor, location);
node.decorators = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.name = typeof name === "string" ? createIdentifier(name) : name;
node.typeParameters = undefined;
node.parameters = createNodeArray([parameter]);
node.parameters = createNodeArray(parameters);
node.body = body;
return node;
}
@@ -503,8 +504,8 @@ namespace ts {
return node;
}
export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement, location?: TextRange) {
const node = <ForStatement>createNode(SyntaxKind.ForStatement, location);
export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement, location?: TextRange, emitOptions?: NodeEmitOptions) {
const node = <ForStatement>createNode(SyntaxKind.ForStatement, location, /*flags*/ undefined, emitOptions);
node.initializer = initializer;
node.condition = condition;
node.incrementor = incrementor;
@@ -923,105 +924,6 @@ namespace ts {
);
}
export interface PropertyDescriptorOptions {
[key: string]: boolean | Expression;
get?: Expression;
set?: Expression;
value?: Expression;
enumerable?: boolean | Expression;
configurable?: boolean | Expression;
writable?: boolean | Expression;
}
export interface PropertyDescriptorExtendedOptions {
[key: string]: PropertyDescriptorExtendedOption;
get?: PropertyDescriptorExtendedOption;
set?: PropertyDescriptorExtendedOption;
value?: PropertyDescriptorExtendedOption;
enumerable?: PropertyDescriptorExtendedOption;
configurable?: PropertyDescriptorExtendedOption;
writable?: PropertyDescriptorExtendedOption;
}
export interface PropertyDescriptorExtendedOption {
location?: TextRange;
original?: Node;
emitFlags?: NodeEmitFlags;
newLine?: boolean;
}
export function createObjectDefineProperty(target: Expression, memberName: Expression, descriptor: PropertyDescriptorOptions, preferNewLine?: boolean, location?: TextRange, descriptorOptions?: PropertyDescriptorExtendedOptions, context?: TransformationContext) {
return createCall(
createPropertyAccess(
createIdentifier("Object"),
"defineProperty"
),
[
target,
memberName,
createObjectLiteral(
createPropertyDescriptorProperties(descriptor, descriptorOptions, preferNewLine, context),
/*location*/ undefined,
/*multiLine*/ preferNewLine
)
],
location
);
}
function createPropertyDescriptorProperties(descriptor: PropertyDescriptorOptions, descriptorExtendedOptions: PropertyDescriptorExtendedOptions, preferNewLine: boolean, context: TransformationContext) {
const properties: ObjectLiteralElement[] = [];
addPropertyDescriptorPropertyAssignmentIfNeeded(properties, "get", descriptor, descriptorExtendedOptions, preferNewLine, context);
addPropertyDescriptorPropertyAssignmentIfNeeded(properties, "set", descriptor, descriptorExtendedOptions, preferNewLine, context);
addPropertyDescriptorPropertyAssignmentIfNeeded(properties, "value", descriptor, descriptorExtendedOptions, preferNewLine, context);
addPropertyDescriptorPropertyAssignmentIfNeeded(properties, "enumerable", descriptor, descriptorExtendedOptions, preferNewLine, context);
addPropertyDescriptorPropertyAssignmentIfNeeded(properties, "configurable", descriptor, descriptorExtendedOptions, preferNewLine, context);
addPropertyDescriptorPropertyAssignmentIfNeeded(properties, "writable", descriptor, descriptorExtendedOptions, preferNewLine, context);
return properties;
}
function addPropertyDescriptorPropertyAssignmentIfNeeded(properties: ObjectLiteralElement[], name: string, descriptor: PropertyDescriptorOptions, descriptorExtendedOptions: PropertyDescriptorExtendedOptions, preferNewLine: boolean, context: TransformationContext) {
const value = getProperty(descriptor, name);
if (value !== undefined) {
let options: PropertyDescriptorExtendedOption;
let location: TextRange;
let original: Node;
let emitFlags: NodeEmitFlags;
if (descriptorExtendedOptions !== undefined) {
options = getProperty(descriptorExtendedOptions, name);
if (options !== undefined) {
location = options.location;
original = options.original;
emitFlags = options.emitFlags;
if (options.newLine !== undefined) {
preferNewLine = options.newLine;
}
}
}
const property = createPropertyAssignment(
name,
typeof value === "boolean" ? createLiteral(value) : value,
location
);
if (emitFlags !== undefined) {
Debug.assert(context !== undefined, "TransformationContext must be supplied when emitFlags are provided.");
context.setNodeEmitFlags(property, emitFlags);
}
if (original) {
property.original = original;
}
if (preferNewLine) {
startOnNewLine(property);
}
properties.push(property);
}
}
function createObjectCreate(prototype: Expression) {
return createCall(
createPropertyAccess(createIdentifier("Object"), "create"),
@@ -1078,6 +980,7 @@ namespace ts {
const getter = createGetAccessor(
/*modifiers*/ undefined,
"value",
[],
createBlock([
createReturn(
createCall(
@@ -1092,7 +995,7 @@ namespace ts {
const setter = createSetAccessor(
/*modifiers*/ undefined,
"value",
createParameter("v"),
[createParameter("v")],
createBlock([
createStatement(
createCall(
@@ -1276,7 +1179,7 @@ namespace ts {
: getSynthesizedClone(node);
}
export function createExpressionForPropertyName(memberName: PropertyName, emitOptions: NodeEmitOptions): Expression {
export function createExpressionForPropertyName(memberName: PropertyName, emitOptions?: NodeEmitOptions): Expression {
if (isIdentifier(memberName)) {
return createLiteral(memberName, /*location*/ undefined, emitOptions);
}
+19 -17
View File
@@ -291,7 +291,7 @@ const _super = (function (geti, seti) {
if (node) {
const flagsToAdd = flags & ~getNodeEmitFlags(node);
if (flagsToAdd) {
setNodeEmitFlags(node, flagsToAdd);
setNodeEmitFlags(node, getNodeEmitFlags(node) | flagsToAdd);
emit(node);
setNodeEmitFlags(node, getNodeEmitFlags(node) & ~flagsToAdd);
return;
@@ -342,7 +342,7 @@ const _super = (function (geti, seti) {
if (node) {
const leadingComments = getLeadingComments(node, shouldSkipLeadingCommentsForNode, getCommentRange);
const trailingComments = getTrailingComments(node, shouldSkipTrailingCommentsForNode, getCommentRange);
emitLeadingComments(node, leadingComments);
emitLeadingComments(node, leadingComments, getCommentRange);
emitStart(node, shouldSkipLeadingSourceMapForNode, shouldSkipSourceMapForChildren, getSourceMapRange);
emitWorker(node);
emitEnd(node, shouldSkipTrailingSourceMapForNode, shouldSkipSourceMapForChildren, getSourceMapRange);
@@ -1305,14 +1305,14 @@ const _super = (function (geti, seti) {
function emitBlock(node: Block, format?: ListFormat) {
if (isSingleLineEmptyBlock(node)) {
writeToken(SyntaxKind.OpenBraceToken, node.pos);
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
write(" ");
writeToken(SyntaxKind.CloseBraceToken, node.statements.end);
writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node);
}
else {
writeToken(SyntaxKind.OpenBraceToken, node.pos);
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
emitBlockStatements(node);
writeToken(SyntaxKind.CloseBraceToken, node.statements.end);
writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node);
}
}
@@ -1408,7 +1408,7 @@ const _super = (function (geti, seti) {
const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos);
write(" ");
writeToken(SyntaxKind.OpenParenToken, openParenPos);
writeToken(SyntaxKind.OpenParenToken, openParenPos, /*contextNode*/ node);
emitForBinding(node.initializer);
write(";");
emitExpressionWithPrefix(" ", node.condition);
@@ -1464,7 +1464,7 @@ const _super = (function (geti, seti) {
}
function emitReturnStatement(node: ReturnStatement) {
writeToken(SyntaxKind.ReturnKeyword, node.pos, node, shouldSkipSourceMapForToken);
writeToken(SyntaxKind.ReturnKeyword, node.pos, /*contextNode*/ node);
emitExpressionWithPrefix(" ", node.expression);
write(";");
}
@@ -1992,7 +1992,7 @@ const _super = (function (geti, seti) {
// "comment1" is not considered to be leading comment for node.initializer
// but rather a trailing comment on the previous node.
if (!shouldSkipLeadingCommentsForNode(node.initializer)) {
emitLeadingComments(node.initializer, getTrailingComments(collapseRangeToStart(node.initializer)));
emitLeadingComments(node.initializer, getTrailingComments(collapseRangeToStart(node.initializer)), getCommentRange);
}
emitExpression(node.initializer);
}
@@ -2356,7 +2356,7 @@ const _super = (function (geti, seti) {
}
if (shouldEmitInterveningComments) {
emitLeadingComments(child, getTrailingCommentsOfPosition(child.pos));
emitLeadingComments(child, getTrailingCommentsOfPosition(child.pos), getCommentRange);
}
else {
shouldEmitInterveningComments = true;
@@ -2410,18 +2410,20 @@ const _super = (function (geti, seti) {
}
}
function writeToken(token: SyntaxKind, tokenStartPos: number): number;
function writeToken(token: SyntaxKind, tokenStartPos: number, contextNode: Node, shouldIgnoreSourceMapForTokenCallback: (contextNode: Node) => boolean): number;
function writeToken(token: SyntaxKind, tokenStartPos: number, contextNode?: Node, shouldIgnoreSourceMapForTokenCallback?: (contextNode: Node) => boolean) {
function writeToken(token: SyntaxKind, tokenStartPos: number, contextNode?: Node) {
tokenStartPos = skipTrivia(currentText, tokenStartPos);
emitPos(tokenStartPos, contextNode, shouldIgnoreSourceMapForTokenCallback);
emitPos(tokenStartPos, contextNode, shouldSkipLeadingSourceMapForToken);
const tokenEndPos = writeTokenText(token, tokenStartPos);
emitPos(tokenEndPos, contextNode, shouldIgnoreSourceMapForTokenCallback);
emitPos(tokenEndPos, contextNode, shouldSkipTrailingSourceMapForToken);
return tokenEndPos;
}
function shouldSkipSourceMapForToken(contextNode: Node) {
return (getNodeEmitFlags(contextNode) & NodeEmitFlags.NoTokenSourceMaps) !== 0;
function shouldSkipLeadingSourceMapForToken(contextNode: Node) {
return (getNodeEmitFlags(contextNode) & NodeEmitFlags.NoTokenLeadingSourceMaps) !== 0;
}
function shouldSkipTrailingSourceMapForToken(contextNode: Node) {
return (getNodeEmitFlags(contextNode) & NodeEmitFlags.NoTokenTrailingSourceMaps) !== 0;
}
function writeTokenText(token: SyntaxKind, pos?: number) {
+45 -41
View File
@@ -168,22 +168,12 @@ namespace ts {
emit(node);
}
function getNodeEmitOptions(node: Node, createIfMissing: boolean) {
// Keeps track of the nearest set of options
let options: NodeEmitOptions;
let currentNode = node;
while (currentNode) {
const currentOptions = currentNode.emitOptions || nodeEmitOptions[getNodeId(currentNode)];
if (currentOptions) {
options = currentOptions;
break;
}
currentNode = currentNode.original;
}
if (currentNode !== node && createIfMissing) {
options = options ? clone(options) : { };
function getEmitOptions(node: Node, create?: boolean) {
let options = isSourceTreeNode(node)
? nodeEmitOptions[getNodeId(node)]
: node.emitOptions;
if (!options && create) {
options = { };
if (isSourceTreeNode(node)) {
nodeEmitOptions[getNodeId(node)] = options;
}
@@ -191,22 +181,6 @@ namespace ts {
node.emitOptions = options;
}
}
// Merge with previous options on get.
if (options && options.flags & NodeEmitFlags.Merge) {
const previousOptions = getNodeEmitOptions(currentNode.original, /*createIfMissing*/ false);
if (previousOptions) {
options.flags = (options.flags | previousOptions.flags) & ~NodeEmitFlags.Merge;
if (!options.sourceMapRange && (options.flags & NodeEmitFlags.NoSourceMap) === 0) {
options.sourceMapRange = previousOptions.sourceMapRange;
}
if (!options.commentRange && (options.flags & NodeEmitFlags.NoComments) === 0) {
options.commentRange = previousOptions.commentRange;
}
}
}
return options;
}
@@ -214,15 +188,27 @@ namespace ts {
* Gets flags that control emit behavior of a node.
*/
function getNodeEmitFlags(node: Node) {
const options = getNodeEmitOptions(node, /*createIfMissing*/ false);
return options && options.flags;
while (node) {
const options = getEmitOptions(node, /*create*/ false);
if (options && options.flags !== undefined) {
if (options.flags & NodeEmitFlags.Merge) {
options.flags = (options.flags | getNodeEmitFlags(node.original)) & ~NodeEmitFlags.Merge;
}
return options.flags;
}
node = node.original;
}
return undefined;
}
/**
* Sets flags that control emit behavior of a node.
*/
function setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags) {
getNodeEmitOptions(node, /*createIfMissing*/ true).flags = flags;
getEmitOptions(node, /*create*/ true).flags = flags;
return node;
}
@@ -230,15 +216,24 @@ namespace ts {
* Gets a custom text range to use when emitting source maps.
*/
function getSourceMapRange(node: Node) {
const options = getNodeEmitOptions(node, /*createIfMissing*/ false);
return options && options.sourceMapRange;
let current = node;
while (current) {
const options = getEmitOptions(current);
if (options && options.sourceMapRange !== undefined) {
return options.sourceMapRange;
}
current = current.original;
}
return node;
}
/**
* Sets a custom text range to use when emitting source maps.
*/
function setSourceMapRange<T extends Node>(node: T, range: TextRange) {
getNodeEmitOptions(node, /*createIfMissing*/ true).sourceMapRange = range;
getEmitOptions(node, /*create*/ true).sourceMapRange = range;
return node;
}
@@ -246,15 +241,24 @@ namespace ts {
* Gets a custom text range to use when emitting comments.
*/
function getCommentRange(node: Node) {
const options = getNodeEmitOptions(node, /*createIfMissing*/ false);
return options && options.commentRange;
let current = node;
while (current) {
const options = getEmitOptions(current, /*create*/ false);
if (options && options.commentRange !== undefined) {
return options.commentRange;
}
current = current.original;
}
return node;
}
/**
* Sets a custom text range to use when emitting comments.
*/
function setCommentRange<T extends Node>(node: T, range: TextRange) {
getNodeEmitOptions(node, /*createIfMissing*/ true).commentRange = range;
getEmitOptions(node, /*create*/ true).commentRange = range;
return node;
}
+20 -20
View File
@@ -63,9 +63,10 @@ namespace ts {
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
const expression = createAssignment(name, value, location);
if (isSimpleExpression(value)) {
context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps);
}
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps);
aggregateTransformFlags(expression);
expressions.push(expression);
@@ -98,9 +99,10 @@ namespace ts {
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
const declaration = createVariableDeclaration(name, value, location);
if (isSimpleExpression(value)) {
context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps);
}
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps);
aggregateTransformFlags(declaration);
declarations.push(declaration);
@@ -132,16 +134,14 @@ namespace ts {
return declarations;
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
debugger;
const declaration = createVariableDeclaration(name, value, location);
if (declarations.length === 0) {
declaration.pos = -1;
}
if (isSimpleExpression(value)) {
context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps);
}
declaration.original = original;
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(declaration, NodeEmitFlags.NoNestedSourceMaps);
declarations.push(declaration);
aggregateTransformFlags(declaration);
}
@@ -189,11 +189,12 @@ namespace ts {
function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) {
const expression = createAssignment(name, value, location);
if (isSimpleExpression(value)) {
context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps);
}
expression.original = original;
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
context.setNodeEmitFlags(expression, NodeEmitFlags.NoNestedSourceMaps);
pendingAssignments.push(expression);
return expression;
}
@@ -341,8 +342,7 @@ namespace ts {
}
}
else {
const clonedName = getSynthesizedClone(name);
emitAssignment(clonedName, value, target, target);
emitAssignment(name, value, target, target);
}
}
+147 -79
View File
@@ -145,8 +145,10 @@ namespace ts {
hoistVariableDeclaration,
getNodeEmitFlags,
setNodeEmitFlags,
getCommentRange,
setCommentRange,
setSourceMapRange
getSourceMapRange,
setSourceMapRange,
} = context;
const resolver = context.getEmitResolver();
@@ -311,7 +313,7 @@ namespace ts {
return visitFunctionExpression(<FunctionExpression>node);
case SyntaxKind.VariableDeclaration:
return visitVariableDeclaration(<VariableDeclaration>node);
return visitVariableDeclaration(<VariableDeclaration>node, /*offset*/ undefined);
case SyntaxKind.Identifier:
return visitIdentifier(<Identifier>node);
@@ -387,7 +389,7 @@ namespace ts {
return visitSourceFileNode(<SourceFile>node);
case SyntaxKind.VariableStatement:
return visitEachChild(node, visitor, context);
return visitVariableStatement(<VariableStatement>node);
default:
Debug.failBadSyntaxKind(node);
@@ -836,18 +838,24 @@ namespace ts {
else if (isBindingPattern(node.name)) {
// Binding patterns are converted into a generated name and are
// evaluated inside the function body.
return createParameter(
getGeneratedNameForNode(node),
/*initializer*/ undefined,
/*location*/ node
return setOriginalNode(
createParameter(
getGeneratedNameForNode(node),
/*initializer*/ undefined,
/*location*/ node
),
/*original*/ node
);
}
else if (node.initializer) {
// Initializers are elided
return createParameter(
node.name,
/*initializer*/ undefined,
/*location*/ node
return setOriginalNode(
createParameter(
node.name,
/*initializer*/ undefined,
/*location*/ node
),
/*original*/ node
);
}
else {
@@ -1127,6 +1135,13 @@ namespace ts {
* @param member The MethodDeclaration node.
*/
function transformClassMethodDeclarationToStatement(receiver: LeftHandSideExpression, member: MethodDeclaration) {
const commentRange = getCommentRange(member);
const sourceMapRange = getSourceMapRange(member);
const func = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined);
setNodeEmitFlags(func, NodeEmitFlags.NoComments);
setSourceMapRange(func, sourceMapRange);
const statement = createStatement(
createAssignment(
createMemberAccessForPropertyName(
@@ -1134,13 +1149,13 @@ namespace ts {
visitNode(member.name, visitor, isPropertyName),
/*location*/ member.name
),
transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined),
/*location*/ moveRangeEnd(member, -1)
func
),
/*location*/ member
);
setOriginalNode(statement, member);
setCommentRange(statement, commentRange);
// The location for the statement is used to emit comments only.
// No source map should be emitted for this statement to align with the
@@ -1158,7 +1173,7 @@ namespace ts {
function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations): Statement {
const statement = createStatement(
transformAccessorsToExpression(receiver, accessors),
/*location*/ accessors.firstAccessor
/*location*/ getSourceMapRange(accessors.firstAccessor)
);
// The location for the statement is used to emit source maps only.
@@ -1177,40 +1192,43 @@ namespace ts {
function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations): Expression {
// To align with source maps in the old emitter, the receiver and property name
// arguments are both mapped contiguously to the accessor name.
const target = getMutableClone(receiver, { flags: NodeEmitFlags.Merge | NodeEmitFlags.NoComments, sourceMapRange: moveRangeEnd(firstAccessor.name, -1) });
const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName), { flags: NodeEmitFlags.NoComments, sourceMapRange: moveRangePos(firstAccessor.name, -1) });
const target = getMutableClone(receiver);
setNodeEmitFlags(target, NodeEmitFlags.NoComments | NodeEmitFlags.NoTrailingSourceMap);
setSourceMapRange(target, firstAccessor.name);
let getAccessorExpression: FunctionExpression;
const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName));
setNodeEmitFlags(propertyName, NodeEmitFlags.NoComments | NodeEmitFlags.NoLeadingSourceMap);
setSourceMapRange(propertyName, firstAccessor.name);
const properties: ObjectLiteralElement[] = [];
if (getAccessor) {
getAccessorExpression = transformFunctionLikeToExpression(getAccessor, /*location*/ getAccessor, /*name*/ undefined);
setNodeEmitFlags(getAccessorExpression, NodeEmitFlags.NoLeadingComments | getNodeEmitFlags(getAccessorExpression));
const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined);
setSourceMapRange(getterFunction, getSourceMapRange(getAccessor));
const getter = createPropertyAssignment("get", getterFunction);
setCommentRange(getter, getCommentRange(getAccessor));
properties.push(getter);
}
let setAccessorExpression: FunctionExpression;
if (setAccessor) {
setAccessorExpression = transformFunctionLikeToExpression(setAccessor, /*location*/ setAccessor, /*name*/ undefined);
setNodeEmitFlags(setAccessorExpression, NodeEmitFlags.NoLeadingComments | getNodeEmitFlags(setAccessorExpression));
const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined);
setSourceMapRange(setterFunction, getSourceMapRange(setAccessor));
const setter = createPropertyAssignment("set", setterFunction);
setCommentRange(setter, getCommentRange(setAccessor));
properties.push(setter);
}
return setNodeEmitFlags(
createObjectDefineProperty(
properties.push(
createPropertyAssignment("enumerable", createLiteral(true)),
createPropertyAssignment("configurable", createLiteral(true))
);
return createCall(
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
[
target,
propertyName,
/*descriptor*/ {
get: getAccessorExpression,
set: setAccessorExpression,
enumerable: true,
configurable: true
},
/*preferNewLine*/ true,
/*location*/ undefined,
/*descriptorLocations*/ {
get: { location: getAccessor, emitFlags: NodeEmitFlags.NoSourceMap, original: getAccessor },
set: { location: setAccessor, emitFlags: NodeEmitFlags.NoSourceMap, original: getAccessor }
},
context
),
NodeEmitFlags.NoComments
createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)
]
);
}
@@ -1459,7 +1477,16 @@ namespace ts {
return undefined;
}
}
return visitEachChild(node, visitor, context);
const visited = visitEachChild(node, visitor, context);
// if (node.declarationList.transformFlags & TransformFlags.ContainsBindingPattern) {
// // To align with source maps from the old emitter, we do not emit the start pos
// // for the statement if it contains a binding pattern.
// setNodeEmitFlags(visited, NodeEmitFlags.NoLeadingSourceMap);
// }
return visited;
}
/**
@@ -1468,17 +1495,36 @@ namespace ts {
* @param node A VariableDeclarationList node.
*/
function visitVariableDeclarationList(node: VariableDeclarationList): VariableDeclarationList {
// If we are here it is because the list is defined as `let` or `const`.
Debug.assert((node.flags & NodeFlags.BlockScoped) !== 0);
if (node.flags & NodeFlags.BlockScoped) {
enableSubstitutionsForBlockScopedBindings();
}
enableSubstitutionsForBlockScopedBindings();
return setOriginalNode(
createVariableDeclarationList(
flatten(map(node.declarations, visitVariableDeclarationInLetDeclarationList)),
/*location*/ node
),
node
);
const declarations = flatten(map(node.declarations, node.flags & NodeFlags.Let
? visitVariableDeclarationInLetDeclarationList
: visitVariableDeclaration));
const declarationList = createVariableDeclarationList(declarations, /*location*/ node);
setOriginalNode(declarationList, node);
// if (node.transformFlags & TransformFlags.ContainsBindingPattern) {
// const firstOriginalDeclaration = node.declarations[0];
// if (isBindingPattern(firstOriginalDeclaration.name)) {
// // // If the first var declaration is a binding pattern, we need to emit source maps
// // // at var/let/const keyword instead
// // const firstDeclaration = declarations[0];
// // const range = getSourceMapRange(firstDeclaration);
// // if (firstOriginalDeclaration.initializer && isIdentifier(firstOriginalDeclaration.initializer)) {
// // // setSourceMapRange(declarationList, createRange(-1, node.end));
// // // setSourceMapRange(declarationList, createRange(range.pos, node.end));
// // // setSourceMapRange(firstDeclaration, createRange(-1, range.end));
// // }
// // else {
// // setSourceMapRange(firstDeclaration, createRange(node.pos, range.end));
// // }
// }
// }
return declarationList;
}
/**
@@ -1555,13 +1601,13 @@ namespace ts {
*
* @param node A VariableDeclaration node.
*/
function visitVariableDeclarationInLetDeclarationList(node: VariableDeclaration) {
function visitVariableDeclarationInLetDeclarationList(node: VariableDeclaration, offset: number) {
// For binding pattern names that lack initializers there is no point to emit
// explicit initializer since downlevel codegen for destructuring will fail
// in the absence of initializer so all binding elements will say uninitialized
const name = node.name;
if (isBindingPattern(name)) {
return visitVariableDeclaration(node);
return visitVariableDeclaration(node, offset);
}
if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
@@ -1578,11 +1624,13 @@ namespace ts {
*
* @param node A VariableDeclaration node.
*/
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
function visitVariableDeclaration(node: VariableDeclaration, offset: number): VisitResult<VariableDeclaration> {
// If we are here it is because the name contains a binding pattern.
Debug.assert(isBindingPattern(node.name));
if (isBindingPattern(node.name)) {
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor);
}
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor);
return visitEachChild(node, visitor, context);
}
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
@@ -1672,25 +1720,33 @@ namespace ts {
// Initialize LHS
// var v = _a[_i];
if (isVariableDeclarationList(initializer)) {
const firstDeclaration = firstOrUndefined(initializer.declarations);
const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
if (initializer.flags & NodeFlags.BlockScoped) {
enableSubstitutionsForBlockScopedBindings();
}
if (firstDeclaration && isBindingPattern(firstDeclaration.name)) {
if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
// This works whether the declaration is a var, let, or const.
// It will use rhsIterationValue _a[_i] as the initializer.
const declarationList = createVariableDeclarationList(
flattenVariableDestructuring(
context,
firstOriginalDeclaration,
createElementAccess(rhsReference, counter),
visitor
),
/*location*/ moveRangeEnd(initializer, -1)
);
// Adjust the source map range for the first declaration to align with the old
// emitter.
const firstDeclaration = declarationList.declarations[0];
const range = getSourceMapRange(firstDeclaration);
setSourceMapRange(firstDeclaration, createRange(-1, range.end));
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(
flattenVariableDestructuring(
context,
firstDeclaration,
createElementAccess(rhsReference, counter),
visitor
)
),
/*location*/ moveRangeEnd(initializer, -1)
declarationList
)
);
}
@@ -1702,7 +1758,7 @@ namespace ts {
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
firstDeclaration ? firstDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
createElementAccess(rhsReference, counter)
)
], /*location*/ moveRangePos(initializer, -1)),
@@ -1735,13 +1791,17 @@ namespace ts {
}
}
let bodyLocation: TextRange;
let statementsLocation: TextRange;
if (convertedLoopBodyStatements) {
addRange(statements, convertedLoopBodyStatements);
}
else {
const statement = visitNode(node.statement, visitor, isStatement);
if (isBlock(statement)) {
addRange(statements, (<Block>statement).statements);
addRange(statements, statement.statements);
bodyLocation = statement;
statementsLocation = statement.statements;
}
else {
statements.push(statement);
@@ -1751,25 +1811,33 @@ namespace ts {
// The old emitter does not emit source maps for the expression
setNodeEmitFlags(expression, NodeEmitFlags.NoSourceMap | getNodeEmitFlags(expression));
return createFor(
createVariableDeclarationList(
[
createVariableDeclaration(counter, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, expression, /*location*/ node.expression)
],
/*location*/ node.expression
),
// The old emitter does not emit source maps for the block.
// We add the location to preserve comments.
const body = createBlock(
createNodeArray(statements, /*location*/ statementsLocation),
/*location*/ bodyLocation
);
setNodeEmitFlags(body, NodeEmitFlags.NoSourceMap | NodeEmitFlags.NoTokenSourceMaps);
const forStatement = createFor(
createVariableDeclarationList([
createVariableDeclaration(counter, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
createVariableDeclaration(rhsReference, expression, /*location*/ node.expression)
], /*location*/ node.expression),
createLessThan(
counter,
createPropertyAccess(rhsReference, "length"),
/*location*/ node.expression
),
createPostfixIncrement(counter, /*location*/ node.expression),
createBlock(
statements
),
body,
/*location*/ node
);
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
setNodeEmitFlags(forStatement, NodeEmitFlags.NoTokenTrailingSourceMaps);
return forStatement;
}
/**
+19 -11
View File
@@ -507,10 +507,15 @@ namespace ts {
else {
statements.push(
createStatement(
createObjectDefineProperty(
createIdentifier("exports"),
createLiteral("__esModule"),
{ value: createLiteral(true) }
createCall(
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
[
createIdentifier("exports"),
createLiteral("__esModule"),
createObjectLiteral([
createPropertyAssignment("value", createLiteral(true))
])
]
)
)
);
@@ -651,13 +656,16 @@ namespace ts {
const name = node.name || getGeneratedNameForNode(node);
if (hasModifier(node, ModifierFlags.Export)) {
statements.push(
createFunctionDeclaration(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
name,
node.parameters,
node.body,
/*location*/ node
setOriginalNode(
createFunctionDeclaration(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
name,
node.parameters,
node.body,
/*location*/ node
),
/*original*/ node
)
);
+6 -1
View File
@@ -11,11 +11,15 @@ namespace ts {
const {
getNodeEmitFlags,
setNodeEmitFlags,
getCommentRange,
setCommentRange,
getSourceMapRange,
setSourceMapRange,
startLexicalEnvironment,
endLexicalEnvironment,
hoistVariableDeclaration,
hoistFunctionDeclaration,
setNodeEmitFlags
} = context;
const compilerOptions = context.getCompilerOptions();
@@ -661,6 +665,7 @@ namespace ts {
recordExportName(name);
}
setOriginalNode(newNode, node);
node = newNode;
}
+66 -67
View File
@@ -225,7 +225,7 @@ namespace ts {
* @param node The node to visit.
*/
function visitTypeScript(node: Node): VisitResult<Node> {
if (hasModifier(node, ModifierFlags.Ambient)) {
if (hasModifier(node, ModifierFlags.Ambient) && isStatement(node)) {
// TypeScript ambient declarations are elided, but some comments may be preserved.
// See the implementation of `getLeadingComments` in comments.ts for more details.
return isStatement(node)
@@ -598,7 +598,7 @@ namespace ts {
// ---------------------------------------------------------------------
//
const location = getUndecoratedRange(node);
const location = moveRangePastDecorators(node);
// ... = class ${name} ${heritageClauses} {
// ${members}
@@ -914,8 +914,12 @@ namespace ts {
function transformParameterWithPropertyAssignment(node: ParameterDeclaration) {
Debug.assert(isIdentifier(node.name));
const name = node.name as Identifier;
const propertyName = getMutableClone(name, { flags: NodeEmitFlags.NoComments | NodeEmitFlags.NoSourceMap });
const localName = getMutableClone(name, { flags: NodeEmitFlags.NoComments });
const propertyName = getMutableClone(name);
setNodeEmitFlags(propertyName, NodeEmitFlags.NoComments | NodeEmitFlags.NoSourceMap);
const localName = getMutableClone(name);
setNodeEmitFlags(localName, NodeEmitFlags.NoComments);
return startOnNewLine(
createStatement(
createAssignment(
@@ -926,7 +930,7 @@ namespace ts {
),
localName
),
/*location*/ node
/*location*/ moveRangePos(node, -1)
)
);
}
@@ -980,12 +984,10 @@ namespace ts {
*/
function addInitializedPropertyStatements(statements: Statement[], node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
for (const property of properties) {
statements.push(
createStatement(
transformInitializedProperty(node, property, receiver),
/*location*/ property
)
);
const statement = createStatement(transformInitializedProperty(node, property, receiver));
setSourceMapRange(statement, moveRangePastModifiers(property));
setCommentRange(statement, property);
statements.push(statement);
}
}
@@ -999,7 +1001,10 @@ namespace ts {
function generateInitializedPropertyExpressions(node: ClassExpression | ClassDeclaration, properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
const expressions: Expression[] = [];
for (const property of properties) {
expressions.push(transformInitializedProperty(node, property, receiver, /*location*/ property));
const expression = transformInitializedProperty(node, property, receiver);
setSourceMapRange(expression, moveRangePastModifiers(property));
setCommentRange(expression, property);
expressions.push(expression);
}
return expressions;
@@ -1012,7 +1017,7 @@ namespace ts {
* @param property The property declaration.
* @param receiver The object receiving the property assignment.
*/
function transformInitializedProperty(node: ClassExpression | ClassDeclaration, property: PropertyDeclaration, receiver: LeftHandSideExpression, location?: TextRange) {
function transformInitializedProperty(node: ClassExpression | ClassDeclaration, property: PropertyDeclaration, receiver: LeftHandSideExpression) {
const propertyName = visitPropertyNameOfClassElement(property);
const initializer = visitNode(property.initializer, visitor, isExpression);
const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
@@ -1020,11 +1025,7 @@ namespace ts {
setNodeEmitFlags(memberAccess, NodeEmitFlags.NoNestedSourceMaps);
}
return createAssignment(
memberAccess,
initializer,
location
);
return createAssignment(memberAccess, initializer);
}
/**
@@ -1321,7 +1322,7 @@ namespace ts {
prefix,
memberName,
descriptor,
getUndecoratedRange(member)
moveRangePastDecorators(member)
);
setNodeEmitFlags(helper, NodeEmitFlags.NoComments);
@@ -1371,7 +1372,7 @@ namespace ts {
)
);
const result = createAssignment(getDeclarationName(node), expression, getUndecoratedRange(node));
const result = createAssignment(getDeclarationName(node), expression, moveRangePastDecorators(node));
setNodeEmitFlags(result, NodeEmitFlags.NoComments);
return result;
}
@@ -1392,7 +1393,7 @@ namespace ts {
decoratorExpressions,
getDeclarationName(node)
),
getUndecoratedRange(node)
moveRangePastDecorators(node)
);
setNodeEmitFlags(result, NodeEmitFlags.NoComments);
@@ -1903,8 +1904,7 @@ namespace ts {
*
* This function will be called when one of the following conditions are met:
* - The node is an overload
* - The node is marked as abstract
* - The node is marked as async
* - The node is marked as abstract, async, public, private, protected, or readonly
* - The node has both a decorator and a computed property name
*
* @param node The method node.
@@ -1916,20 +1916,18 @@ namespace ts {
const method = createMethod(
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
visitPropertyNameOfClassElement(node),
visitNodes(node.parameters, visitor, isParameter),
transformFunctionBody(node),
/*location*/ getUndecoratedRange(node)
/*location*/ node
);
setOriginalNode(method, node);
// While we emit the source map for the node after skipping the decorators,
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
if (node.decorators) {
setCommentRange(method, node);
setSourceMapRange(method, getUndecoratedRange(node));
}
setCommentRange(method, node);
setSourceMapRange(method, moveRangePastDecorators(node));
setOriginalNode(method, node);
return method;
}
@@ -1948,7 +1946,7 @@ namespace ts {
* Visits a get accessor declaration of a class.
*
* This function will be called when one of the following conditions are met:
* - The node is marked as abstract
* - The node is marked as abstract, public, private, or protected
* - The node has both a decorator and a computed property name
*
* @param node The get accessor node.
@@ -1961,18 +1959,16 @@ namespace ts {
const accessor = createGetAccessor(
visitNodes(node.modifiers, visitor, isModifier),
visitPropertyNameOfClassElement(node),
visitNodes(node.parameters, visitor, isParameter),
node.body ? visitEachChild(node.body, visitor, context) : createBlock([]),
/*location*/ getUndecoratedRange(node)
/*location*/ node
);
setOriginalNode(accessor, node);
// While we emit the source map for the node after skipping the decorators,
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
if (node.decorators) {
setCommentRange(accessor, node);
setSourceMapRange(accessor, getUndecoratedRange(node));
}
setCommentRange(accessor, node);
setSourceMapRange(accessor, moveRangePastDecorators(node));
setOriginalNode(accessor, node);
return accessor;
}
@@ -1981,7 +1977,7 @@ namespace ts {
* Visits a set accessor declaration of a class.
*
* This function will be called when one of the following conditions are met:
* - The node is marked as abstract
* - The node is marked as abstract, public, private, or protected
* - The node has both a decorator and a computed property name
*
* @param node The set accessor node.
@@ -1994,19 +1990,16 @@ namespace ts {
const accessor = createSetAccessor(
visitNodes(node.modifiers, visitor, isModifier),
visitPropertyNameOfClassElement(node),
visitNode(firstOrUndefined(node.parameters), visitor, isParameter),
visitNodes(node.parameters, visitor, isParameter),
node.body ? visitEachChild(node.body, visitor, context) : createBlock([]),
/*location*/ getUndecoratedRange(node)
/*location*/ node
);
setOriginalNode(accessor, node);
// While we emit the source map for the node after skipping the decorators,
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
if (node.decorators) {
setCommentRange(accessor, node);
setSourceMapRange(accessor, getUndecoratedRange(node));
}
setCommentRange(accessor, node);
setSourceMapRange(accessor, moveRangePastDecorators(node));
setOriginalNode(accessor, node);
return accessor;
}
@@ -2032,8 +2025,9 @@ namespace ts {
node.name,
visitNodes(node.parameters, visitor, isParameter),
transformFunctionBody(node),
node
/*location*/ node
);
setOriginalNode(func, node);
if (isNamespaceExport(node)) {
const statements: Statement[] = [func];
@@ -2054,17 +2048,20 @@ namespace ts {
*/
function visitFunctionExpression(node: FunctionExpression) {
if (nodeIsMissing(node.body)) {
return createNode(SyntaxKind.OmittedExpression);
// return createOmittedExpression(/*location*/ node);
return createOmittedExpression();
}
return createFunctionExpression(
const func = createFunctionExpression(
node.asteriskToken,
node.name,
visitNodes(node.parameters, visitor, isParameter),
transformFunctionBody(node),
node
/*location*/ node
);
setOriginalNode(func, node);
return func;
}
/**
@@ -2073,11 +2070,15 @@ namespace ts {
* - The node is marked async
*/
function visitArrowFunction(node: ArrowFunction) {
return createArrowFunction(
const func = createArrowFunction(
visitNodes(node.parameters, visitor, isParameter),
transformConciseBody(node),
node
/*location*/ node
);
setOriginalNode(func, node);
return func;
}
function transformFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
@@ -2196,17 +2197,15 @@ namespace ts {
node.dotDotDotToken,
visitNode(node.name, visitor, isBindingName),
visitNode(node.initializer, visitor, isExpression),
/*location*/ getUndecoratedRange(node)
/*location*/ moveRangePastModifiers(node)
);
setOriginalNode(parameter, node);
// While we emit the source map for the node after skipping the decorators,
// While we emit the source map for the node after skipping decorators and modifiers,
// we need to emit the comments for the original range.
if (node.decorators) {
setCommentRange(parameter, node);
setSourceMapRange(parameter, getUndecoratedRange(node));
}
setCommentRange(parameter, node);
setSourceMapRange(parameter, moveRangePastModifiers(node));
setNodeEmitFlags(parameter.name, NodeEmitFlags.NoTrailingSourceMap);
setOriginalNode(parameter, node);
return parameter;
}
@@ -2777,9 +2776,9 @@ namespace ts {
createAssignment(
getExportName(node),
getLocalName(node, /*noSourceMaps*/ true),
/*location*/ node
/*location*/ createRange(node.name.pos, node.end)
),
/*location*/ moveRangePos(node, -1)
/*location*/ createRange(-1, node.end)
)
);
}
+14 -9
View File
@@ -2894,6 +2894,7 @@ namespace ts {
ContainsSpreadElementExpression = 1 << 16,
ContainsComputedPropertyName = 1 << 17,
ContainsBlockScopedBinding = 1 << 18,
ContainsBindingPattern = 1 << 19,
HasComputedFlags = 1 << 31, // Transform flags have been computed.
@@ -2917,6 +2918,8 @@ namespace ts {
TypeExcludes = ~ContainsTypeScript,
ObjectLiteralExcludes = ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
ArrayLiteralOrCallOrNewExcludes = ContainsSpreadElementExpression,
VariableDeclarationListExcludes = ContainsBindingPattern,
ParameterExcludes = ContainsBindingPattern,
}
/* @internal */
@@ -2935,21 +2938,23 @@ namespace ts {
NoTrailingSourceMap = 1 << 11, // Do not emit a trailing source map location for this node.
NoSourceMap = NoLeadingSourceMap | NoTrailingSourceMap, // Do not emit a source map location for this node.
NoNestedSourceMaps = 1 << 12, // Do not emit source map locations for children of this node.
NoTokenSourceMaps = 1 << 13, // Do not emit source map locations for tokens of this node.
NoLeadingComments = 1 << 14, // Do not emit leading comments for this node.
NoTrailingComments = 1 << 15, // Do not emit trailing comments for this node.
NoTokenLeadingSourceMaps = 1 << 13, // Do not emit leading source map location for token nodes.
NoTokenTrailingSourceMaps = 1 << 14, // Do not emit trailing source map location for token nodes.
NoTokenSourceMaps = NoTokenLeadingSourceMaps | NoTokenTrailingSourceMaps, // Do not emit source map locations for tokens of this node.
NoLeadingComments = 1 << 15, // Do not emit leading comments for this node.
NoTrailingComments = 1 << 16, // Do not emit trailing comments for this node.
NoComments = NoLeadingComments | NoTrailingComments, // Do not emit comments for this node.
ExportName = 1 << 16, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
LocalName = 1 << 17, // Ensure an export prefix is not added for an identifier that points to an exported declaration.
Indented = 1 << 18, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
Merge = 1 << 19, // When getting emit options, merge with existing emit options.
ExportName = 1 << 17, // Ensure an export prefix is added for an identifier that points to an exported declaration with a local name (see SymbolFlags.ExportHasLocal).
LocalName = 1 << 18, // Ensure an export prefix is not added for an identifier that points to an exported declaration.
Indented = 1 << 19, // Adds an explicit extra indentation level for class and function bodies when printing (used to match old emitter).
Merge = 1 << 20, // When getting emit options, merge with existing emit options.
// SourceMap Specialization.
// TODO(rbuckton): These should be removed once source maps are aligned with the old
// emitter and new baselines are taken. This exists solely to
// align with the old emitter.
SourceMapEmitOpenBraceAsToken = 1 << 20, // Emits the open brace of a block function body as a source mapped token.
SourceMapAdjustRestParameterLoop = 1 << 21, // Emits adjusted source map positions for a ForStatement generated when transforming a rest parameter for ES5/3.
SourceMapEmitOpenBraceAsToken = 1 << 21, // Emits the open brace of a block function body as a source mapped token.
SourceMapAdjustRestParameterLoop = 1 << 22, // Emits adjusted source map positions for a ForStatement generated when transforming a rest parameter for ES5/3.
}
/* @internal */
+36 -4
View File
@@ -3026,6 +3026,19 @@ namespace ts {
else if (kind === SyntaxKind.ObjectLiteralExpression) {
return (<ObjectLiteralExpression>node).properties.length === 0;
}
else if (kind === SyntaxKind.CallExpression) {
if (!isSimpleExpressionWorker((<CallExpression>node).expression, depth + 1)) {
return false;
}
for (const argument of (<CallExpression>node).arguments) {
if (!isSimpleExpressionWorker(argument, depth + 1)) {
return false;
}
}
return true;
}
}
return false;
@@ -3045,6 +3058,16 @@ namespace ts {
}
}
/**
* Creates a new TextRange from the provided pos and end.
*
* @param pos The start position.
* @param end The end position.
*/
export function createRange(pos: number, end: number): TextRange {
return { pos, end };
}
/**
* Creates a new TextRange from a provided range with a new end position.
*
@@ -3052,7 +3075,7 @@ namespace ts {
* @param end The new end position.
*/
export function moveRangeEnd(range: TextRange, end: number): TextRange {
return { pos: range.pos, end };
return createRange(range.pos, end);
}
/**
@@ -3062,18 +3085,27 @@ namespace ts {
* @param pos The new Start position.
*/
export function moveRangePos(range: TextRange, pos: number): TextRange {
return { pos, end: range.end };
return createRange(pos, range.end);
}
/**
* Moves the start position of a range past any decorators.
*/
export function getUndecoratedRange(node: Node): TextRange {
export function moveRangePastDecorators(node: Node): TextRange {
return node.decorators && node.decorators.length > 0
? moveRangePos(node, node.decorators.end)
: node;
}
/**
* Moves the start position of a range past any decorators or modifiers.
*/
export function moveRangePastModifiers(node: Node): TextRange {
return node.modifiers && node.modifiers.length > 0
? moveRangePos(node, node.modifiers.end)
: moveRangePastDecorators(node);
}
/**
* Determines whether a TextRange has the same start and end positions.
*
@@ -3110,7 +3142,7 @@ namespace ts {
* @param token The token.
*/
export function createTokenRange(pos: number, token: SyntaxKind): TextRange {
return { pos, end: pos + tokenToString(token).length };
return createRange(pos, pos + tokenToString(token).length);
}
export function rangeIsOnSingleLine(range: TextRange, sourceFile: SourceFile) {
@@ -2,4 +2,4 @@
var v = { *<T>() { } }
//// [FunctionPropertyAssignments6_es6.js]
var v = { : function () { } };
var v = { : function* () { } };
@@ -7,6 +7,6 @@ class C {
var C = (function () {
function C() {
}
C.prototype.foo = function () { };
C.prototype.foo = function* () { };
return C;
}());