mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Addesses a number of comment/sourcemap related issues
This commit is contained in:
@@ -13,7 +13,10 @@ namespace ts {
|
||||
getTrailingCommentsOfPosition(pos: number): CommentRange[];
|
||||
emitLeadingComments(range: TextRange, comments: CommentRange[]): void;
|
||||
emitTrailingComments(range: TextRange, comments: CommentRange[]): void;
|
||||
emitDetachedComments(range: TextRange): void;
|
||||
emitLeadingDetachedComments(range: TextRange): void;
|
||||
emitLeadingDetachedComments(range: TextRange, contextNode: Node, shouldSkipCommentsForNodeCallback: (node: Node) => boolean): void;
|
||||
emitTrailingDetachedComments(range: TextRange): void;
|
||||
emitTrailingDetachedComments(range: TextRange, contextNode: Node, shouldSkipCommentsForNodeCallback: (node: Node) => boolean): void;
|
||||
}
|
||||
|
||||
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
|
||||
@@ -46,10 +49,15 @@ namespace ts {
|
||||
getTrailingCommentsOfPosition(pos: number): CommentRange[] { return undefined; },
|
||||
emitLeadingComments(range: TextRange, comments: CommentRange[]): void { },
|
||||
emitTrailingComments(range: TextRange, comments: CommentRange[]): void { },
|
||||
emitDetachedComments,
|
||||
emitLeadingDetachedComments,
|
||||
emitTrailingDetachedComments(node: TextRange, contextNode?: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): void {}
|
||||
};
|
||||
|
||||
function emitDetachedComments(node: TextRange): void {
|
||||
function emitLeadingDetachedComments(node: TextRange, contextNode?: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): void {
|
||||
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(contextNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(node, /*removeComments*/ true);
|
||||
}
|
||||
}
|
||||
@@ -65,7 +73,8 @@ namespace ts {
|
||||
getTrailingCommentsOfPosition,
|
||||
emitLeadingComments,
|
||||
emitTrailingComments,
|
||||
emitDetachedComments,
|
||||
emitLeadingDetachedComments,
|
||||
emitTrailingDetachedComments
|
||||
};
|
||||
|
||||
function getLeadingComments(range: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): CommentRange[];
|
||||
@@ -154,10 +163,23 @@ namespace ts {
|
||||
emitComments(currentText, currentLineMap, writer, comments, /*leadingSeparator*/ true, /*trailingSeparator*/ false, newLine, writeComment);
|
||||
}
|
||||
|
||||
function emitDetachedComments(range: TextRange) {
|
||||
function emitLeadingDetachedComments(range: TextRange, contextNode?: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): void {
|
||||
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(contextNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
emitDetachedCommentsAndUpdateCommentsInfo(range, /*removeComments*/ false);
|
||||
}
|
||||
|
||||
function emitTrailingDetachedComments(range: TextRange, contextNode?: Node, shouldSkipCommentsForNodeCallback?: (node: Node) => boolean): void {
|
||||
if (shouldSkipCommentsForNodeCallback && shouldSkipCommentsForNodeCallback(contextNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
range = collapseRangeToEnd(range);
|
||||
emitLeadingComments(range, getLeadingComments(range));
|
||||
}
|
||||
|
||||
function hasConsumedCommentRange(comment: CommentRange) {
|
||||
return comment.end === consumedCommentRanges[comment.pos];
|
||||
}
|
||||
|
||||
@@ -651,13 +651,14 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Creates a synthetic expression to act as a placeholder for a not-emitted expression in
|
||||
* order to preserve comments.
|
||||
* order to preserve comments or sourcemap positions.
|
||||
*
|
||||
* @param expression The inner expression to emit.
|
||||
* @param original The original outer expression.
|
||||
* @param location The location for the expression. Defaults to the positions from "original" if provided.
|
||||
*/
|
||||
export function createPartiallyEmittedExpression(expression: Expression, original: Node) {
|
||||
const node = <PartiallyEmittedExpression>createNode(SyntaxKind.PartiallyEmittedExpression, /*location*/ original);
|
||||
export function createPartiallyEmittedExpression(expression: Expression, original?: Node, location?: TextRange) {
|
||||
const node = <PartiallyEmittedExpression>createNode(SyntaxKind.PartiallyEmittedExpression, /*location*/ location || original);
|
||||
node.expression = expression;
|
||||
node.original = original;
|
||||
return node;
|
||||
@@ -1257,7 +1258,7 @@ namespace ts {
|
||||
* The function needs to be called during each transformation step.
|
||||
* This function needs to be called whenever we transform the statement
|
||||
* list of a source file, namespace, or function-like body.
|
||||
*
|
||||
*
|
||||
* @param target: result statements array
|
||||
* @param source: origin statements array
|
||||
* @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
|
||||
|
||||
+42
-20
@@ -140,7 +140,8 @@ const _super = (function (geti, seti) {
|
||||
getTrailingCommentsOfPosition,
|
||||
emitLeadingComments,
|
||||
emitTrailingComments,
|
||||
emitDetachedComments
|
||||
emitLeadingDetachedComments,
|
||||
emitTrailingDetachedComments
|
||||
} = comments;
|
||||
|
||||
let context: TransformationContext;
|
||||
@@ -298,24 +299,45 @@ const _super = (function (geti, seti) {
|
||||
const leadingComments = getLeadingComments(node, shouldSkipCommentsForNode);
|
||||
const trailingComments = getTrailingComments(node, shouldSkipCommentsForNode);
|
||||
emitLeadingComments(node, leadingComments);
|
||||
emitStart(node, shouldIgnoreSourceMapForNode, shouldIgnoreSourceMapForChildren);
|
||||
emitStart(node, shouldSkipSourceMapForNode, shouldSkipSourceMapForChildren);
|
||||
emitWorker(node);
|
||||
emitEnd(node, shouldIgnoreSourceMapForNode, shouldIgnoreSourceMapForChildren);
|
||||
emitEnd(node, shouldSkipSourceMapForNode, shouldSkipSourceMapForChildren);
|
||||
emitTrailingComments(node, trailingComments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to skip comment emit for a node.
|
||||
*
|
||||
* We do not emit comments for NotEmittedStatement nodes or any node that has
|
||||
* NodeEmitFlags.NoComments.
|
||||
*
|
||||
* @param node A Node.
|
||||
*/
|
||||
function shouldSkipCommentsForNode(node: Node) {
|
||||
return isNotEmittedStatement(node)
|
||||
|| (getNodeEmitFlags(node) & NodeEmitFlags.NoComments) !== 0;
|
||||
}
|
||||
|
||||
function shouldIgnoreSourceMapForNode(node: Node) {
|
||||
return isNotEmittedOrPartiallyEmittedNode(node)
|
||||
/**
|
||||
* Determines whether to skip source map emit for a node.
|
||||
*
|
||||
* We do not emit source maps for NotEmittedStatement nodes or any node that
|
||||
* has NodeEmitFlags.NoSourceMap.
|
||||
*
|
||||
* @param node A Node.
|
||||
*/
|
||||
function shouldSkipSourceMapForNode(node: Node) {
|
||||
return isNotEmittedStatement(node)
|
||||
|| (getNodeEmitFlags(node) & NodeEmitFlags.NoSourceMap) !== 0;
|
||||
}
|
||||
|
||||
function shouldIgnoreSourceMapForChildren(node: Node) {
|
||||
/**
|
||||
* Determines whether to skip source map emit for a node and its children.
|
||||
*
|
||||
* We do not emit source maps for a node that has NodeEmitFlags.NoNestedSourceMaps.
|
||||
*/
|
||||
function shouldSkipSourceMapForChildren(node: Node) {
|
||||
return (getNodeEmitFlags(node) & NodeEmitFlags.NoNestedSourceMaps) !== 0;
|
||||
}
|
||||
|
||||
@@ -1064,7 +1086,6 @@ const _super = (function (geti, seti) {
|
||||
emitDecorators(node, node.decorators);
|
||||
emitModifiers(node, node.modifiers);
|
||||
emitSignatureAndBody(node, emitArrowFunctionHead);
|
||||
|
||||
}
|
||||
|
||||
function emitArrowFunctionHead(node: ArrowFunction) {
|
||||
@@ -1375,7 +1396,8 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function emitDebuggerStatement(node: DebuggerStatement) {
|
||||
write("debugger;");
|
||||
writeToken(SyntaxKind.DebuggerKeyword, node.pos);
|
||||
write(";");
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1417,9 +1439,7 @@ const _super = (function (geti, seti) {
|
||||
tempFlags = 0;
|
||||
startLexicalEnvironment();
|
||||
emitSignatureHead(node);
|
||||
write(" {");
|
||||
emitBlockFunctionBody(node, body);
|
||||
writeToken(SyntaxKind.CloseBraceToken, node.end)
|
||||
emitBlockFunctionBodyAndEndLexicalEnvironment(node, body);
|
||||
if (indentedFlag) {
|
||||
decreaseIndent();
|
||||
}
|
||||
@@ -1483,10 +1503,12 @@ const _super = (function (geti, seti) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function emitBlockFunctionBody(parentNode: Node, body: Block) {
|
||||
function emitBlockFunctionBodyAndEndLexicalEnvironment(parentNode: Node, body: Block) {
|
||||
write(" {");
|
||||
|
||||
const startingLine = writer.getLine();
|
||||
increaseIndent();
|
||||
emitDetachedComments(body.statements);
|
||||
emitLeadingDetachedComments(body.statements, body, shouldSkipCommentsForNode);
|
||||
|
||||
// Emit all the prologue directives (like "use strict").
|
||||
const statementOffset = emitPrologueDirectives(body.statements, /*startWithNewLine*/ true);
|
||||
@@ -1503,10 +1525,9 @@ const _super = (function (geti, seti) {
|
||||
|
||||
const endingLine = writer.getLine();
|
||||
emitLexicalEnvironment(endLexicalEnvironment(), /*newLine*/ startingLine !== endingLine);
|
||||
|
||||
const range = collapseRangeToEnd(body.statements);
|
||||
emitLeadingComments(range, getLeadingComments(range));
|
||||
emitTrailingDetachedComments(body.statements, body, shouldSkipCommentsForNode);
|
||||
decreaseIndent();
|
||||
writeToken(SyntaxKind.CloseBraceToken, body.statements.end);
|
||||
}
|
||||
|
||||
function emitClassDeclaration(node: ClassDeclaration) {
|
||||
@@ -1882,7 +1903,7 @@ const _super = (function (geti, seti) {
|
||||
function emitSourceFile(node: SourceFile) {
|
||||
writeLine();
|
||||
emitShebang();
|
||||
emitDetachedComments(node);
|
||||
emitLeadingDetachedComments(node);
|
||||
|
||||
const statements = node.statements;
|
||||
const statementOffset = emitPrologueDirectives(statements);
|
||||
@@ -1900,7 +1921,7 @@ const _super = (function (geti, seti) {
|
||||
tempFlags = savedTempFlags;
|
||||
}
|
||||
|
||||
emitLeadingComments(node.endOfFileToken, getLeadingComments(node.endOfFileToken));
|
||||
emitTrailingDetachedComments(node.statements);
|
||||
}
|
||||
|
||||
// Transformation nodes
|
||||
@@ -2281,6 +2302,7 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function writeToken(token: SyntaxKind, tokenStartPos: number) {
|
||||
tokenStartPos = skipTrivia(currentText, tokenStartPos);
|
||||
emitPos(tokenStartPos);
|
||||
const tokenEndPos = writeTokenText(token, tokenStartPos);
|
||||
emitPos(tokenEndPos);
|
||||
@@ -2295,9 +2317,9 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function writeTokenNode(node: Node) {
|
||||
if (node) {
|
||||
emitStart(node, shouldIgnoreSourceMapForNode, shouldIgnoreSourceMapForChildren);
|
||||
emitStart(node, shouldSkipSourceMapForNode, shouldSkipSourceMapForChildren);
|
||||
writeTokenText(node.kind);
|
||||
emitEnd(node, shouldIgnoreSourceMapForNode, shouldIgnoreSourceMapForChildren);
|
||||
emitEnd(node, shouldSkipSourceMapForNode, shouldSkipSourceMapForChildren);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ namespace ts {
|
||||
context.expressionSubstitution = substituteExpression;
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentParent: Node;
|
||||
let currentNode: Node;
|
||||
let enclosingBlockScopeContainer: Node;
|
||||
@@ -183,6 +184,7 @@ namespace ts {
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
currentText = node.text;
|
||||
return visitNode(node, visitor, isSourceFile);
|
||||
}
|
||||
|
||||
@@ -609,14 +611,14 @@ namespace ts {
|
||||
if (node.name) {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
}
|
||||
|
||||
const closingBraceLocation = { pos: node.end - 1, end: node.end };
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
const classFunction = createFunctionExpression(
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
baseTypeNode ? [createParameter("_super")] : [],
|
||||
transformClassBody(node, baseTypeNode !== undefined, closingBraceLocation),
|
||||
closingBraceLocation
|
||||
transformClassBody(node, baseTypeNode !== undefined)
|
||||
);
|
||||
|
||||
// To preserve the behavior of the old emitter, we explicitly indent
|
||||
@@ -626,15 +628,23 @@ namespace ts {
|
||||
setNodeEmitFlags(classFunction, NodeEmitFlags.Indented);
|
||||
}
|
||||
|
||||
// "inner" and "outer" below are added purely to preserve source map locations from
|
||||
// the old emitter
|
||||
const inner = createPartiallyEmittedExpression(classFunction);
|
||||
inner.end = node.end;
|
||||
setNodeEmitFlags(inner, NodeEmitFlags.NoComments);
|
||||
|
||||
const outer = createPartiallyEmittedExpression(inner);
|
||||
outer.end = node.pos;
|
||||
setNodeEmitFlags(outer, NodeEmitFlags.NoComments);
|
||||
|
||||
return createParen(
|
||||
createCall(
|
||||
classFunction,
|
||||
outer,
|
||||
baseTypeNode
|
||||
? [visitNode(baseTypeNode.expression, visitor, isExpression)]
|
||||
: [],
|
||||
closingBraceLocation
|
||||
),
|
||||
closingBraceLocation
|
||||
: []
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -644,15 +654,33 @@ namespace ts {
|
||||
* @param node A ClassExpression or ClassDeclaration node.
|
||||
* @param hasExtendsClause A value indicating whether the class has an `extends` clause.
|
||||
*/
|
||||
function transformClassBody(node: ClassExpression | ClassDeclaration, hasExtendsClause: boolean, closingBraceLocation: TextRange): Block {
|
||||
function transformClassBody(node: ClassExpression | ClassDeclaration, hasExtendsClause: boolean): Block {
|
||||
const statements: Statement[] = [];
|
||||
startLexicalEnvironment();
|
||||
addExtendsHelperIfNeeded(statements, node, hasExtendsClause);
|
||||
addConstructor(statements, node, hasExtendsClause);
|
||||
addClassMembers(statements, node);
|
||||
statements.push(createReturn(getDeclarationName(node), /*location*/ closingBraceLocation));
|
||||
|
||||
// Create a synthetic text range for the return statement.
|
||||
const closingBraceLocation = createTokenRange(skipTrivia(currentText, node.members.end), SyntaxKind.CloseBraceToken);
|
||||
const name = getDeclarationName(node);
|
||||
|
||||
// The following partially-emitted expression exists purely to align our sourcemap
|
||||
// emit with the original emitter.
|
||||
const outer = createPartiallyEmittedExpression(name);
|
||||
outer.end = closingBraceLocation.end;
|
||||
setNodeEmitFlags(outer, NodeEmitFlags.NoComments);
|
||||
|
||||
const statement = createReturn(outer);
|
||||
statement.pos = closingBraceLocation.pos;
|
||||
statements.push(statement);
|
||||
setNodeEmitFlags(statement, NodeEmitFlags.NoComments);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
return createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
|
||||
const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true);
|
||||
setNodeEmitFlags(block, NodeEmitFlags.NoComments);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -688,7 +716,7 @@ namespace ts {
|
||||
/*asteriskToken*/ undefined,
|
||||
getDeclarationName(node),
|
||||
transformConstructorParameters(constructor, hasSynthesizedSuper),
|
||||
transformConstructorBody(constructor, hasExtendsClause, hasSynthesizedSuper),
|
||||
transformConstructorBody(constructor, node, hasExtendsClause, hasSynthesizedSuper),
|
||||
/*location*/ constructor || node
|
||||
)
|
||||
);
|
||||
@@ -718,11 +746,12 @@ namespace ts {
|
||||
* Transforms the body of a constructor declaration of a class.
|
||||
*
|
||||
* @param constructor The constructor for the class.
|
||||
* @param node The node which contains the constructor.
|
||||
* @param hasExtendsClause A value indicating whether the class has an `extends` clause.
|
||||
* @param hasSynthesizedSuper A value indicating whether the constructor starts with a
|
||||
* synthesized `super` call.
|
||||
*/
|
||||
function transformConstructorBody(constructor: ConstructorDeclaration, hasExtendsClause: boolean, hasSynthesizedSuper: boolean) {
|
||||
function transformConstructorBody(constructor: ConstructorDeclaration, node: ClassDeclaration | ClassExpression, hasExtendsClause: boolean, hasSynthesizedSuper: boolean) {
|
||||
const statements: Statement[] = [];
|
||||
startLexicalEnvironment();
|
||||
if (constructor) {
|
||||
@@ -739,14 +768,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
return createBlock(
|
||||
const block = createBlock(
|
||||
createNodeArray(
|
||||
statements,
|
||||
/*location*/ constructor ? constructor.body.statements : undefined
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
),
|
||||
/*location*/ constructor ? constructor.body : undefined,
|
||||
/*location*/ constructor ? constructor.body : node,
|
||||
/*multiLine*/ true
|
||||
);
|
||||
|
||||
if (!constructor) {
|
||||
setNodeEmitFlags(block, NodeEmitFlags.NoComments);
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
function transformConstructorBodyWithSynthesizedSuper(node: ConstructorDeclaration) {
|
||||
@@ -1077,16 +1112,24 @@ namespace ts {
|
||||
* @param member The MethodDeclaration node.
|
||||
*/
|
||||
function transformClassMethodDeclarationToStatement(receiver: LeftHandSideExpression, member: MethodDeclaration) {
|
||||
return createStatement(
|
||||
const statement = createStatement(
|
||||
createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
visitNode(member.name, visitor, isPropertyName)
|
||||
visitNode(member.name, visitor, isPropertyName),
|
||||
/*location*/ member.name
|
||||
),
|
||||
transformFunctionLikeToExpression(member, /*location*/ undefined, /*name*/ undefined)
|
||||
transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined),
|
||||
/*location*/ moveRangeEnd(member, -1)
|
||||
),
|
||||
/*location*/ member
|
||||
);
|
||||
|
||||
// The location for the statement is used to emit comments only.
|
||||
// No source map should be emitted for this statement to align with the
|
||||
// old emitter.
|
||||
setNodeEmitFlags(statement, NodeEmitFlags.NoSourceMap);
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1096,9 +1139,16 @@ namespace ts {
|
||||
* @param accessors The set of related get/set accessors.
|
||||
*/
|
||||
function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations): Statement {
|
||||
return createStatement(
|
||||
transformAccessorsToExpression(receiver, accessors)
|
||||
const statement = createStatement(
|
||||
transformAccessorsToExpression(receiver, accessors),
|
||||
/*location*/ accessors.firstAccessor
|
||||
);
|
||||
|
||||
// The location for the statement is used to emit source maps only.
|
||||
// No comments should be emitted for this statement to align with the
|
||||
// old emitter.
|
||||
setNodeEmitFlags(statement, NodeEmitFlags.NoComments);
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1122,7 +1172,7 @@ namespace ts {
|
||||
configurable: true
|
||||
},
|
||||
/*preferNewLine*/ true,
|
||||
/*location*/ firstAccessor,
|
||||
/*location*/ undefined,
|
||||
/*descriptorLocations*/ {
|
||||
get: getAccessor,
|
||||
set: setAccessor
|
||||
@@ -1224,6 +1274,7 @@ namespace ts {
|
||||
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
|
||||
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false);
|
||||
}
|
||||
|
||||
addCaptureThisForNodeIfNeeded(statements, node);
|
||||
addDefaultValueAssignmentsIfNeeded(statements, node);
|
||||
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
|
||||
@@ -1244,7 +1295,12 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
Debug.assert(node.kind === SyntaxKind.ArrowFunction);
|
||||
statementsLocation = body;
|
||||
|
||||
// To align with the old emitter, we use a synthetic end position on the location
|
||||
// for the statement list we synthesize when we down-level an arrow function with
|
||||
// an expression function body. This prevents both comments and source maps from
|
||||
// being emitted for the end position only.
|
||||
statementsLocation = moveRangeEnd(body, -1);
|
||||
|
||||
const equalsGreaterThanToken = (<ArrowFunction>node).equalsGreaterThanToken;
|
||||
if (!nodeIsSynthesized(equalsGreaterThanToken) && !nodeIsSynthesized(body)) {
|
||||
@@ -1258,7 +1314,7 @@ namespace ts {
|
||||
|
||||
const expression = visitNode(body, visitor, isExpression);
|
||||
if (expression) {
|
||||
statements.push(createReturn(expression));
|
||||
statements.push(createReturn(expression, /*location*/ statementsLocation));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2943,12 +2943,63 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function collapseRangeToStart(range: TextRange) {
|
||||
return range.pos === range.end ? range : { pos: range.pos, end: range.pos };
|
||||
/**
|
||||
* Creates a new TextRange from a provided range with a new end position.
|
||||
*
|
||||
* @param range A TextRange.
|
||||
* @param end The new end position.
|
||||
*/
|
||||
export function moveRangeEnd(range: TextRange, end: number): TextRange {
|
||||
return { pos: range.pos, end };
|
||||
}
|
||||
|
||||
export function collapseRangeToEnd(range: TextRange) {
|
||||
return range.pos === range.end ? range : { pos: range.end, end: range.end };
|
||||
/**
|
||||
* Creates a new TextRange from a provided range with a new start position.
|
||||
*
|
||||
* @param range A TextRange.
|
||||
* @param pos The new Start position.
|
||||
*/
|
||||
export function moveRangePos(range: TextRange, pos: number): TextRange {
|
||||
return { pos, end: range.end };
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a TextRange has the same start and end positions.
|
||||
*
|
||||
* @param range A TextRange.
|
||||
*/
|
||||
export function isCollapsedRange(range: TextRange) {
|
||||
return range.pos === range.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new TextRange from a provided range with its end position collapsed to its
|
||||
* start position.
|
||||
*
|
||||
* @param range A TextRange.
|
||||
*/
|
||||
export function collapseRangeToStart(range: TextRange): TextRange {
|
||||
return isCollapsedRange(range) ? range : moveRangeEnd(range, range.pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new TextRange from a provided range with its start position collapsed to its
|
||||
* end position.
|
||||
*
|
||||
* @param range A TextRange.
|
||||
*/
|
||||
export function collapseRangeToEnd(range: TextRange): TextRange {
|
||||
return isCollapsedRange(range) ? range : moveRangePos(range, range.end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new TextRange for a token at the provides start position.
|
||||
*
|
||||
* @param pos The start position.
|
||||
* @param token The token.
|
||||
*/
|
||||
export function createTokenRange(pos: number, token: SyntaxKind): TextRange {
|
||||
return { pos, end: pos + tokenToString(token).length };
|
||||
}
|
||||
|
||||
export function rangeIsOnSingleLine(range: TextRange, sourceFile: SourceFile) {
|
||||
|
||||
@@ -45,6 +45,6 @@ var x = function (a) { return a.toString(); };
|
||||
var x2 = function (a) { return a.toString(); }; // Like iWithCallSignatures
|
||||
var x2 = function (a) { return a; }; // Like iWithCallSignatures2
|
||||
// With call signatures of mismatching parameter type
|
||||
var x3 = function (a) { return a.toString(); };
|
||||
var x3 = function (a) { /*here a should be any*/ return a.toString(); };
|
||||
// With call signature count mismatch
|
||||
var x4 = function (a) { return a.toString(); };
|
||||
var x4 = function (a) { /*here a should be any*/ return a.toString(); };
|
||||
|
||||
@@ -110,9 +110,7 @@ var f8 = function (x, y, z) {
|
||||
var f9 = function (a) { return a; };
|
||||
var f10 = function (a) { return a; };
|
||||
var f11 = function (a) { return a; };
|
||||
var f12 = function (a) {
|
||||
return a;
|
||||
};
|
||||
var f12 = function (a) { return a; };
|
||||
// Should be valid.
|
||||
var f11 = function (a) { return a; };
|
||||
// Should be valid.
|
||||
|
||||
Reference in New Issue
Block a user