Skip to content
Closed
7 changes: 5 additions & 2 deletions Jakefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ var harnessSources = [
"services/preProcessFile.ts",
"services/patternMatcher.ts",
"versionCache.ts",
"convertToBase64.ts"
"convertToBase64.ts",
"expandFiles.ts"
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
Expand Down Expand Up @@ -505,7 +506,9 @@ function cleanTestDirs() {
// used to pass data from jake command line directly to run.js
function writeTestConfigFile(tests, testConfigFile) {
console.log('Running test(s): ' + tests);
var testConfigContents = '{\n' + '\ttest: [\'' + tests + '\']\n}';
var testConfigContents = JSON.stringify({
"test": [tests]
});
fs.writeFileSync('test.config', testConfigContents);
}

Expand Down
462 changes: 447 additions & 15 deletions src/compiler/commandLineParser.ts

Large diffs are not rendered by default.

58 changes: 58 additions & 0 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,19 @@ module ts {
if (b === undefined) return Comparison.GreaterThan;
return a < b ? Comparison.LessThan : Comparison.GreaterThan;
}

export function compareStrings(a: string, b: string, ignoreCase?: boolean) {
if (a === b) return Comparison.EqualTo;
if (a === undefined) return Comparison.LessThan;
if (b === undefined) return Comparison.GreaterThan;
if (ignoreCase) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a === b) return Comparison.EqualTo;
}

return a < b ? Comparison.LessThan : Comparison.GreaterThan;
}

function getDiagnosticFileName(diagnostic: Diagnostic): string {
return diagnostic.file ? diagnostic.file.fileName : undefined;
Expand Down Expand Up @@ -643,7 +656,48 @@ module ts {
if (path1.charAt(path1.length - 1) === directorySeparator) return path1 + path2;
return path1 + directorySeparator + path2;
}

/**
* Removes a trailing directory separator from a path.
* @param path The path.
*/
export function removeTrailingDirectorySeparator(path: string) {
if (path.charAt(path.length - 1) === directorySeparator) {
return path.substr(0, path.length - 1);
}

return path;
}

/**
* Adds a trailing directory separator to a path, if it does not already have one.
* @param path The path.
*/
export function ensureTrailingDirectorySeparator(path: string) {
if (path.charAt(path.length - 1) !== directorySeparator) {
return path + directorySeparator;
}

return path;
}

export function comparePaths(a: string, b: string, currentDirectory: string, ignoreCase?: boolean) {
if (a === b) return Comparison.EqualTo;
if (a === undefined) return Comparison.LessThan;
if (b === undefined) return Comparison.GreaterThan;
a = removeTrailingDirectorySeparator(a);
b = removeTrailingDirectorySeparator(b);
let aComponents = getNormalizedPathComponents(a, currentDirectory);
let bComponents = getNormalizedPathComponents(b, currentDirectory);
let sharedLength = Math.min(aComponents.length, bComponents.length);
for (let i = 0; i < sharedLength; ++i) {
let result = compareStrings(aComponents[i], bComponents[i], ignoreCase);
if (result) return result;
}

return compareValues(aComponents.length, bComponents.length);
}

export function fileExtensionIs(path: string, extension: string): boolean {
let pathLen = path.length;
let extLen = extension.length;
Expand All @@ -654,6 +708,10 @@ module ts {
* List of supported extensions in order of file resolution precedence.
*/
export const supportedExtensions = [".ts", ".d.ts"];

export function hasSupportedFileExtension(file: string) {
return forEach(supportedExtensions, extension => fileExtensionIs(file, extension));
}

const extensionsToRemove = [".d.ts", ".ts", ".js"];
export function removeFileExtension(path: string): string {
Expand Down
1 change: 1 addition & 0 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ module ts {
Loop_contains_block_scoped_variable_0_referenced_by_a_function_in_the_loop_This_is_only_supported_in_ECMAScript_6_or_higher: { code: 4091, category: DiagnosticCategory.Error, key: "Loop contains block-scoped variable '{0}' referenced by a function in the loop. This is only supported in ECMAScript 6 or higher." },
The_current_host_does_not_support_the_0_option: { code: 5001, category: DiagnosticCategory.Error, key: "The current host does not support the '{0}' option." },
Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: DiagnosticCategory.Error, key: "Cannot find the common subdirectory path for the input files." },
File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0: { code: 5011, category: DiagnosticCategory.Error, key: "File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'." },
Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" },
Unsupported_file_encoding: { code: 5013, category: DiagnosticCategory.Error, key: "Unsupported file encoding." },
Failed_to_parse_file_0_Colon_1: { code: 5014, category: DiagnosticCategory.Error, key: "Failed to parse file '{0}': {1}." },
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,10 @@
"category": "Error",
"code": 5009
},
"File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'.": {
"category": "Error",
"code": 5011
},
"Cannot read file '{0}': {1}": {
"category": "Error",
"code": 5012
Expand Down
14 changes: 13 additions & 1 deletion src/compiler/sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module ts {
getExecutingFilePath(): string;
getCurrentDirectory(): string;
readDirectory(path: string, extension?: string): string[];
readDirectoryFlat(path: string): string[];
getMemoryUsage?(): number;
exit(exitCode?: number): void;
}
Expand Down Expand Up @@ -135,6 +136,11 @@ module ts {
}
}
}

function readDirectoryFlat(path: string): string[] {
var folder = fso.GetFolder(path || ".");
return [...getNames(folder.files), ...getNames(folder.subfolders)];
}

return {
args,
Expand Down Expand Up @@ -166,6 +172,7 @@ module ts {
return new ActiveXObject("WScript.Shell").CurrentDirectory;
},
readDirectory,
readDirectoryFlat,
exit(exitCode?: number): void {
try {
WScript.Quit(exitCode);
Expand Down Expand Up @@ -246,6 +253,10 @@ module ts {
}
}
}

function readDirectoryFlat(path: string): string[] {
return _fs.readdirSync(path || ".").sort();
}

return {
args: process.argv.slice(2),
Expand Down Expand Up @@ -277,7 +288,7 @@ module ts {
return _path.resolve(path);
},
fileExists(path: string): boolean {
return _fs.existsSync(path);
return _fs.existsSync(path) && _fs.statSync(path).isFile();
},
directoryExists(path: string) {
return _fs.existsSync(path) && _fs.statSync(path).isDirectory();
Expand All @@ -294,6 +305,7 @@ module ts {
return process.cwd();
},
readDirectory,
readDirectoryFlat,
getMemoryUsage() {
if (global.gc) {
global.gc();
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ module ts {
setCachedProgram(compileResult.program);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
}

function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError ?: (message: string) => void) {
// Return existing SourceFile object if one is available
if (cachedProgram) {
Expand Down
22 changes: 21 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1027,15 +1027,35 @@ module ts {
// This field should never be used directly to obtain line map, use getLineMap function instead.
/* @internal */ lineMap: number[];
}

export interface ScriptReferenceHost {
getCompilerOptions(): CompilerOptions;
getSourceFile(fileName: string): SourceFile;
getCurrentDirectory(): string;
}

export interface ParseConfigHost {
useCaseSensitiveFileNames: boolean;

readDirectory(rootDir: string, extension: string): string[];

/**
* Gets a value indicating whether the specified path exists.
* @param path The path to test.
*/
fileExists(path: string): boolean;

/**
* Gets a value indicating whether the specified path exists and is a directory.
* @param path The path to test.
*/
directoryExists(path: string): boolean;

/**
* Reads the files in the directory.
* @param path The directory path.
*/
readDirectoryFlat(path: string): string[];
}

export interface WriteFileCallback {
Expand Down
3 changes: 3 additions & 0 deletions src/harness/external/chai.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,8 @@ declare module chai {
function isFalse(value: any, message?: string): void;
function isNull(value: any, message?: string): void;
function isNotNull(value: any, message?: string): void;
function deepEqual(actual: any, expected: any, message?: string): void;
function notDeepEqual(actual: any, expected: any, message?: string): void;
function lengthOf(object: any[], length: number, message?: string): void;
}
}
8 changes: 8 additions & 0 deletions src/harness/harnessLanguageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ module Harness.LanguageService {
readDirectory(rootDir: string, extension: string): string {
throw new Error("NYI");
}

readDirectoryFlat(path: string): string {
throw new Error("NYI");
}

log(s: string): void { this.nativeHost.log(s); }
trace(s: string): void { this.nativeHost.trace(s); }
Expand Down Expand Up @@ -537,6 +541,10 @@ module Harness.LanguageService {
throw new Error("Not implemented Yet.");
}

readDirectoryFlat(path: string): string[] {
throw new Error("Not implemented Yet.");
}

watchFile(fileName: string, callback: (fileName: string) => void): ts.FileWatcher {
return { close() { } };
}
Expand Down
21 changes: 16 additions & 5 deletions src/harness/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@ var testConfigFile =
Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) :
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '');

var unitTestsRequested = false;

if (testConfigFile !== '') {
// TODO: not sure why this is crashing mocha
//var testConfig = JSON.parse(testConfigRaw);
var testConfig = testConfigFile.match(/test:\s\['(.*)'\]/);
var options = testConfig ? [testConfig[1]] : [];
var options: string[];
try {
let testConfigJson = JSON.parse(testConfigFile);
options = testConfigJson.test instanceof Array ? testConfigJson.test : [];
}
catch (e) {
let testConfig = testConfigFile.match(/test:\s\['(.*)'\]/);
options = testConfig ? [testConfig[1]] : [];
}

for (var i = 0; i < options.length; i++) {
switch (options[i]) {
case 'compiler':
Expand Down Expand Up @@ -73,11 +81,14 @@ if (testConfigFile !== '') {
case 'test262':
runners.push(new Test262BaselineRunner());
break;
case 'unit':
unitTestsRequested = true;
break;
}
}
}

if (runners.length === 0) {
if (runners.length === 0 && !unitTestsRequested) {
// compiler
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
Expand Down
46 changes: 45 additions & 1 deletion src/services/shims.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ module ts {
export interface CoreServicesShimHost extends Logger {
/** Returns a JSON-encoded value of the type: string[] */
readDirectory(rootDir: string, extension: string): string;
readDirectoryFlat?(path: string): string;
useCaseSensitiveFileNames?: boolean;
fileExists?(path: string): boolean;
directoryExists?(path: string): boolean;
}

///
Expand Down Expand Up @@ -335,13 +339,53 @@ module ts {

export class CoreServicesShimHostAdapter implements ParseConfigHost {

public useCaseSensitiveFileNames: boolean;

constructor(private shimHost: CoreServicesShimHost) {
if (typeof shimHost.useCaseSensitiveFileNames === "boolean") {
this.useCaseSensitiveFileNames = shimHost.useCaseSensitiveFileNames;
}
else if (sys) {
this.useCaseSensitiveFileNames = sys.useCaseSensitiveFileNames;
}
else {
this.useCaseSensitiveFileNames = true;
}
}

public readDirectory(rootDir: string, extension: string): string[] {
var encoded = this.shimHost.readDirectory(rootDir, extension);
return JSON.parse(encoded);
}

public readDirectoryFlat(path: string): string[] {
path = normalizePath(path);
path = ensureTrailingDirectorySeparator(path);
if (this.shimHost.readDirectoryFlat) {
var encoded = this.shimHost.readDirectoryFlat(path);
return JSON.parse(encoded);
}

return sys ? sys.readDirectoryFlat(path): [];
}

public fileExists(path: string): boolean {
path = normalizePath(path);
if (this.shimHost.fileExists) {
return this.shimHost.fileExists(path);
}

return sys ? sys.fileExists(path) : undefined;
}

public directoryExists(path: string): boolean {
path = normalizePath(path);
if (this.shimHost.directoryExists) {
return this.shimHost.directoryExists(path);
}

return sys ? sys.directoryExists(path) : undefined;
}
}

function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): any {
Expand Down
Loading