fix(compiler): correctly map error message locations (#19424)

This commit is contained in:
Chuck Jazdzewski 2017-09-28 10:53:04 -07:00 committed by Victor Berchet
parent b3db3f80ba
commit ff5b050a92
2 changed files with 43 additions and 2 deletions

View File

@ -161,7 +161,7 @@ export class EmitterVisitorContext {
spanOf(line: number, column: number): ParseSourceSpan|null {
const emittedLine = this._lines[line - this._preambleLineCount];
if (emittedLine) {
let columnsLeft = column - emittedLine.indent;
let columnsLeft = column - _createIndent(emittedLine.indent).length;
for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
const part = emittedLine.parts[partIndex];
if (part.length > columnsLeft) {

View File

@ -9,7 +9,7 @@
import {StaticSymbol} from '@angular/compiler/src/aot/static_symbol';
import * as o from '@angular/compiler/src/output/output_ast';
import {TypeScriptEmitter} from '@angular/compiler/src/output/ts_emitter';
import {ParseLocation, ParseSourceFile, ParseSourceSpan} from '@angular/compiler/src/parse_util';
import {stripSourceMapAndNewLine} from './abstract_emitter_spec';
const someGenFilePath = 'somePackage/someGenFile';
@ -420,5 +420,46 @@ export function main() {
'/* SomePreamble */', 'a;'
].join('\n'));
});
describe('emitter context', () => {
it('should be able to back to the generating span', () => {
const file = new ParseSourceFile('some content', 'a.ts');
const returnSpan = new ParseSourceSpan(
new ParseLocation(file, 100, 10, 10), new ParseLocation(file, 200, 20, 10));
const referenceSpan = new ParseSourceSpan(
new ParseLocation(file, 150, 15, 10), new ParseLocation(file, 175, 17, 10));
const statements = [new o.ClassStmt(
'SomeClass', null, [], [], new o.ClassMethod(null, [], []),
[new o.ClassMethod('someMethod', [new o.FnParam('a', o.INT_TYPE)], [
o.variable('someVar', o.INT_TYPE).set(o.literal(0)).toDeclStmt(),
new o.ReturnStatement(o.variable('someVar', null, referenceSpan), returnSpan)
])])];
const {sourceText, context} =
emitter.emitStatementsAndContext('a.ts', 'a.ts', statements, '/* some preamble /*\n\n');
const spanOf = (text: string, after: number = 0) => {
const location = sourceText.indexOf(text, after);
const {line, col} = calculateLineCol(sourceText, location);
return context.spanOf(line, col);
};
const returnLoc = sourceText.indexOf('return');
expect(spanOf('return someVar')).toEqual(returnSpan, 'return span calculated incorrectly');
expect(spanOf(';', returnLoc)).toEqual(returnSpan, 'reference span calculated incorrectly');
expect(spanOf('someVar', returnLoc))
.toEqual(referenceSpan, 'return span calculated incorrectly');
});
});
});
}
function calculateLineCol(text: string, offset: number): {line: number, col: number} {
const lines = text.split('\n');
let line = 0;
for (let cur = 0; cur < text.length; line++) {
const next = cur + lines[line].length + 1;
if (next > offset) {
return {line, col: offset - cur};
}
cur = next;
}
return {line, col: 0};
}