diff --git a/src/Formatter.spec.ts b/src/Formatter.spec.ts index 21ba9d1..675b278 100644 --- a/src/Formatter.spec.ts +++ b/src/Formatter.spec.ts @@ -664,6 +664,56 @@ end sub`; formatEqual(`action("value" ,"otherValue")`, `action("value", "otherValue")`); }); + it('removes whitespace if present in component scope variable declaration', () => { + expect(formatter.format(`m.a`)).to.equal(`m.a`); + expect(formatter.format(`m.foo`)).to.equal(`m.foo`); + expect(formatter.format(`m. a`)).to.equal(`m.a`); + expect(formatter.format(`m. foo`)).to.equal(`m.foo`); + expect(formatter.format(`m .a`)).to.equal(`m.a`); + expect(formatter.format(`m .foo`)).to.equal(`m.foo`); + expect(formatter.format(`m . a`)).to.equal(`m.a`); + expect(formatter.format(`m . foo`)).to.equal(`m.foo`); + }); + + it('formats with optional chaining operators', () => { + formatEqual( + `m. alpha = m. alpha`, + `m.alpha = m.alpha` + ); + formatEqual( + `m .beta = m .beta`, + `m.beta = m.beta` + ); + formatEqual( + `m . charlie = m . charlie`, + `m.charlie = m.charlie` + ); + formatEqual( + `print alpha . beta`, + `print alpha.beta` + ); + formatEqual( + `doSomething(alpha . beta)`, + `doSomething(alpha.beta)` + ); + formatEqual( + `doSomething(doSomethingElse( alpha . beta . charlie))`, + `doSomething(doSomethingElse(alpha.beta.charlie))` + ); + formatEqual( + `value = alpha . beta + delta . charlie`, + `value = alpha.beta + delta.charlie` + ); + formatEqual( + `value = 1 + (alpha . beta * (delta . charlie - 2) )`, + `value = 1 + (alpha.beta * (delta.charlie - 2))` + ); + formatEqual( + `value = { alpha: beta . charlie }`, + `value = { alpha: beta.charlie }` + ); + }); + it('disabling the rule works', () => { expect(formatter.format(`a=1`)).to.equal('a = 1'); //disabled diff --git a/src/formatters/InteriorWhitespaceFormatter.ts b/src/formatters/InteriorWhitespaceFormatter.ts index fddd2c1..d72dd0a 100644 --- a/src/formatters/InteriorWhitespaceFormatter.ts +++ b/src/formatters/InteriorWhitespaceFormatter.ts @@ -83,10 +83,31 @@ export class InteriorWhitespaceFormatter { continue; } isPastFirstTokenOfLine = true; - //force token to be exactly 1 space if (token.kind === TokenKind.Whitespace) { + //force token to be exactly 1 space token.text = ' '; } + if (token.kind === TokenKind.Dot && i > 0) { + let whitespaceExistsOnTheLeft = true; + // eslint-disable-next-line no-unmodified-loop-condition + while (whitespaceExistsOnTheLeft === true) { + if (tokens[i - 1].kind === TokenKind.Whitespace) { + this.removeWhitespace(tokens, i - 1); + i--; + } else { + whitespaceExistsOnTheLeft = false; + } + } + let whitespaceExistsOnTheRight = true; + // eslint-disable-next-line no-unmodified-loop-condition + while (whitespaceExistsOnTheRight === true) { + if (tokens[i + 1].kind === TokenKind.Whitespace) { + this.removeWhitespace(tokens, i + 1); + } else { + whitespaceExistsOnTheRight = false; + } + } + } //pad any of these token types with a space to the right if (addRight.includes(token.kind)) { @@ -374,7 +395,7 @@ export class InteriorWhitespaceFormatter { } /** - * Determine if the current token appears to be the negative sign for a numeric leteral + * Determine if the current token appears to be the negative sign for a numeric literal */ public looksLikeNegativeNumericLiteral(tokens: Token[], index: number) { let thisToken = tokens[index];