feat(ivy): add support for windows concrete types for paths (#28752)

This commit introduces support for the windows paths in the new concrete types mechanism that was introduced in this PR https://github.com/angular/angular/pull/28523

Normalized posix paths that start with either a `/` or `C:/` are considered to be an absolute path.

Note: `C:/` is used as a reference, as other drive letters are also supported.

Fixes #28754

PR Close #28752
This commit is contained in:
Alan Agius 2019-02-16 09:30:39 +01:00 committed by Ben Lesh
parent 034de06ab1
commit 34bdebcdd2
4 changed files with 22 additions and 5 deletions

View File

@ -17,6 +17,8 @@ import {stripExtension} from './util';
/**
* A path that's relative to the logical root of a TypeScript project (one of the project's
* rootDirs).
*
* Paths in the type system use POSIX format.
*/
export type LogicalProjectPath = BrandedPath<'LogicalProjectPath'>;

View File

@ -8,7 +8,7 @@
import * as ts from 'typescript';
import {normalizeSeparators} from './util';
import {isAbsolutePath, normalizeSeparators} from './util';
/**
* A `string` representing a specific type of path, with a particular brand `B`.
@ -41,7 +41,7 @@ export const AbsoluteFsPath = {
*/
from: function(str: string): AbsoluteFsPath {
const normalized = normalizeSeparators(str);
if (!normalized.startsWith('/')) {
if (!isAbsolutePath(normalized)) {
throw new Error(`Internal Error: AbsoluteFsPath.from(${str}): path is not absolute`);
}
return normalized as AbsoluteFsPath;
@ -73,7 +73,7 @@ export const PathSegment = {
*/
fromFsPath: function(str: string): PathSegment {
const normalized = normalizeSeparators(str);
if (normalized.startsWith('/')) {
if (isAbsolutePath(normalized)) {
throw new Error(`Internal Error: PathSegment.from(${str}): path is not relative`);
}
return normalized as PathSegment;

View File

@ -9,9 +9,10 @@
// TODO(alxhub): Unify this file with `util/src/path`.
const TS_DTS_JS_EXTENSION = /(?:\.d)?\.ts$|\.js$/;
const ABSOLUTE_PATH = /^([a-zA-Z]\:\/|\/)/;
/**
* Convert Windows-style paths to POSIX paths.
* Convert Windows-style separators to POSIX separators.
*/
export function normalizeSeparators(path: string): string {
// TODO: normalize path only for OS that need it.
@ -24,3 +25,11 @@ export function normalizeSeparators(path: string): string {
export function stripExtension(path: string): string {
return path.replace(TS_DTS_JS_EXTENSION, '');
}
/**
* Returns true if the normalized path is an absolute path.
*/
export function isAbsolutePath(path: string): boolean {
// TODO: use regExp based on OS in the future
return ABSOLUTE_PATH.test(path);
}

View File

@ -10,10 +10,16 @@ import {AbsoluteFsPath} from '../src/types';
describe('path types', () => {
describe('AbsoluteFsPath', () => {
it('should not throw when creating one from a non-absolute path',
it('should not throw when creating one from an absolute path',
() => { expect(AbsoluteFsPath.from('/test.txt')).toEqual('/test.txt'); });
it('should not throw when creating one from a windows absolute path',
() => { expect(AbsoluteFsPath.from('C:\\test.txt')).toEqual('C:/test.txt'); });
it('should not throw when creating one from a windows absolute path with POSIX separators',
() => { expect(AbsoluteFsPath.from('C:/test.txt')).toEqual('C:/test.txt'); });
it('should throw when creating one from a non-absolute path',
() => { expect(() => AbsoluteFsPath.from('test.txt')).toThrow(); });
it('should support windows drive letters',
() => { expect(AbsoluteFsPath.from('D:\\foo\\test.txt')).toEqual('D:/foo/test.txt'); });
it('should convert Windows path separators to POSIX separators',
() => { expect(AbsoluteFsPath.from('\\foo\\test.txt')).toEqual('/foo/test.txt'); });
});