mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Added rules for spacing around decorators, computing the undecorated start line of a node
This commit is contained in:
@@ -150,14 +150,20 @@ module ts {
|
||||
return !nodeIsMissing(node);
|
||||
}
|
||||
|
||||
export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile): number {
|
||||
export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile, skipDecorators?: boolean): number {
|
||||
// With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
|
||||
// want to skip trivia because this will launch us forward to the next token.
|
||||
if (nodeIsMissing(node)) {
|
||||
return node.pos;
|
||||
}
|
||||
|
||||
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
|
||||
let pos = node.pos;
|
||||
if (skipDecorators && node.decorators) {
|
||||
// Skip past decorators
|
||||
pos = node.decorators.end;
|
||||
}
|
||||
|
||||
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, pos);
|
||||
}
|
||||
|
||||
export function getSourceTextOfNodeFromSourceFile(sourceFile: SourceFile, node: Node): string {
|
||||
|
||||
@@ -328,8 +328,13 @@ module ts.formatting {
|
||||
|
||||
if (formattingScanner.isOnToken()) {
|
||||
let startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line;
|
||||
let undecoratedStartLine = startLine;
|
||||
if (enclosingNode.decorators) {
|
||||
undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile, /*skipDecorators*/ true)).line;
|
||||
}
|
||||
|
||||
let delta = getOwnOrInheritedDelta(enclosingNode, options, sourceFile);
|
||||
processNode(enclosingNode, enclosingNode, startLine, initialIndentation, delta);
|
||||
processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta);
|
||||
}
|
||||
|
||||
formattingScanner.close();
|
||||
@@ -500,7 +505,7 @@ module ts.formatting {
|
||||
}
|
||||
}
|
||||
|
||||
function processNode(node: Node, contextNode: Node, nodeStartLine: number, indentation: number, delta: number) {
|
||||
function processNode(node: Node, contextNode: Node, nodeStartLine: number, undecoratedNodeStartLine: number, indentation: number, delta: number) {
|
||||
if (!rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) {
|
||||
return;
|
||||
}
|
||||
@@ -526,7 +531,7 @@ module ts.formatting {
|
||||
forEachChild(
|
||||
node,
|
||||
child => {
|
||||
processChildNode(child, /*inheritedIndentation*/ Constants.Unknown, node, nodeDynamicIndentation, nodeStartLine, /*isListElement*/ false)
|
||||
processChildNode(child, /*inheritedIndentation*/ Constants.Unknown, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListElement*/ false)
|
||||
},
|
||||
(nodes: NodeArray<Node>) => {
|
||||
processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation);
|
||||
@@ -547,11 +552,17 @@ module ts.formatting {
|
||||
parent: Node,
|
||||
parentDynamicIndentation: DynamicIndentation,
|
||||
parentStartLine: number,
|
||||
undecoratedParentStartLine: number,
|
||||
isListItem: boolean): number {
|
||||
|
||||
let childStartPos = child.getStart(sourceFile);
|
||||
|
||||
let childStart = sourceFile.getLineAndCharacterOfPosition(childStartPos);
|
||||
let childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line;
|
||||
|
||||
let undecoratedChildStartLine = childStartLine;
|
||||
if (child.decorators) {
|
||||
undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(child.getStart(sourceFile, /*skipDecorators*/ true)).line;
|
||||
}
|
||||
|
||||
// if child is a list item - try to get its indentation
|
||||
let childIndentationAmount = Constants.Unknown;
|
||||
@@ -594,9 +605,10 @@ module ts.formatting {
|
||||
return inheritedIndentation;
|
||||
}
|
||||
|
||||
let childIndentation = computeIndentation(child, childStart.line, childIndentationAmount, node, parentDynamicIndentation, parentStartLine);
|
||||
let effectiveParentStartLine = child.kind === SyntaxKind.Decorator ? childStartLine : undecoratedParentStartLine;
|
||||
let childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine);
|
||||
|
||||
processNode(child, childContextNode, childStart.line, childIndentation.indentation, childIndentation.delta);
|
||||
processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
|
||||
|
||||
childContextNode = node;
|
||||
|
||||
@@ -640,7 +652,7 @@ module ts.formatting {
|
||||
|
||||
let inheritedIndentation = Constants.Unknown;
|
||||
for (let child of nodes) {
|
||||
inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, /*isListElement*/ true)
|
||||
inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListElement*/ true)
|
||||
}
|
||||
|
||||
if (listEndToken !== SyntaxKind.Unknown) {
|
||||
|
||||
@@ -208,6 +208,10 @@ module ts.formatting {
|
||||
public SpaceAfterAnonymousFunctionKeyword: Rule;
|
||||
public NoSpaceAfterAnonymousFunctionKeyword: Rule;
|
||||
|
||||
// Insert space after @ in decorator
|
||||
public SpaceBeforeAt: Rule;
|
||||
public NoSpaceAfterAt: Rule;
|
||||
|
||||
constructor() {
|
||||
///
|
||||
/// Common Rules
|
||||
@@ -344,6 +348,10 @@ module ts.formatting {
|
||||
// Remove spaces in empty interface literals. e.g.: x: {}
|
||||
this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsObjectTypeContext), RuleAction.Delete));
|
||||
|
||||
// decorators
|
||||
this.SpaceBeforeAt = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.AtToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
|
||||
this.NoSpaceAfterAt = new Rule(RuleDescriptor.create3(SyntaxKind.AtToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
|
||||
|
||||
// These rules are higher in priority than user-configurable rules.
|
||||
this.HighPriorityCommonRules =
|
||||
[
|
||||
@@ -381,7 +389,9 @@ module ts.formatting {
|
||||
this.NoSpaceBetweenCloseParenAndAngularBracket,
|
||||
this.NoSpaceAfterOpenAngularBracket,
|
||||
this.NoSpaceBeforeCloseAngularBracket,
|
||||
this.NoSpaceAfterCloseAngularBracket
|
||||
this.NoSpaceAfterCloseAngularBracket,
|
||||
this.SpaceBeforeAt,
|
||||
this.NoSpaceAfterAt,
|
||||
];
|
||||
|
||||
// These rules are lower in priority than user-configurable rules.
|
||||
|
||||
@@ -19,7 +19,7 @@ module ts {
|
||||
getChildCount(sourceFile?: SourceFile): number;
|
||||
getChildAt(index: number, sourceFile?: SourceFile): Node;
|
||||
getChildren(sourceFile?: SourceFile): Node[];
|
||||
getStart(sourceFile?: SourceFile): number;
|
||||
getStart(sourceFile?: SourceFile, skipDecorators?: boolean): number;
|
||||
getFullStart(): number;
|
||||
getEnd(): number;
|
||||
getWidth(sourceFile?: SourceFile): number;
|
||||
@@ -149,8 +149,8 @@ module ts {
|
||||
return getSourceFileOfNode(this);
|
||||
}
|
||||
|
||||
public getStart(sourceFile?: SourceFile): number {
|
||||
return getTokenPosOfNode(this, sourceFile);
|
||||
public getStart(sourceFile?: SourceFile, skipDecorators?: boolean): number {
|
||||
return getTokenPosOfNode(this, sourceFile, skipDecorators);
|
||||
}
|
||||
|
||||
public getFullStart(): number {
|
||||
|
||||
Reference in New Issue
Block a user