From eec39c2fc50fdeee05b385e8c83fd54992e03d87 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 7 Apr 2015 17:23:52 -0700 Subject: [PATCH] Additional rule for spacing between decorator on same line as its declaration --- src/services/formatting/rules.ts | 25 +++++++++++++++++++ .../reference/APISample_linter.types | 4 +-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 4319f4bf311..ac3d7fe6783 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -211,6 +211,7 @@ module ts.formatting { // Insert space after @ in decorator public SpaceBeforeAt: Rule; public NoSpaceAfterAt: Rule; + public SpaceAfterDecorator: Rule; constructor() { /// @@ -351,6 +352,7 @@ module ts.formatting { // 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)); + this.SpaceAfterDecorator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.ExportKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.ClassKeyword, SyntaxKind.StaticKeyword, SyntaxKind.PublicKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.GetKeyword, SyntaxKind.SetKeyword, SyntaxKind.OpenBracketToken, SyntaxKind.AsteriskToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), RuleAction.Space)); // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = @@ -392,6 +394,7 @@ module ts.formatting { this.NoSpaceAfterCloseAngularBracket, this.SpaceBeforeAt, this.NoSpaceAfterAt, + this.SpaceAfterDecorator, ]; // These rules are lower in priority than user-configurable rules. @@ -659,6 +662,28 @@ module ts.formatting { return context.TokensAreOnSameLine(); } + static IsEndOfDecoratorContextOnSameLine(context: FormattingContext): boolean { + return context.TokensAreOnSameLine() && + context.contextNode.decorators && + Rules.NodeIsInDecoratorContext(context.currentTokenParent) && + !Rules.NodeIsInDecoratorContext(context.nextTokenParent); + } + + static NodeIsInDecoratorContext(node: Node): boolean { + if (node.parserContextFlags & ParserContextFlags.Decorator) { + return true; + } + while (node) { + if (isExpression(node)) { + node = node.parent; + } + else { + return node.kind === SyntaxKind.Decorator; + } + } + return false; + } + static IsStartOfVariableDeclarationList(context: FormattingContext): boolean { return context.currentTokenParent.kind === SyntaxKind.VariableDeclarationList && context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos; diff --git a/tests/baselines/reference/APISample_linter.types b/tests/baselines/reference/APISample_linter.types index 609f08f3a76..5db938d63bd 100644 --- a/tests/baselines/reference/APISample_linter.types +++ b/tests/baselines/reference/APISample_linter.types @@ -237,9 +237,9 @@ export function delint(sourceFile: ts.SourceFile) { >sourceFile : ts.SourceFile >getLineAndCharacterOfPosition : (pos: number) => ts.LineAndCharacter >node.getStart() : number ->node.getStart : (sourceFile?: ts.SourceFile) => number +>node.getStart : (sourceFile?: ts.SourceFile, skipDecorators?: boolean) => number >node : ts.Node ->getStart : (sourceFile?: ts.SourceFile) => number +>getStart : (sourceFile?: ts.SourceFile, skipDecorators?: boolean) => number console.log(`${sourceFile.fileName} (${line + 1},${character + 1}): ${message}`); >console.log(`${sourceFile.fileName} (${line + 1},${character + 1}): ${message}`) : any