Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templates: location information from @angular/compiler is not always as expected #292

Closed
drakenfly opened this issue Jan 14, 2021 · 10 comments
Milestone

Comments

@drakenfly
Copy link

drakenfly commented Jan 14, 2021

I noticed that expressions with additional whitespaces lead to wrong reports of errors:

I created an examplatory test-case for the negated-async pipe which fails, even though it should obviously pass:

convertAnnotatedSourceToFailureCase({
  description: 'it should fail if async pipe is negated even with additional whitespace',
  annotatedSource: `
    {{     !(foo | async) }}
           ~~~~~~~~~~~~~~
  `,
  messageId: noNegatedAsync
}),

Note: This also affects BoundAttributes, not only Interpolations.

@angular-eslint/template-parser invokes @angular/compiler with preserveWhitespaces set to true:

function parseForESLint(code: string, options: { filePath: string }) {
  const angularCompilerResult = parseTemplate(code, options.filePath, {
    preserveWhitespaces: true,
  });
 // ...
}

I tried to debug the parser and it seems impossible to find the absolute positions in the actual sourcecode with preserveWhitespaces: true, because the source-property of the AST is trimmed before the compiler decides about the location of the processed source code fragment.

Is there a way to solve this issue? Simply switching it off leads to a lot off issues in other rules (I tried running all test cases in the project).

@JamesHenry JamesHenry added the blocked:@angular/compiler This issue requires changes to the @angular/compiler in order to be resolved label Jan 16, 2021
@JamesHenry
Copy link
Member

There isn't documentation from the Angular Team for usage of the compiler API, so everything we know/have implemented is based on just digging in and trying to figure stuff out.

I will message the Angular tooling team and request a process for us to report and resolve these issues.

@JamesHenry
Copy link
Member

From @rafaelss95 on an overlapping issue:


As reported in mgechev/codelyzer#859, #205 (comment) and #269 (comment), column numbers are off by one.

Sample:

<a href="http://example.com">{{ getInfo() }}</a>
~~~~~~~~~


I noticed that we have a hacky way to handle this in no-negated-async:

const additionalOffset = isInterpolation(type) ? -1 : 0;
and
const additionalStartOffset = isInterpolation(type) ? -2 : -1;
const additionalEndOffset = isInterpolation(type) ? -1 : 0;

@JamesHenry JamesHenry changed the title 'ignoreWhitespace: true' as @angular/compiler option leads to error report shifting Templates: location information from @angular/compiler is not always expected Jan 16, 2021
@JamesHenry
Copy link
Member

Folding this in, even though it might not be 100% related to the original description.

Truly single line inline-templates have wonky location information right now:


Multi-line:
image

🙅 Single-line:
image

@JamesHenry JamesHenry changed the title Templates: location information from @angular/compiler is not always expected Templates: location information from @angular/compiler is not always as expected Jan 16, 2021
@jerone
Copy link
Contributor

jerone commented Jan 17, 2021

Not only column is off by one (or sometimes two):

test
{{ property }}
  ~~~~~~~~

The line index can also be off:

test
{{
  ~~~~~~~~
    property
}}

@kyliau
Copy link

kyliau commented Jan 27, 2021

I think this might have something to do with CRLF line endings.
@JamesHenry could you please try passing preserveLineEndings: true to parseTemplate and see if it fixes the offset problem?
Ref https://github.com/angular/angular/blob/66c27ffdfc0e4f0a37a375a453d368c8ef13e326/packages/compiler/src/ml_parser/lexer.ts#L116-L119

@JamesHenry
Copy link
Member

JamesHenry commented Feb 6, 2021

Thanks @kyliau! At the time you wrote this it hadn't actually been released :)

It is now available on npm though and I have a PR in the works which enables that and preserveWhitespace. With those two we definitely seem to get more predictable location information, thanks a lot!

If you could let us know your/the teams thoughts on HTML comment nodes (which will unblock #97) that would cover off everything for now

Thanks again!

@JamesHenry JamesHenry added this to the v2 milestone Mar 7, 2021
@JamesHenry JamesHenry mentioned this issue Mar 7, 2021
@JamesHenry JamesHenry removed the blocked:@angular/compiler This issue requires changes to the @angular/compiler in order to be resolved label Mar 7, 2021
@JamesHenry
Copy link
Member

Resolved in the newly published v2.0.0, see releases or changelog for more information.

@jerone
Copy link
Contributor

jerone commented Mar 14, 2021

I upgraded my plugin and can confirm that all interpolation locations are correct now. Thanks.

However, the location for data-binding is still off. 
Let me explain with the following HTML template:

<div [class]="
    value
">
</div>

As seen in the screenshot below, the location of the warning is:

{
	"start": { 
		"line": 2, 
		"column": 9 
	}, 
	"end": { 
		"line": 3, 
		"column": 3 
	}
}
<div [class]="
    value
         ~
">
~~
</div>

image

While, I expect the error to be under value:

{
	"start": { 
		"line": 2, 
		"column": 4 
	}, 
	"end": { 
		"line": 2, 
		"column": 9 
	}
}
<div [class]="
    value
    ~~~~~
">
</div>

@jerone
Copy link
Contributor

jerone commented Mar 21, 2021

@JamesHenry Should I open an new bug issue with above report?

@JamesHenry
Copy link
Member

Yes please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants