From 77965af47cbc5dc997e90d72dbf302f0b4a3200e Mon Sep 17 00:00:00 2001 From: mgechev Date: Sat, 1 Jul 2017 16:36:48 +0300 Subject: [PATCH] fix(rules): handle the desugered syntax of ngFor Fix #346 --- .../templates/basicTemplateAstVisitor.ts | 29 +++++++++++++------ src/angularWhitespaceRule.ts | 1 - test/angularWhitespaceRule.spec.ts | 4 +-- test/noAccessMissingMemberRule.spec.ts | 4 +-- test/templatesUsePublicRule.spec.ts | 4 +-- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/angular/templates/basicTemplateAstVisitor.ts b/src/angular/templates/basicTemplateAstVisitor.ts index 8290aafb5..30717de64 100644 --- a/src/angular/templates/basicTemplateAstVisitor.ts +++ b/src/angular/templates/basicTemplateAstVisitor.ts @@ -45,21 +45,32 @@ const getExpressionDisplacement = (binding: any) => { if (!(binding instanceof ast.BoundDirectivePropertyAst)) { attrLen = binding.name.length + 4 + subBindingLen; } + // Total length of the attribute value if (binding instanceof ast.BoundEventAst) { valLen = binding.handler.span.end; + } else if (binding instanceof ast.BoundDirectivePropertyAst && binding.templateName === 'ngForOf') { + // Handling everything except [ngForOf] differently + // [ngForOf] requires different logic because it gets desugered from *ngFor + const content = binding.sourceSpan.end.file.content; + const ngForSubstr = content.substring(binding.sourceSpan.start.offset, binding.sourceSpan.end.offset); + result = ngForSubstr.lastIndexOf((binding.value as any).source) + '*ngFor'.length; } else { valLen = binding.value.span.end; } - // Total length of the entire part of the template AST corresponding to this AST. - totalLength = binding.sourceSpan.end.offset - binding.sourceSpan.start.offset; - // The whitespace are possible only in: - // `[foo.bar] = "...."`, - // and they are everything except the attrLen and the valLen (-1 because of the close quote). - let whitespace = totalLength - (attrLen + valLen) - 1; - // The resulted displacement is the length of the attribute + the whitespaces which - // can be located ONLY before the value (the binding). - result = whitespace + attrLen + binding.sourceSpan.start.offset; + + // Handling everything except [ngForOf] + if (!(binding instanceof ast.BoundDirectivePropertyAst) || binding.templateName !== 'ngForOf') { + // Total length of the entire part of the template AST corresponding to this AST. + totalLength = binding.sourceSpan.end.offset - binding.sourceSpan.start.offset; + // The whitespace are possible only in: + // `[foo.bar] = "...."`, + // and they are everything except the attrLen and the valLen (-1 because of the close quote). + let whitespace = totalLength - (attrLen + valLen) - 1; + // The resulted displacement is the length of the attribute + the whitespaces which + // can be located ONLY before the value (the binding). + result = whitespace + attrLen + binding.sourceSpan.start.offset; + } } else if (binding instanceof ast.BoundTextAst) { result = binding.sourceSpan.start.offset; } diff --git a/src/angularWhitespaceRule.ts b/src/angularWhitespaceRule.ts index 469344df0..9e922b207 100644 --- a/src/angularWhitespaceRule.ts +++ b/src/angularWhitespaceRule.ts @@ -159,7 +159,6 @@ class PipeWhitespaceVisitor extends RecursiveAngularExpressionVisitor implements const exprEnd = context.getSourcePosition(ast.exp.span.end); const sf = context.getSourceFile().getFullText(); const exprText = sf.substring(exprStart, exprEnd); - const replacements = []; // Handling the right side of the pipe let leftBeginning = exprEnd + 1; // exprEnd === '|' diff --git a/test/angularWhitespaceRule.spec.ts b/test/angularWhitespaceRule.spec.ts index b3c2aba3c..15f2f1279 100644 --- a/test/angularWhitespaceRule.spec.ts +++ b/test/angularWhitespaceRule.spec.ts @@ -55,7 +55,7 @@ describe('angular-whitespace', () => { assertSuccess('angular-whitespace', source, ['check-pipe']); }); - it.only('should succeed with in structural directives with proper style', () => { + it('should succeed with in structural directives with proper style', () => { let source = ` @Component({ selector: 'foo', @@ -128,7 +128,7 @@ describe('angular-whitespace', () => { @Component({ selector: 'foo', template: \` -
{{ pony }}
+
{{ pony }}
\` }) class Bar { diff --git a/test/noAccessMissingMemberRule.spec.ts b/test/noAccessMissingMemberRule.spec.ts index d04efa247..6243b9fb5 100644 --- a/test/noAccessMissingMemberRule.spec.ts +++ b/test/noAccessMissingMemberRule.spec.ts @@ -657,7 +657,7 @@ describe('no-access-missing-member', () => { let source = ` @Component({ template: \`
- ~~~~~~~ + ~~~~~~~ \` }) class Test { @@ -674,7 +674,7 @@ describe('no-access-missing-member', () => { let source = ` @Component({ template: \`
- ~~~~~~~ + ~~~~~~~
\` }) diff --git a/test/templatesUsePublicRule.spec.ts b/test/templatesUsePublicRule.spec.ts index 8328f4dbc..7d3800c0d 100644 --- a/test/templatesUsePublicRule.spec.ts +++ b/test/templatesUsePublicRule.spec.ts @@ -215,7 +215,7 @@ describe('templates-use-public', () => { selector: 'foobar', template: \`
- ~~~~~~ + ~~~~~~
\` @@ -237,7 +237,7 @@ describe('templates-use-public', () => { selector: 'foobar', template: \`
- ~~~~~ + ~~~~~
\`