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:
JoostK 2018-10-24 18:39:29 +02:00 committed by Kara Erickson
parent d568d7a352
commit d0037b22ef
10 changed files with 18 additions and 15 deletions

View File

@ -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",
], ],
) )

View File

@ -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 {

View File

@ -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",
], ],
) )

View File

@ -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 './'.

View File

@ -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",
], ],
) )

View File

@ -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.

View File

@ -10,6 +10,7 @@ ts_library(
]), ]),
deps = [ deps = [
"//packages:types", "//packages:types",
"@ngdeps//canonical-path",
"@ngdeps//typescript", "@ngdeps//typescript",
], ],
) )

View File

@ -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; }

View File

@ -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",
], ],
) )

View File

@ -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;