Merge pull request #10054 from SaschaNaz/jsxopening

Format JSX opening element
This commit is contained in:
Ryan Cavanaugh
2016-08-01 15:50:43 -07:00
committed by GitHub
3 changed files with 48 additions and 20 deletions

View File

@@ -453,9 +453,9 @@ namespace ts.formatting {
case SyntaxKind.MethodDeclaration:
if ((<MethodDeclaration>node).asteriskToken) {
return SyntaxKind.AsteriskToken;
}
// fall-through
}/*
fall-through
*/
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.Parameter:
return (<Declaration>node).name.kind;
@@ -732,7 +732,7 @@ namespace ts.formatting {
else {
// indent token only if end line of previous range does not match start line of the token
const prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line;
indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine;
}
}
}
@@ -892,7 +892,7 @@ namespace ts.formatting {
}
function indentationIsDifferent(indentationString: string, startLinePosition: number): boolean {
return indentationString !== sourceFile.text.substr(startLinePosition , indentationString.length);
return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
}
function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) {
@@ -936,7 +936,7 @@ namespace ts.formatting {
// shift all parts on the delta size
const delta = indentation - nonWhitespaceColumnInFirstPart.column;
for (let i = startIndex, len = parts.length; i < len; i++, startLine++) {
for (let i = startIndex, len = parts.length; i < len; i++ , startLine++) {
const startLinePos = getStartPositionOfLine(startLine, sourceFile);
const nonWhitespaceCharacterAndColumn =
i === 0

View File

@@ -231,6 +231,13 @@ namespace ts.formatting {
public NoSpaceBeforeCloseBraceInJsxExpression: Rule;
public SpaceBeforeCloseBraceInJsxExpression: Rule;
// JSX opening elements
public SpaceBeforeJsxAttribute: Rule;
public SpaceBeforeSlashInJsxOpeningElement: Rule;
public NoSpaceBeforeGreaterThanTokenInJsxOpeningElement: Rule;
public NoSpaceBeforeEqualInJsxAttribute: Rule;
public NoSpaceAfterEqualInJsxAttribute: Rule;
constructor() {
///
/// Common Rules
@@ -322,7 +329,7 @@ namespace ts.formatting {
// Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
// So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space));
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space));
// This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
@@ -386,6 +393,13 @@ namespace ts.formatting {
// template string
this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
// jsx opening element
this.SpaceBeforeJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
this.SpaceBeforeSlashInJsxOpeningElement = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SlashToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new Rule(RuleDescriptor.create1(SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeEqualInJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
this.NoSpaceAfterEqualInJsxAttribute = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
// These rules are higher in priority than user-configurable rules.
this.HighPriorityCommonRules = [
this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
@@ -413,6 +427,8 @@ namespace ts.formatting {
this.SpaceAfterVoidOperator,
this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword,
this.NoSpaceBetweenTagAndTemplateString,
this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement,
this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute,
// TypeScript-specific rules
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
@@ -450,8 +466,8 @@ namespace ts.formatting {
///
// Insert space after comma delimiter
this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext), RuleAction.Delete));
this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), RuleAction.Delete));
// Insert space before and after binary operators
this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
@@ -498,10 +514,10 @@ namespace ts.formatting {
this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
// No space after { and before } in JSX expression
this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete));
this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space));
this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete));
this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space));
// Insert space after function keyword for anonymous functions
this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
@@ -741,14 +757,26 @@ namespace ts.formatting {
return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText;
}
static isNonJsxElementContext(context: FormattingContext): boolean {
static IsNonJsxElementContext(context: FormattingContext): boolean {
return context.contextNode.kind !== SyntaxKind.JsxElement;
}
static isJsxExpressionContext(context: FormattingContext): boolean {
static IsJsxExpressionContext(context: FormattingContext): boolean {
return context.contextNode.kind === SyntaxKind.JsxExpression;
}
static IsNextTokenParentJsxAttribute(context: FormattingContext): boolean {
return context.nextTokenParent.kind === SyntaxKind.JsxAttribute;
}
static IsJsxAttributeContext(context: FormattingContext): boolean {
return context.contextNode.kind === SyntaxKind.JsxAttribute;
}
static IsJsxSelfClosingElementContext(context: FormattingContext): boolean {
return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement;
}
static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean {
return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context);
}

View File

@@ -70,7 +70,7 @@
////<div>, {integer}</div>;/*commaInJsxElement2*/
////<span>)</span>;/*closingParenInJsxElement*/
////<span>) </span>;/*closingParenInJsxElement2*/
////<Router routes={ 3 } />;/*jsxExpressionSpaces*/
////<Router routes = { 3 } / >;/*jsxExpressionSpaces*/
////<Router routes={ (3) } />;/*jsxExpressionSpaces2*/
format.document();
@@ -85,7 +85,7 @@ goTo.marker("indent1");
verify.indentationIs(12);
goTo.marker("1");
verify.currentLineContentIs(' class1= {');
verify.currentLineContentIs(' class1={');
goTo.marker("2");
verify.currentLineContentIs(' }>');
@@ -95,7 +95,7 @@ goTo.marker("indent2");
verify.indentationIs(12);
goTo.marker("3");
verify.currentLineContentIs(' class2= {');
verify.currentLineContentIs(' class2={');
goTo.marker("4");
verify.currentLineContentIs(' }>');
@@ -105,9 +105,9 @@ goTo.marker("indent3");
verify.indentationIs(12);
goTo.marker("5");
verify.currentLineContentIs(' class3= {');
verify.currentLineContentIs(' class3={');
goTo.marker("6");
verify.currentLineContentIs(' }/>');
verify.currentLineContentIs(' } />');
goTo.marker("attrAutoformat");