refactor(compiler-cli): remove TS bug workaround (#42000)
The TS bug at https://github.com/Microsoft/TypeScript/issues/29300 was fixed in TS 3.3, so the workaround is no longer required. PR Close #42000
This commit is contained in:
parent
500db42a2e
commit
0cb68632c6
|
@ -23,7 +23,6 @@ import {ClassDeclaration, DeclarationNode, Decorator, ReflectionHost, reflectObj
|
|||
import {ComponentScopeReader, LocalModuleScopeRegistry, TypeCheckScopeRegistry} from '../../scope';
|
||||
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerFlags, HandlerPrecedence, ResolveResult} from '../../transform';
|
||||
import {TemplateSourceMapping, TypeCheckContext} from '../../typecheck/api';
|
||||
import {tsSourceMapBug29300Fixed} from '../../util/src/ts_source_map_bug_29300';
|
||||
import {SubsetOfKeys} from '../../util/src/typescript';
|
||||
|
||||
import {ResourceLoader} from './api';
|
||||
|
@ -1231,7 +1230,7 @@ export class ComponentDecoratorHandler implements
|
|||
templateUrl,
|
||||
templateUrlExpression: templateUrlExpr,
|
||||
resolvedTemplateUrl: resourceUrl,
|
||||
potentialSourceMapUrl: sourceMapUrl(resourceUrl),
|
||||
potentialSourceMapUrl: resourceUrl,
|
||||
};
|
||||
} catch (e) {
|
||||
throw this.makeResourceNotFoundError(
|
||||
|
@ -1342,17 +1341,6 @@ function getTemplateRange(templateExpr: ts.Expression) {
|
|||
};
|
||||
}
|
||||
|
||||
function sourceMapUrl(resourceUrl: string): string {
|
||||
if (!tsSourceMapBug29300Fixed()) {
|
||||
// By removing the template URL we are telling the translator not to try to
|
||||
// map the external source file to the generated code, since the version
|
||||
// of TS that is running does not support it.
|
||||
return '';
|
||||
} else {
|
||||
return resourceUrl;
|
||||
}
|
||||
}
|
||||
|
||||
/** Determines if the result of an evaluation is a string array. */
|
||||
function isStringArray(resolvedValue: ResolvedValue): resolvedValue is string[] {
|
||||
return Array.isArray(resolvedValue) && resolvedValue.every(elem => typeof elem === 'string');
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
|
||||
let _tsSourceMapBug29300Fixed: boolean|undefined;
|
||||
|
||||
/**
|
||||
* Test the current version of TypeScript to see if it has fixed the external SourceMap
|
||||
* file bug: https://github.com/Microsoft/TypeScript/issues/29300.
|
||||
*
|
||||
* The bug is fixed in TS 3.3+ but this check avoid us having to rely upon the version number,
|
||||
* and allows us to gracefully fail if the TS version still has the bug.
|
||||
*
|
||||
* We check for the bug by compiling a very small program `a;` and transforming it to `b;`,
|
||||
* where we map the new `b` identifier to an external source file, which has different lines to
|
||||
* the original source file. If the bug is fixed then the output SourceMap should contain
|
||||
* mappings that correspond ot the correct line/col pairs for this transformed node.
|
||||
*
|
||||
* @returns true if the bug is fixed.
|
||||
*/
|
||||
export function tsSourceMapBug29300Fixed() {
|
||||
if (_tsSourceMapBug29300Fixed === undefined) {
|
||||
let writtenFiles: {[filename: string]: string} = {};
|
||||
const sourceFile =
|
||||
ts.createSourceFile('test.ts', 'a;', ts.ScriptTarget.ES2015, true, ts.ScriptKind.TS);
|
||||
const host = {
|
||||
getSourceFile(): ts.SourceFile |
|
||||
undefined {
|
||||
return sourceFile;
|
||||
},
|
||||
fileExists(): boolean {
|
||||
return true;
|
||||
},
|
||||
readFile(): string |
|
||||
undefined {
|
||||
return '';
|
||||
},
|
||||
writeFile(fileName: string, data: string) {
|
||||
writtenFiles[fileName] = data;
|
||||
},
|
||||
getDefaultLibFileName(): string {
|
||||
return '';
|
||||
},
|
||||
getCurrentDirectory(): string {
|
||||
return '';
|
||||
},
|
||||
getDirectories(): string[] {
|
||||
return [];
|
||||
},
|
||||
getCanonicalFileName(): string {
|
||||
return '';
|
||||
},
|
||||
useCaseSensitiveFileNames(): boolean {
|
||||
return true;
|
||||
},
|
||||
getNewLine(): string {
|
||||
return '\n';
|
||||
},
|
||||
};
|
||||
|
||||
const transform = (context: ts.TransformationContext) => {
|
||||
return (node: ts.SourceFile) => ts.visitNode(node, visitor);
|
||||
function visitor(node: ts.Node): ts.Node {
|
||||
if (ts.isIdentifier(node) && node.text === 'a') {
|
||||
const newNode = ts.createIdentifier('b');
|
||||
ts.setSourceMapRange(newNode, {
|
||||
pos: 16,
|
||||
end: 16,
|
||||
source: ts.createSourceMapSource('test.html', 'abc\ndef\nghi\njkl\nmno\npqr')
|
||||
});
|
||||
return newNode;
|
||||
}
|
||||
return ts.visitEachChild(node, visitor, context);
|
||||
}
|
||||
};
|
||||
|
||||
const program = ts.createProgram(['test.ts'], {sourceMap: true}, host);
|
||||
program.emit(sourceFile, undefined, undefined, undefined, {after: [transform]});
|
||||
// The first two mappings in the source map should look like:
|
||||
// [0,1,4,0] col 0 => source file 1, row 4, column 0)
|
||||
// [1,0,0,0] col 1 => source file 1, row 4, column 0)
|
||||
_tsSourceMapBug29300Fixed = /ACIA,CAAA/.test(writtenFiles['test.js.map']);
|
||||
}
|
||||
return _tsSourceMapBug29300Fixed;
|
||||
}
|
|
@ -11,7 +11,6 @@ import {inspect} from 'util';
|
|||
|
||||
import {runInEachFileSystem} from '../../src/ngtsc/file_system/testing';
|
||||
import {loadStandardTestFiles} from '../../src/ngtsc/testing';
|
||||
import {tsSourceMapBug29300Fixed} from '../../src/ngtsc/util/src/ts_source_map_bug_29300';
|
||||
|
||||
import {NgtscTestEnvironment} from './env';
|
||||
import {getMappedSegments, SegmentMapping} from './sourcemap_utils';
|
||||
|
@ -603,91 +602,90 @@ runInEachFileSystem((os) => {
|
|||
});
|
||||
});
|
||||
|
||||
if (tsSourceMapBug29300Fixed()) {
|
||||
describe('External templates (where TS supports source-mapping)', () => {
|
||||
it('should create external template source-mapping', () => {
|
||||
const mappings =
|
||||
compileAndMap('<div>this is a test</div><div>{{ 1 + 2 }}</div>', './dir/test.html');
|
||||
describe('External templates (where TS supports source-mapping)', () => {
|
||||
it('should create external template source-mapping', () => {
|
||||
const mappings =
|
||||
compileAndMap('<div>this is a test</div><div>{{ 1 + 2 }}</div>', './dir/test.html');
|
||||
|
||||
// Creation mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(0, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtext(1, "this is a test")',
|
||||
source: 'this is a test',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
expectMapping(
|
||||
mappings,
|
||||
{generated: 'i0.ɵɵelementEnd()', source: '</div>', sourceUrl: '../dir/test.html'});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(2, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
expectMapping(
|
||||
mappings,
|
||||
{generated: 'i0.ɵɵtext(3)', source: '{{ 1 + 2 }}', sourceUrl: '../dir/test.html'});
|
||||
expectMapping(
|
||||
mappings,
|
||||
{generated: 'i0.ɵɵelementEnd()', source: '</div>', sourceUrl: '../dir/test.html'});
|
||||
|
||||
// Update mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtextInterpolate(1 + 2)',
|
||||
source: '{{ 1 + 2 }}',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
// Creation mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(0, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtext(1, "this is a test")',
|
||||
source: 'this is a test',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
expectMapping(
|
||||
mappings,
|
||||
{generated: 'i0.ɵɵelementEnd()', source: '</div>', sourceUrl: '../dir/test.html'});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(2, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
expectMapping(
|
||||
mappings,
|
||||
{generated: 'i0.ɵɵtext(3)', source: '{{ 1 + 2 }}', sourceUrl: '../dir/test.html'});
|
||||
expectMapping(
|
||||
mappings,
|
||||
{generated: 'i0.ɵɵelementEnd()', source: '</div>', sourceUrl: '../dir/test.html'});
|
||||
|
||||
it('should create correct mappings when templateUrl is in a different rootDir', () => {
|
||||
const mappings = compileAndMap(
|
||||
'<div>this is a test</div><div>{{ 1 + 2 }}</div>', 'extraRootDir/test.html');
|
||||
|
||||
// Creation mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(0, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtext(1, "this is a test")',
|
||||
source: 'this is a test',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementEnd()',
|
||||
source: '</div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(2, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtext(3)',
|
||||
source: '{{ 1 + 2 }}',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementEnd()',
|
||||
source: '</div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
|
||||
// Update mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtextInterpolate(1 + 2)',
|
||||
source: '{{ 1 + 2 }}',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
// Update mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtextInterpolate(1 + 2)',
|
||||
source: '{{ 1 + 2 }}',
|
||||
sourceUrl: '../dir/test.html'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('should create correct mappings when templateUrl is in a different rootDir', () => {
|
||||
const mappings = compileAndMap(
|
||||
'<div>this is a test</div><div>{{ 1 + 2 }}</div>', 'extraRootDir/test.html');
|
||||
|
||||
// Creation mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(0, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtext(1, "this is a test")',
|
||||
source: 'this is a test',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementEnd()',
|
||||
source: '</div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementStart(2, "div")',
|
||||
source: '<div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtext(3)',
|
||||
source: '{{ 1 + 2 }}',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵelementEnd()',
|
||||
source: '</div>',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
|
||||
// Update mode
|
||||
expectMapping(mappings, {
|
||||
generated: 'i0.ɵɵtextInterpolate(1 + 2)',
|
||||
source: '{{ 1 + 2 }}',
|
||||
sourceUrl: '../extraRootDir/test.html'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function compileAndMap(template: string, templateUrl: string|null = null) {
|
||||
const templateConfig = templateUrl ? `templateUrl: '${templateUrl}'` :
|
||||
|
|
Loading…
Reference in New Issue