2016-06-23 12:47:54 -04:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. 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
|
|
|
|
*/
|
|
|
|
|
2016-08-30 21:07:40 -04:00
|
|
|
import {ReflectorHostContext} from '@angular/compiler-cli/src/reflector_host';
|
2016-06-09 17:51:53 -04:00
|
|
|
import * as ts from 'typescript';
|
|
|
|
|
|
|
|
export type Entry = string | Directory;
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
export interface Directory { [name: string]: Entry; }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
|
|
|
export class MockContext implements ReflectorHostContext {
|
2016-06-08 19:38:52 -04:00
|
|
|
constructor(public currentDirectory: string, private files: Entry) {}
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
fileExists(fileName: string): boolean { return typeof this.getEntry(fileName) === 'string'; }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-07-21 20:12:00 -04:00
|
|
|
directoryExists(path: string): boolean { return typeof this.getEntry(path) === 'object'; }
|
2016-07-13 14:15:23 -04:00
|
|
|
|
|
|
|
readFile(fileName: string): string|undefined {
|
2016-11-12 08:08:58 -05:00
|
|
|
const data = this.getEntry(fileName);
|
2016-06-08 19:38:52 -04:00
|
|
|
if (typeof data === 'string') {
|
2016-06-09 17:51:53 -04:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
writeFile(fileName: string, data: string): void {
|
2016-11-12 08:08:58 -05:00
|
|
|
const parts = fileName.split('/');
|
|
|
|
const name = parts.pop();
|
|
|
|
const entry = this.getEntry(parts);
|
2016-06-08 19:38:52 -04:00
|
|
|
if (entry && typeof entry !== 'string') {
|
2016-06-09 17:51:53 -04:00
|
|
|
entry[name] = data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
assumeFileExists(fileName: string): void { this.writeFile(fileName, ''); }
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
getEntry(fileName: string|string[]): Entry|undefined {
|
|
|
|
let parts = typeof fileName === 'string' ? fileName.split('/') : fileName;
|
2016-06-09 17:51:53 -04:00
|
|
|
if (parts[0]) {
|
|
|
|
parts = this.currentDirectory.split('/').concat(parts);
|
|
|
|
}
|
|
|
|
parts.shift();
|
|
|
|
parts = normalize(parts);
|
|
|
|
let current = this.files;
|
|
|
|
while (parts.length) {
|
2016-11-12 08:08:58 -05:00
|
|
|
const part = parts.shift();
|
2016-06-08 19:38:52 -04:00
|
|
|
if (typeof current === 'string') {
|
2016-06-09 17:51:53 -04:00
|
|
|
return undefined;
|
|
|
|
}
|
2016-11-12 08:08:58 -05:00
|
|
|
const next = (<Directory>current)[part];
|
2016-06-09 17:51:53 -04:00
|
|
|
if (next === undefined) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
current = next;
|
|
|
|
}
|
|
|
|
return current;
|
|
|
|
}
|
2016-08-30 21:07:40 -04:00
|
|
|
|
|
|
|
getDirectories(path: string): string[] {
|
|
|
|
const dir = this.getEntry(path);
|
|
|
|
if (typeof dir !== 'object') {
|
|
|
|
return [];
|
|
|
|
} else {
|
|
|
|
return Object.keys(dir).filter(key => typeof dir[key] === 'object');
|
|
|
|
}
|
|
|
|
}
|
2016-06-09 17:51:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function normalize(parts: string[]): string[] {
|
2016-11-12 08:08:58 -05:00
|
|
|
const result: string[] = [];
|
2016-06-09 17:51:53 -04:00
|
|
|
while (parts.length) {
|
2016-11-12 08:08:58 -05:00
|
|
|
const part = parts.shift();
|
2016-06-09 17:51:53 -04:00
|
|
|
switch (part) {
|
2016-06-08 19:38:52 -04:00
|
|
|
case '.':
|
|
|
|
break;
|
|
|
|
case '..':
|
|
|
|
result.pop();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
result.push(part);
|
2016-06-09 17:51:53 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class MockCompilerHost implements ts.CompilerHost {
|
2016-06-08 19:38:52 -04:00
|
|
|
constructor(private context: MockContext) {}
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
fileExists(fileName: string): boolean { return this.context.fileExists(fileName); }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
readFile(fileName: string): string { return this.context.readFile(fileName); }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
directoryExists(directoryName: string): boolean {
|
|
|
|
return this.context.directoryExists(directoryName);
|
|
|
|
}
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
getSourceFile(
|
|
|
|
fileName: string, languageVersion: ts.ScriptTarget,
|
|
|
|
onError?: (message: string) => void): ts.SourceFile {
|
2016-11-12 08:08:58 -05:00
|
|
|
const sourceText = this.context.readFile(fileName);
|
2016-06-09 17:51:53 -04:00
|
|
|
if (sourceText) {
|
|
|
|
return ts.createSourceFile(fileName, sourceText, languageVersion);
|
|
|
|
} else {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getDefaultLibFileName(options: ts.CompilerOptions): string {
|
|
|
|
return ts.getDefaultLibFileName(options);
|
|
|
|
}
|
|
|
|
|
2016-07-13 14:15:23 -04:00
|
|
|
writeFile: ts.WriteFileCallback = (fileName, text) => { this.context.writeFile(fileName, text); }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
|
|
|
getCurrentDirectory(): string {
|
|
|
|
return this.context.currentDirectory;
|
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
getCanonicalFileName(fileName: string): string { return fileName; }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
useCaseSensitiveFileNames(): boolean { return false; }
|
2016-06-09 17:51:53 -04:00
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
getNewLine(): string { return '\n'; }
|
2016-08-30 21:07:40 -04:00
|
|
|
|
|
|
|
getDirectories(path: string): string[] { return this.context.getDirectories(path); }
|
2016-06-09 17:51:53 -04:00
|
|
|
}
|