feat(compiler-cli): improve error messages produced during structural errors (#20459)
The errors produced when error were encountered while interpreting the content of a directive was often incomprehencible. With this change these kind of error messages should be easier to understand and diagnose. PR Close #20459
This commit is contained in:

committed by
Miško Hevery

parent
1366762d12
commit
8ecda94899
@ -13,7 +13,7 @@ import {Diagnostics} from '../src/types';
|
||||
import {TypeScriptServiceHost} from '../src/typescript_host';
|
||||
|
||||
import {toh} from './test_data';
|
||||
import {MockTypescriptHost, includeDiagnostic, noDiagnostics} from './test_utils';
|
||||
import {MockTypescriptHost, diagnosticMessageContains, findDiagnostic, includeDiagnostic, noDiagnostics} from './test_utils';
|
||||
|
||||
describe('diagnostics', () => {
|
||||
let documentRegistry = ts.createDocumentRegistry();
|
||||
@ -123,7 +123,8 @@ describe('diagnostics', () => {
|
||||
addCode(code, (fileName, content) => {
|
||||
const diagnostics = ngService.getDiagnostics(fileName);
|
||||
includeDiagnostic(
|
||||
diagnostics !, 'Function calls are not supported.', '() => \'foo\'', content);
|
||||
diagnostics !, 'Function expressions are not supported in decorators', '() => \'foo\'',
|
||||
content);
|
||||
});
|
||||
});
|
||||
|
||||
@ -168,8 +169,7 @@ describe('diagnostics', () => {
|
||||
const code =
|
||||
` @Component({template: '<p> Using an invalid pipe {{data | dat}} </p>'}) export class MyComponent { data = 'some data'; }`;
|
||||
addCode(code, fileName => {
|
||||
const diagnostic =
|
||||
ngService.getDiagnostics(fileName) !.filter(d => d.message.indexOf('pipe') > 0)[0];
|
||||
const diagnostic = findDiagnostic(ngService.getDiagnostics(fileName) !, 'pipe') !;
|
||||
expect(diagnostic).not.toBeUndefined();
|
||||
expect(diagnostic.span.end - diagnostic.span.start).toBeLessThan(11);
|
||||
});
|
||||
@ -216,8 +216,8 @@ describe('diagnostics', () => {
|
||||
`,
|
||||
fileName => {
|
||||
const diagnostics = ngService.getDiagnostics(fileName) !;
|
||||
const expected = diagnostics.find(d => d.message.startsWith('Invalid providers for'));
|
||||
const notExpected = diagnostics.find(d => d.message.startsWith('Cannot read property'));
|
||||
const expected = findDiagnostic(diagnostics, 'Invalid providers for');
|
||||
const notExpected = findDiagnostic(diagnostics, 'Cannot read property');
|
||||
expect(expected).toBeDefined();
|
||||
expect(notExpected).toBeUndefined();
|
||||
});
|
||||
@ -355,12 +355,12 @@ describe('diagnostics', () => {
|
||||
expect(diagnostics.length).toBe(1);
|
||||
if (diagnostics.length > 1) {
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (diagnostic.message.indexOf('MyComponent') >= 0) continue;
|
||||
if (diagnosticMessageContains(diagnostic.message, 'MyComponent')) continue;
|
||||
fail(`(${diagnostic.span.start}:${diagnostic.span.end}): ${diagnostic.message}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
expect(diagnostics[0].message.indexOf('MyComponent') >= 0).toBeTruthy();
|
||||
expect(diagnosticMessageContains(diagnostics[0].message, 'MyComponent')).toBeTruthy();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {Diagnostic, Diagnostics, Span} from '../src/types';
|
||||
import {Diagnostic, DiagnosticMessageChain, Diagnostics, Span} from '../src/types';
|
||||
|
||||
export type MockData = string | MockDirectory;
|
||||
|
||||
@ -317,6 +317,25 @@ export function noDiagnostics(diagnostics: Diagnostics) {
|
||||
}
|
||||
}
|
||||
|
||||
export function diagnosticMessageContains(
|
||||
message: string | DiagnosticMessageChain, messageFragment: string): boolean {
|
||||
if (typeof message == 'string') {
|
||||
return message.indexOf(messageFragment) >= 0;
|
||||
}
|
||||
if (message.message.indexOf(messageFragment) >= 0) {
|
||||
return true;
|
||||
}
|
||||
if (message.next) {
|
||||
return diagnosticMessageContains(message.next, messageFragment);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function findDiagnostic(diagnostics: Diagnostic[], messageFragment: string): Diagnostic|
|
||||
undefined {
|
||||
return diagnostics.find(d => diagnosticMessageContains(d.message, messageFragment));
|
||||
}
|
||||
|
||||
export function includeDiagnostic(
|
||||
diagnostics: Diagnostics, message: string, text?: string, len?: string): void;
|
||||
export function includeDiagnostic(
|
||||
@ -324,14 +343,18 @@ export function includeDiagnostic(
|
||||
export function includeDiagnostic(diagnostics: Diagnostics, message: string, p1?: any, p2?: any) {
|
||||
expect(diagnostics).toBeDefined();
|
||||
if (diagnostics) {
|
||||
const diagnostic = diagnostics.find(d => d.message.indexOf(message) >= 0) as Diagnostic;
|
||||
expect(diagnostic).toBeDefined();
|
||||
const diagnostic = findDiagnostic(diagnostics, message);
|
||||
expect(diagnostic).toBeDefined(`no diagnostic contains '${message}`);
|
||||
if (diagnostic && p1 != null) {
|
||||
const at = typeof p1 === 'number' ? p1 : p2.indexOf(p1);
|
||||
const len = typeof p2 === 'number' ? p2 : p1.length;
|
||||
expect(diagnostic.span.start).toEqual(at);
|
||||
expect(diagnostic.span.start)
|
||||
.toEqual(
|
||||
at,
|
||||
`expected message '${message}' was reported at ${diagnostic.span.start} but should be ${at}`);
|
||||
if (len != null) {
|
||||
expect(diagnostic.span.end - diagnostic.span.start).toEqual(len);
|
||||
expect(diagnostic.span.end - diagnostic.span.start)
|
||||
.toEqual(len, `expected '${message}'s span length to be ${len}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user