fix(ivy): correct ngtsc path handling in Windows (#26703)
As it turns out, the usage of path.posix does not unify path handling across operating systems. Instead, canonical-path is used to ensure path handling is consistent, avoiding incorrect paths in Windows. See https://github.com/angular/angular/pull/25862#discussion_r216157914 PR Close #26703
This commit is contained in:
parent
d568d7a352
commit
d0037b22ef
|
@ -17,6 +17,7 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/transform",
|
"//packages/compiler-cli/src/ngtsc/transform",
|
||||||
"//packages/compiler-cli/src/ngtsc/typecheck",
|
"//packages/compiler-cli/src/ngtsc/typecheck",
|
||||||
"@ngdeps//@types/node",
|
"@ngdeps//@types/node",
|
||||||
|
"@ngdeps//canonical-path",
|
||||||
"@ngdeps//typescript",
|
"@ngdeps//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ConstantPool, CssSelector, Expression, R3ComponentMetadata, R3DirectiveMetadata, SelectorMatcher, Statement, TmplAstNode, WrappedNodeExpr, compileComponentFromMetadata, makeBindingParser, parseTemplate} from '@angular/compiler';
|
import {ConstantPool, CssSelector, Expression, R3ComponentMetadata, R3DirectiveMetadata, SelectorMatcher, Statement, TmplAstNode, WrappedNodeExpr, compileComponentFromMetadata, makeBindingParser, parseTemplate} from '@angular/compiler';
|
||||||
import * as path from 'path';
|
import * as path from 'canonical-path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
|
import {ErrorCode, FatalDiagnosticError} from '../../diagnostics';
|
||||||
|
@ -62,7 +62,7 @@ export class ComponentDecoratorHandler implements
|
||||||
throw new FatalDiagnosticError(
|
throw new FatalDiagnosticError(
|
||||||
ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string');
|
ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string');
|
||||||
}
|
}
|
||||||
const url = path.posix.resolve(path.dirname(node.getSourceFile().fileName), templateUrl);
|
const url = path.resolve(path.dirname(node.getSourceFile().fileName), templateUrl);
|
||||||
return this.resourceLoader.preload(url);
|
return this.resourceLoader.preload(url);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -94,7 +94,7 @@ export class ComponentDecoratorHandler implements
|
||||||
throw new FatalDiagnosticError(
|
throw new FatalDiagnosticError(
|
||||||
ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string');
|
ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string');
|
||||||
}
|
}
|
||||||
const url = path.posix.resolve(path.dirname(node.getSourceFile().fileName), templateUrl);
|
const url = path.resolve(path.dirname(node.getSourceFile().fileName), templateUrl);
|
||||||
templateStr = this.resourceLoader.load(url);
|
templateStr = this.resourceLoader.load(url);
|
||||||
} else if (component.has('template')) {
|
} else if (component.has('template')) {
|
||||||
const templateExpr = component.get('template') !;
|
const templateExpr = component.get('template') !;
|
||||||
|
@ -128,7 +128,7 @@ export class ComponentDecoratorHandler implements
|
||||||
// relative path representation.
|
// relative path representation.
|
||||||
const filePath = node.getSourceFile().fileName;
|
const filePath = node.getSourceFile().fileName;
|
||||||
const relativeFilePath = this.rootDirs.reduce<string|undefined>((previous, rootDir) => {
|
const relativeFilePath = this.rootDirs.reduce<string|undefined>((previous, rootDir) => {
|
||||||
const candidate = path.posix.relative(rootDir, filePath);
|
const candidate = path.relative(rootDir, filePath);
|
||||||
if (previous === undefined || candidate.length < previous.length) {
|
if (previous === undefined || candidate.length < previous.length) {
|
||||||
return candidate;
|
return candidate;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,6 +15,7 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/host",
|
"//packages/compiler-cli/src/ngtsc/host",
|
||||||
"//packages/compiler-cli/src/ngtsc/util",
|
"//packages/compiler-cli/src/ngtsc/util",
|
||||||
"@ngdeps//@types/node",
|
"@ngdeps//@types/node",
|
||||||
|
"@ngdeps//canonical-path",
|
||||||
"@ngdeps//typescript",
|
"@ngdeps//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Expression, ExternalExpr, ExternalReference, WrappedNodeExpr} from '@angular/compiler';
|
import {Expression, ExternalExpr, ExternalReference, WrappedNodeExpr} from '@angular/compiler';
|
||||||
import * as path from 'path';
|
import * as path from 'canonical-path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {ClassMemberKind, ReflectionHost} from '../../host';
|
import {ClassMemberKind, ReflectionHost} from '../../host';
|
||||||
|
@ -155,7 +155,7 @@ export class ResolvedReference<T extends ts.Node = ts.Node> extends Reference<T>
|
||||||
// TODO(alxhub): investigate the impact of multiple source roots here.
|
// TODO(alxhub): investigate the impact of multiple source roots here.
|
||||||
// TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support.
|
// TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support.
|
||||||
let relative =
|
let relative =
|
||||||
path.posix.relative(path.dirname(context.fileName), this.node.getSourceFile().fileName)
|
path.relative(path.dirname(context.fileName), this.node.getSourceFile().fileName)
|
||||||
.replace(TS_DTS_JS_EXTENSION, '');
|
.replace(TS_DTS_JS_EXTENSION, '');
|
||||||
|
|
||||||
// path.relative() does not include the leading './'.
|
// path.relative() does not include the leading './'.
|
||||||
|
|
|
@ -15,6 +15,7 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/metadata",
|
"//packages/compiler-cli/src/ngtsc/metadata",
|
||||||
"//packages/compiler-cli/src/ngtsc/util",
|
"//packages/compiler-cli/src/ngtsc/util",
|
||||||
"@ngdeps//@types/node",
|
"@ngdeps//@types/node",
|
||||||
|
"@ngdeps//canonical-path",
|
||||||
"@ngdeps//typescript",
|
"@ngdeps//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'canonical-path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {relativePathBetween} from '../../util/src/path';
|
import {relativePathBetween} from '../../util/src/path';
|
||||||
|
@ -29,8 +29,7 @@ export class FactoryGenerator implements ShimGenerator {
|
||||||
getOriginalSourceOfShim(fileName: string): string|null { return this.map.get(fileName) || null; }
|
getOriginalSourceOfShim(fileName: string): string|null { return this.map.get(fileName) || null; }
|
||||||
|
|
||||||
generate(original: ts.SourceFile, genFilePath: string): ts.SourceFile {
|
generate(original: ts.SourceFile, genFilePath: string): ts.SourceFile {
|
||||||
const relativePathToSource =
|
const relativePathToSource = './' + path.basename(original.fileName).replace(TS_DTS_SUFFIX, '');
|
||||||
'./' + path.posix.basename(original.fileName).replace(TS_DTS_SUFFIX, '');
|
|
||||||
// Collect a list of classes that need to have factory types emitted for them. This list is
|
// Collect a list of classes that need to have factory types emitted for them. This list is
|
||||||
// overly broad as at this point the ts.TypeChecker hasn't been created, and can't be used to
|
// overly broad as at this point the ts.TypeChecker hasn't been created, and can't be used to
|
||||||
// semantically understand which decorated types are actually decorated with Angular decorators.
|
// semantically understand which decorated types are actually decorated with Angular decorators.
|
||||||
|
|
|
@ -10,6 +10,7 @@ ts_library(
|
||||||
]),
|
]),
|
||||||
deps = [
|
deps = [
|
||||||
"//packages:types",
|
"//packages:types",
|
||||||
|
"@ngdeps//canonical-path",
|
||||||
"@ngdeps//typescript",
|
"@ngdeps//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
///<reference types="jasmine"/>
|
///<reference types="jasmine"/>
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'canonical-path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
export function makeProgram(
|
export function makeProgram(
|
||||||
|
@ -93,7 +93,7 @@ export class InMemoryHost implements ts.CompilerHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanonicalFileName(fileName: string): string {
|
getCanonicalFileName(fileName: string): string {
|
||||||
return path.posix.normalize(`${this.getCurrentDirectory()}/${fileName}`);
|
return path.normalize(`${this.getCurrentDirectory()}/${fileName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
useCaseSensitiveFileNames(): boolean { return true; }
|
useCaseSensitiveFileNames(): boolean { return true; }
|
||||||
|
|
|
@ -5,13 +5,13 @@ load("//tools:defaults.bzl", "ts_library")
|
||||||
ts_library(
|
ts_library(
|
||||||
name = "util",
|
name = "util",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
"index.ts",
|
|
||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
]),
|
]),
|
||||||
module_name = "@angular/compiler-cli/src/ngtsc/util",
|
module_name = "@angular/compiler-cli/src/ngtsc/util",
|
||||||
deps = [
|
deps = [
|
||||||
"//packages:types",
|
"//packages:types",
|
||||||
"@ngdeps//@types/node",
|
"@ngdeps//@types/node",
|
||||||
|
"@ngdeps//canonical-path",
|
||||||
"@ngdeps//typescript",
|
"@ngdeps//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
|
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'canonical-path';
|
||||||
|
|
||||||
const TS_DTS_EXTENSION = /(\.d)?\.ts$/;
|
const TS_DTS_EXTENSION = /(\.d)?\.ts$/;
|
||||||
|
|
||||||
export function relativePathBetween(from: string, to: string): string|null {
|
export function relativePathBetween(from: string, to: string): string|null {
|
||||||
let relative = path.posix.relative(path.dirname(from), to).replace(TS_DTS_EXTENSION, '');
|
let relative = path.relative(path.dirname(from), to).replace(TS_DTS_EXTENSION, '');
|
||||||
|
|
||||||
if (relative === '') {
|
if (relative === '') {
|
||||||
return null;
|
return null;
|
||||||
|
@ -25,4 +25,4 @@ export function relativePathBetween(from: string, to: string): string|null {
|
||||||
}
|
}
|
||||||
|
|
||||||
return relative;
|
return relative;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue