Add snapshot of compiler sources

This commit is contained in:
Mohamed Hegazy 2014-07-12 16:04:16 -07:00
parent 99ec3a9688
commit 214df64e28
14390 changed files with 671305 additions and 0 deletions

66
.gitignore vendored Normal file
View File

@ -0,0 +1,66 @@
node_modules/
built/
bin/wrapped_tsc.js
tests/cases/*.js
tests/cases/*/*.js
tests/cases/*/*/*.js
tests/cases/*/*/*/*.js
tests/cases/*/*/*/*/*.js
tests/cases/*.js.map
tests/cases/*/*.js.map
tests/cases/*/*/*.js.map
tests/cases/*/*/*/*.js.map
tests/cases/*/*/*/*/*.js.map
tests/cases/rwc/*
tests/cases/perf/*
!tests/cases/webharness/compilerToString.js
tests/runners/*.js
tests/runners/*/*.js
tests/runners/rwc/*
!tests/runners/rwc/rwcRunner.ts
!tests/runners/rwc/loggedIO.ts
diff-*.html
test-args.txt
*.suo
~*.docx
tests/baselines/local/*
tests/baselines/reference/projectOutput/
tests/services/baselines/local/*
tests/baselines/prototyping/local/*
tests/baselines/rwc/*
tests/services/baselines/prototyping/local/*
tests/services/browser/typescriptServices.js
scripts/processDiagnosticMessages.d.ts
scripts/processDiagnosticMessages.js
src/compiler/*.js
src/compiler/syntax/wrapped_SyntaxGenerator.js
src/compiler/syntax/SyntaxGenerator.js
src/compiler/syntax/SyntaxGenerator.d.ts
src/compiler/prototype/*.js
src/services/*.js
src/services/*/*.js
src/harness/*.js
src/prototype/*.js
src/prototype/*/*.js
baseline-report.html
fidelity-report.html
rwc-report.html
*.swp
build.json
monaco.editor.json
samples/win8/encyclopedia/Encyclopedia/js/*.js
samples/win8/encyclopedia/Encyclopedia/js/*.js.map
samples/win8/encyclopedia/Encyclopedia/bin/
samples/win8/encyclopedia/Encyclopedia/bld/
samples/win8/encyclopedia/Encyclopedia/Encyclopedia.jsproj.user
*.actual
tests/Fidelity/*.d.ts
tests/Fidelity/*.js
tests/cases/webharness/*.d.ts
tests/webhost/*.d.ts
tests/webhost/webtsc.js
tests/*.js
tests/*.d.ts
*.config
scripts/debug.bat
scripts/run.bat

12
.npmignore Normal file
View File

@ -0,0 +1,12 @@
built
doc
samples
src
tests
typings
bin/winjs.d.ts
bin/winrt.d.ts
bin/*.bat
bin/jquery.d.ts
bin/typescriptServices.js
Jakefile

15
CopyrightNotice.txt Normal file
View File

@ -0,0 +1,15 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

443
Jakefile Normal file
View File

@ -0,0 +1,443 @@
// This file contains the build logic for the public repo
var fs = require("fs");
var path = require("path");
// Variables
var compilerDirectory = "src/compiler/";
var servicesDirectory = "src/services/";
var harnessDirectory = "src/harness/";
var libraryDirectory = "src/lib/";
var scriptsDirectory = "scripts/"
var builtDirectory = "built/";
var builtLocalDirectory = "built/local/";
var LKGDirectory = "bin/";
var copyright = "CopyrightNotice.txt";
var thirdParty = "ThirdPartyNoticeText.txt";
var compilerSources = [
"core.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"binder.ts",
"checker.ts",
"emitter.ts",
"commandLineParser.ts",
"tc.ts",
"diagnosticInformationMap.generated.ts"
].map(function (f) {
return path.join(compilerDirectory, f);
});
var servicesSources = [
"core.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"binder.ts",
"checker.ts",
"emitter.ts"
].map(function (f) {
return path.join(compilerDirectory, f);
}).concat([
"services.ts",
"shims.ts",
].map(function (f) {
return path.join(servicesDirectory, f);
}));
var harnessSources = [
"harness.ts",
"sourceMapRecorder.ts",
// TODO Re-enable
// "harnessLanguageService.ts",
// "fourslash.ts",
"runner.ts",
"external/json2.ts",
"runnerbase.ts",
"compilerRunner.ts",
"typeWriter.ts",
// TODO Re-enable fourslash and project tests
// "fourslashRunner.ts",
"projectsRunner.ts",
"unittestrunner.ts",
"rwcRunner.ts",
].map(function (f) {
return path.join(harnessDirectory, f);
});
var librarySourceMap = [
{ target: "lib.core.d.ts", sources: ["core.d.ts"] },
{ target: "lib.dom.d.ts", sources: ["importcore.d.ts", "extensions.d.ts", "dom.generated.d.ts"], },
{ target: "lib.webworker.d.ts", sources: ["importcore.d.ts", "extensions.d.ts", "webworker.generated.d.ts"], },
{ target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"], },
{ target: "lib.d.ts", sources: ["core.d.ts", "extensions.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"], },
];
var libraryTargets = librarySourceMap.map(function (f) {
return path.join(builtLocalDirectory, f.target);
});
// Prepends the contents of prefixFile to destinationFile
function prependFile(prefixFile, destinationFile) {
if (!fs.existsSync(prefixFile)) {
fail(prefixFile + " does not exist!");
}
if (!fs.existsSync(destinationFile)) {
fail(destinationFile + " failed to be created!");
}
var temp = "temptemp";
jake.cpR(prefixFile, temp, {silent: true});
fs.appendFileSync(temp, fs.readFileSync(destinationFile));
fs.renameSync(temp, destinationFile);
}
// concatenate a list of sourceFiles to a destinationFile
function concatenateFiles(destinationFile, sourceFiles) {
var temp = "temptemp";
// Copy the first file to temp
if (!fs.existsSync(sourceFiles[0])) {
fail(sourceFiles[0] + " does not exist!");
}
jake.cpR(sourceFiles[0], temp, {silent: true});
// append all files in sequence
for (var i = 1; i < sourceFiles.length; i++) {
if (!fs.existsSync(sourceFiles[i])) {
fail(sourceFiles[i] + " does not exist!");
}
fs.appendFileSync(temp, fs.readFileSync(sourceFiles[i]));
}
// Move the file to the final destination
fs.renameSync(temp, destinationFile);
}
var useDebugMode = false;
/* Compiles a file from a list of sources
* @param outFile: the target file name
* @param sources: an array of the names of the source files
* @param prereqs: prerequisite tasks to compiling the file
* @param prefixes: a list of files to prepend to the target file
* @param useBuiltCompiler: true to use the built compiler, false to use the LKG
* @param noOutFile: true to compile without using --out
*/
function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile) {
file(outFile, prereqs, function() {
var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory;
var compilerFilename = "tc.js";
var options = "-removeComments --module commonjs -noImplicitAny "; //" -propagateEnumConstants "
var cmd = (process.env.host || process.env.TYPESCRIPT_HOST || "node") + " " + dir + compilerFilename + " " + options + " ";
if (useDebugMode) {
cmd = cmd + " " + path.join(harnessDirectory, "external/es5compat.ts") + " " + path.join(harnessDirectory, "external/json2.ts") + " ";
}
cmd = cmd + sources.join(" ") + (!noOutFile ? " -out " + outFile : "");
if (useDebugMode) {
cmd = cmd + " -sourcemap -mapRoot file:///" + path.resolve(path.dirname(outFile));
}
console.log(cmd + "\n");
var ex = jake.createExec([cmd]);
// Add listeners for output and error
ex.addListener("stdout", function(output) {
process.stdout.write(output);
});
ex.addListener("stderr", function(error) {
process.stderr.write(error);
});
ex.addListener("cmdEnd", function() {
if (!useDebugMode && prefixes && fs.existsSync(outFile)) {
for (var i in prefixes) {
prependFile(prefixes[i], outFile);
}
}
complete();
});
ex.addListener("error", function() {
fs.unlinkSync(outFile);
console.log("Compilation of " + outFile + " unsuccessful");
});
ex.run();
}, {async: true});
}
// Prerequisite task for built directory and library typings
directory(builtLocalDirectory);
for (var i in libraryTargets) {
(function (i) {
var entry = librarySourceMap[i];
var target = libraryTargets[i];
var sources = [copyright].concat(entry.sources.map(function (s) {
return path.join(libraryDirectory, s);
}));
file(target, [builtLocalDirectory].concat(sources), function() {
concatenateFiles(target, sources);
});
})(i);
}
// Lib target to build the library files
desc("Builds the library targets");
task("lib", libraryTargets);
// Generate diagnostics
var processDiagnosticMessagesJs = path.join(scriptsDirectory, "processDiagnosticMessages.js");
var processDiagnosticMessagesTs = path.join(scriptsDirectory, "processDiagnosticMessages.ts");
var diagnosticMessagesJson = path.join(compilerDirectory, "diagnosticMessages.json");
var diagnosticInfoMapTs = path.join(compilerDirectory, "diagnosticInformationMap.generated.ts");
// processDiagnosticMessages script
compileFile(processDiagnosticMessagesJs,
[processDiagnosticMessagesTs],
[processDiagnosticMessagesTs],
[],
false);
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
var cmd = "node " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
console.log(cmd);
var ex = jake.createExec([cmd]);
// Add listeners for output and error
ex.addListener("stdout", function(output) {
process.stdout.write(output);
});
ex.addListener("stderr", function(error) {
process.stderr.write(error);
});
ex.addListener("cmdEnd", function() {
complete();
});
ex.run();
}, {async: true})
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
task("generate-diagnostics", [diagnosticInfoMapTs])
// Local target to build the compiler and services
var tcFile = path.join(builtLocalDirectory, "tc.js");
compileFile(tcFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false);
var tcServicesFile = path.join(builtLocalDirectory, "services.js");
compileFile(tcServicesFile, servicesSources, [builtLocalDirectory, copyright].concat(servicesSources), [copyright], /*useBuiltCompiler:*/ true);
// Local target to build the compiler and services
desc("Builds the full compiler and services");
task("local", ["generate-diagnostics", "lib", tcFile, tcServicesFile]);
// Local target to build the compiler and services
desc("Emit debug mode files with sourcemaps");
task("debug", function() {
useDebugMode = true;
});
// Set the default task to "local"
task("default", ["local"]);
// Cleans the built directory
desc("Cleans the compiler output, declare files, and tests");
task("clean", function() {
jake.rmRf(builtDirectory);
});
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
desc("Makes a new LKG out of the built js files");
task("LKG", libraryTargets, function() {
var expectedFiles = [tcFile, tcServicesFile].concat(libraryTargets);
var missingFiles = expectedFiles.filter(function (f) {
return !fs.existsSync(f);
});
if (missingFiles.length > 0) {
fail("Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory +
". The following files are missing:\n" + missingFiles.join("\n"));
}
// Copy all the targets into the LKG directory
jake.mkdirP(LKGDirectory);
for (i in expectedFiles) {
jake.cpR(expectedFiles[i], LKGDirectory);
}
//var resourceDirectories = fs.readdirSync(builtLocalResourcesDirectory).map(function(p) { return path.join(builtLocalResourcesDirectory, p); });
//resourceDirectories.map(function(d) {
// jake.cpR(d, LKGResourcesDirectory);
//});
});
// Test directory
directory(builtLocalDirectory);
// Task to build the tests infrastructure using the built compiler
var run = path.join(builtLocalDirectory, "run.js");
compileFile(run, harnessSources, [builtLocalDirectory, tcFile].concat(libraryTargets).concat(harnessSources), [], /*useBuiltCompiler:*/ true);
var localBaseline = "tests/baselines/local/";
var refBaseline = "tests/baselines/reference/";
var localRwcBaseline = "tests/baselines/rwc/local/";
var refRwcBaseline = "tests/baselines/rwc/reference/";
desc("Builds the test infrastructure using the built compiler");
task("tests", ["local", run].concat(libraryTargets));
function exec(cmd) {
var ex = jake.createExec([cmd]);
// Add listeners for output and error
ex.addListener("stdout", function(output) {
process.stdout.write(output);
});
ex.addListener("stderr", function(error) {
process.stderr.write(error);
});
ex.addListener("cmdEnd", function() {
complete();
});
try{
ex.run();
} catch(e) {
console.log('Exception: ' + e)
}
}
function cleanTestDirs() {
// Clean the local baselines directory
if (fs.existsSync(localBaseline)) {
jake.rmRf(localBaseline);
}
// Clean the local Rwc baselines directory
if (fs.existsSync(localRwcBaseline)) {
jake.rmRf(localRwcBaseline);
}
jake.mkdirP(localBaseline);
}
// 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}';
fs.writeFileSync('test.config', testConfigContents);
}
desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|<more>]'.");
task("runtests", ["tests", builtLocalDirectory], function() {
cleanTestDirs();
host = "mocha"
tests = process.env.test || process.env.tests;
var testConfigFile = 'test.config';
if(fs.existsSync(testConfigFile)) {
fs.unlinkSync(testConfigFile);
}
if(tests) {
writeTestConfigFile(tests, testConfigFile);
}
colors = process.env.colors || process.env.color
colors = colors ? ' --no-colors ' : ''
tests = tests ? ' -g ' + tests : '';
reporter = process.env.reporter || process.env.r || 'dot';
var cmd = host + " -R " + reporter + tests + colors + ' ' + run;
console.log(cmd);
exec(cmd)
}, {async: true});
// Browser tests
var nodeServerOutFile = 'tests/webTestServer.js'
var nodeServerInFile = 'tests/webTestServer.ts'
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tcFile], [], true, true);
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
var cmd = 'browserify built/local/run.js -o built/local/bundle.js';
exec(cmd);
}, {async: true});
desc("Runs the tests using the built run.js file like 'jake runtests'. Syntax is jake runtests-browser. Additional optional parameters tests=[regex], port=, browser=[chrome|IE]");
task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function() {
cleanTestDirs();
host = "node"
port = process.env.port || '8888';
browser = process.env.browser || "IE";
tests = process.env.test || process.env.tests;
var testConfigFile = 'test.config';
if(fs.existsSync(testConfigFile)) {
fs.unlinkSync(testConfigFile);
}
if(tests) {
writeTestConfigFile(tests, testConfigFile);
}
tests = tests ? tests : '';
var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests
console.log(cmd);
exec(cmd);
}, {async: true});
// Baseline Diff
desc("Diffs the compiler baselines using the diff tool specified by the %DIFF% environment variable");
task('diff', function () {
var cmd = "%DIFF% " + refBaseline + ' ' + localBaseline;
console.log(cmd)
exec(cmd);
}, {async: true});
desc("Diffs the RWC baselines using the diff tool specified by the %DIFF% environment variable");
task('diff-rwc', function () {
var cmd = "%DIFF% " + refRwcBaseline + ' ' + localRwcBaseline;
console.log(cmd)
exec(cmd);
}, {async: true});
desc("Builds the test sources and automation in debug mode");
task("tests-debug", ["setDebugMode", "tests"]);
// Makes the test results the new baseline
desc("Makes the most recent test results the new baseline, overwriting the old baseline");
task("baseline-accept", function(hardOrSoft) {
if (!hardOrSoft || hardOrSoft == "hard") {
jake.rmRf(refBaseline);
fs.renameSync(localBaseline, refBaseline);
}
else if (hardOrSoft == "soft") {
var files = jake.readdirR(localBaseline);
for (var i in files) {
jake.cpR(files[i], refBaseline);
}
jake.rmRf(path.join(refBaseline, "local"));
}
});
desc("Makes the most recent rwc test results the new baseline, overwriting the old baseline");
task("baseline-accept-rwc", function() {
jake.rmRf(refRwcBaseline);
fs.renameSync(localRwcBaseline, refRwcBaseline);
});
// Webhost
var webhostPath = "tests/webhost/webtsc.ts";
var webhostJsPath = "tests/webhost/webtsc.js";
compileFile(webhostJsPath, [webhostPath], [tcFile, webhostPath].concat(libraryTargets), [], true);
desc("Builds the tsc web host");
task("webhost", [webhostJsPath], function() {
jake.cpR(path.join(builtLocalDirectory, "lib.d.ts"), "tests/webhost/", {silent: true});
});
// Perf compiler
var perftcPath = "tests/perftc.ts";
var perftcJsPath = "built/local/perftc.js";
compileFile(perftcJsPath, [perftcPath], [tcFile, perftcPath, "tests/perfsys.ts"].concat(libraryTargets), [], true);
desc("Builds augmented version of the compiler for perf tests");
task("perftc", [perftcJsPath]);

55
LICENSE.txt Normal file
View File

@ -0,0 +1,55 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

96
ThirdPartyNoticeText.txt Normal file
View File

@ -0,0 +1,96 @@
/*!----------------- TypeScript ThirdPartyNotices -------------------------------------------------------
The TypeScript software is based on or incorporates material and code from the projects listed below
(collectively "Third Party Code"). Microsoft is not the original author of the
Third Party Code. The original copyright notice and the license, under which
Microsoft received such Third Party Code, are set forth below. Such license and
notices are provided for informational purposes only. Microsoft licenses the Third
Party Code to you under the terms of the Apache 2.0 License.
All Third Party Code licensed by Microsoft under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and
limitations under the License.
---------------------------------------------
Third Party Code Components
--------------------------------------------
---- Mozilla Developer Code---------
The following Mozilla Developer Code is under Public Domain as updated after Aug. 20, 2012, see, https://developer.mozilla.org/en-US/docs/Project:Copyrights
1. Array filter Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
Any copyright is dedicated to the Public Domain.
2. Array forEach Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
Any copyright is dedicated to the Public Domain.
3. Array indexOf Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
Any copyright is dedicated to the Public Domain.
4. Array map Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map
Any copyright is dedicated to the Public Domain.
5. Array Reduce Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce
Any copyright is dedicated to the Public Domain.
6. String Trim Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim
Any copyright is dedicated to the Public Domain.
7. Date now Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now
Any copyright is dedicated to the Public Domain.
------------JSON2 Script------------------------
json2.js 2012-10-08
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See, http://www.JSON.org/js.html
--------------r.js----------------------
Copyright (c) 2010-2011 Dojo Foundation. All Rights Reserved.
Originally License under MIT License
-------------------------------------------------------------------------
Provided for Informational Purposes Only
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------- DefinitelyTyped --------------------
This file is based on or incorporates material from the projects listed below (collectively ?Third Party Code?). Microsoft is not the original author of the Third Party Code. The original copyright notice and the license, under which Microsoft received such Third Party Code, are set forth below. Such licenses and notices are provided for informational purposes only. Microsoft, not the third party, licenses the Third Party Code to you under the terms set forth in the EULA for the Microsoft Product. Microsoft reserves all other rights not expressly granted under this agreement, whether by implication, estoppel or otherwise.
DefinitelyTyped
This project is licensed under the MIT license.
Copyrights are respective of each contributor listed at the beginning of each definition file.
Provided for Informational Purposes Only
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------------
------------- End of ThirdPartyNotices --------------------------------------------------- */

1143
bin/lib.core.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

14182
bin/lib.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

13027
bin/lib.dom.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

38
bin/lib.scripthost.d.ts vendored Normal file
View File

@ -0,0 +1,38 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/// <reference path="lib.core.d.ts" />
/////////////////////////////
/// Windows Script Host APIS
/////////////////////////////
declare var ActiveXObject: { new (s: string): any; };
interface ITextWriter {
Write(s: string): void;
WriteLine(s: string): void;
Close(): void;
}
declare var WScript: {
Echo(s: any): void;
StdErr: ITextWriter;
StdOut: ITextWriter;
Arguments: { length: number; Item(n: number): string; };
ScriptFullName: string;
Quit(exitCode?: number): number;
}

1637
bin/lib.webworker.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

11536
bin/services.js Normal file

File diff suppressed because one or more lines are too long

11354
bin/tc.js Normal file

File diff suppressed because one or more lines are too long

2
bin/tsc Normal file
View File

@ -0,0 +1,2 @@
#!/usr/bin/env node
require('./tsc.js')

Binary file not shown.

Binary file not shown.

41
package.json Normal file
View File

@ -0,0 +1,41 @@
{
"name": "typescript",
"author": "Microsoft Corp.",
"homepage": "http://typescriptlang.org/",
"version": "1.0.1",
"licenses": [
{
"type": "Apache License 2.0",
"url": "http://typescript.codeplex.com/license"
}
],
"description": "TypeScript is a language for application scale JavaScript development",
"keywords": [
"TypeScript",
"Microsoft",
"compiler",
"language",
"javascript"
],
"bugs": {
"url" : "http://typescript.codeplex.com/workitem/list/basic"
},
"repository" : {
"type" : "git",
"url" : "https://git01.codeplex.com/typescript"
},
"preferGlobal" : true,
"main" : "./bin/typescript.js",
"bin" : {
"tsc" : "./bin/tsc"
},
"engines" : {
"node" : ">=0.8.0"
},
"devDependencies": {
"jake" : "latest",
"mocha" : "latest",
"chai" : "latest",
"browserify" : "latest"
}
}

View File

@ -0,0 +1,182 @@
/// <reference path="../src/compiler/sys.ts" />
interface DiagnosticDetails {
category: string;
code: number;
}
interface InputDiagnosticMessageTable {
[msg: string]: DiagnosticDetails;
}
interface IIndexable<V> {
[key: string]: V;
}
function main(): void {
if (sys.args.length < 1) {
sys.write("Usage:" + sys.newLine)
sys.write("\tnode processDiagnosticMessages.js <diagnostic-json-input-file>" + sys.newLine);
return;
}
var inputFilePath = sys.args[0].replace(/\\/g, "/");
var inputStr = sys.readFile(inputFilePath);
var diagnosticMesages: InputDiagnosticMessageTable = JSON.parse(inputStr);
var names = Utilities.getObjectKeys(diagnosticMesages);
var nameMap = buildUniqueNameMap(names);
var infoFileOutput = buildInfoFileOutput(diagnosticMesages, nameMap);
// TODO: Fix path joining
var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/"));
var fileOutputPath = inputDirectory + "/diagnosticInformationMap.generated.ts";
sys.writeFile(fileOutputPath, infoFileOutput);
}
function buildUniqueNameMap(names: string[]): IIndexable<string> {
var nameMap: IIndexable<string> = {};
var uniqueNames = NameGenerator.ensureUniqueness(names, /*isFixed */ undefined, /* isCaseSensitive */ false);
for (var i = 0; i < names.length; i++) {
nameMap[names[i]] = uniqueNames[i];
}
return nameMap;
}
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: IIndexable<string>): string {
var result =
'// <auto-generated />\r\n' +
'/// <reference path="types.ts" />\r\n' +
'module ts {\r\n' +
' export var Diagnostics = {\r\n';
var names = Utilities.getObjectKeys(messageTable);
for (var i = 0; i < names.length; i++) {
var name = names[i];
var diagnosticDetails = messageTable[name];
result +=
' ' + convertPropertyName(nameMap[name]) +
': { code: ' + diagnosticDetails.code +
', category: DiagnosticCategory.' + diagnosticDetails.category +
', key: "' + name.replace('"', '\\"') +
'" },\r\n';
}
result += ' };\r\n}';
return result;
}
function convertPropertyName(origName: string): string {
var result = origName.split("").map(char => {
if (char === '*') { return "_Asterisk"; }
if (char === '/') { return "_Slash"; }
if (char === ':') { return "_Colon"; }
return /\w/.test(char) ? char : "_";
}).join("");
// get rid of all multi-underscores
result = result.replace(/_+/g, "_");
// remove any leading underscore, unless it is followed by a number.
result = result.replace(/^_([^\d])/, "$1")
// get rid of all trailing underscores.
result = result.replace(/_$/, "");
return result;
}
module NameGenerator {
export function ensureUniqueness(
names: string[],
isFixed: boolean[]= names.map(() => false),
isCaseSensitive: boolean = true): string[] {
var names = names.map(x => x);
ensureUniquenessInPlace(names, isFixed, isCaseSensitive);
return names;
}
function ensureUniquenessInPlace(names: string[], isFixed: boolean[], isCaseSensitive: boolean): void {
for (var i = 0; i < names.length; i++) {
var name = names[i];
var collisionIndices = Utilities.collectMatchingIndices(name, names, isCaseSensitive);
// We will always have one "collision" because getCollisionIndices returns the index of name itself as well;
// so if we only have one collision, then there are no issues.
if (collisionIndices.length < 2) {
continue;
}
handleCollisions(name, names, isFixed, collisionIndices, isCaseSensitive);
}
}
function handleCollisions(name: string, proposedNames: string[], isFixed: boolean[], collisionIndices: number[], isCaseSensitive: boolean): void {
var suffix = 1;
for (var i = 0; i < collisionIndices.length; i++) {
var collisionIndex = collisionIndices[i];
if (isFixed[collisionIndex]) {
// can't do anything about this name.
continue;
}
while (true) {
var newName = name + suffix++;
if (proposedNames.some((name) => Utilities.stringEquals(name, newName, isCaseSensitive))) {
proposedNames[collisionIndex] = newName;
break;
}
}
}
}
}
module Utilities {
/// Return a list of all indices where a string occurs.
export function collectMatchingIndices(name: string, proposedNames: string[], isCaseSensitive: boolean = true): number[] {
var matchingIndices: number[] = [];
for (var i = 0; i < proposedNames.length; i++) {
if (stringEquals(name, proposedNames[i], isCaseSensitive)) {
matchingIndices.push(i);
}
}
return matchingIndices;
}
export function stringEquals(s1: string, s2: string, caseSensitive: boolean = true): boolean {
if (!caseSensitive) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
}
return s1 == s2;
}
// Like Object.keys
export function getObjectKeys(obj: any): string[]{
var result: string[] = [];
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
result.push(name);
}
}
return result;
}
}
main();

338
src/compiler/binder.ts Normal file
View File

@ -0,0 +1,338 @@
/// <reference path="types.ts"/>
/// <reference path="core.ts"/>
/// <reference path="scanner.ts"/>
/// <reference path="parser.ts"/>
module ts {
export function isInstantiated(node: Node): boolean {
// A module is uninstantiated if it contains only
// 1. interface declarations
if (node.kind === SyntaxKind.InterfaceDeclaration) {
return false;
}
// 2. non - exported import declarations
else if (node.kind === SyntaxKind.ImportDeclaration && !(node.flags & NodeFlags.Export)) {
return false;
}
// 3. other uninstantiated module declarations.
else if (node.kind === SyntaxKind.ModuleBlock && !forEachChild(node, isInstantiated)) {
return false;
}
else if (node.kind === SyntaxKind.ModuleDeclaration && !isInstantiated((<ModuleDeclaration>node).body)) {
return false;
}
else {
return true;
}
}
export function bindSourceFile(file: SourceFile) {
var parent: Node;
var container: Declaration;
var symbolCount = 0;
var Symbol = objectAllocator.getSymbolConstructor();
if (!file.locals) {
file.locals = {};
container = file;
bind(file);
file.symbolCount = symbolCount;
}
function createSymbol(flags: SymbolFlags, name: string): Symbol {
symbolCount++;
return new Symbol(flags, name);
}
function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolKind: SymbolFlags) {
symbol.flags |= symbolKind;
if (!symbol.declarations) symbol.declarations = [];
symbol.declarations.push(node);
if (symbolKind & SymbolFlags.HasExports && !symbol.exports) symbol.exports = {};
if (symbolKind & SymbolFlags.HasMembers && !symbol.members) symbol.members = {};
node.symbol = symbol;
if (symbolKind & SymbolFlags.Value && !symbol.valueDeclaration) symbol.valueDeclaration = node;
}
function getDeclarationName(node: Declaration): string {
if (node.name) {
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
return '"' + node.name.text + '"';
}
return node.name.text;
}
switch (node.kind) {
case SyntaxKind.Constructor: return "__constructor";
case SyntaxKind.CallSignature: return "__call";
case SyntaxKind.ConstructSignature: return "__new";
case SyntaxKind.IndexSignature: return "__index";
}
}
function getDisplayName(node: Declaration): string {
return node.name ? identifierToString(node.name) : getDeclarationName(node);
}
function declareSymbol(symbols: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
var name = getDeclarationName(node);
if (name !== undefined) {
var symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name));
if (symbol.flags & excludes) {
if (node.name) {
node.name.parent = node;
}
file.semanticErrors.push(createDiagnosticForNode(node.name ? node.name : node,
Diagnostics.Duplicate_identifier_0, getDisplayName(node)));
symbol = createSymbol(0, name);
}
}
else {
symbol = createSymbol(0, "__missing");
}
addDeclarationToSymbol(symbol, node, includes);
symbol.parent = parent;
if (node.kind === SyntaxKind.ClassDeclaration && symbol.exports) {
// TypeScript 1.0 spec (April 2014): 8.4
// Every class automatically contains a static property member named 'prototype',
// the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
// It is an error to explicitly declare a static property member with the name 'prototype'.
var prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
if (hasProperty(symbol.exports, prototypeSymbol.name)) {
if (node.name) {
node.name.parent = node;
}
file.semanticErrors.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0],
Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
}
symbol.exports[prototypeSymbol.name] = prototypeSymbol;
prototypeSymbol.parent = symbol;
}
return symbol;
}
function isAmbientContext(node: Node): boolean {
while (node) {
if (node.flags & NodeFlags.Ambient) return true;
node = node.parent;
}
return false;
}
function declareModuleMember(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
// Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
// ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set
// on it. There are 2 main reasons:
//
// 1. We treat locals and exports of the same name as mutually exclusive within a container.
// That means the binder will issue a Duplicate Identifier error if you mix locals and exports
// with the same name in the same container.
// TODO: Make this a more specific error and decouple it from the exclusion logic.
// 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
// but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
// when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
var exportKind = 0;
var exportExcludes = 0;
if (symbolKind & SymbolFlags.Value) {
exportKind |= SymbolFlags.ExportValue;
exportExcludes |= SymbolFlags.Value;
}
if (symbolKind & SymbolFlags.Type) {
exportKind |= SymbolFlags.ExportType;
exportExcludes |= SymbolFlags.Type;
}
if (symbolKind & SymbolFlags.Namespace) {
exportKind |= SymbolFlags.ExportNamespace;
exportExcludes |= SymbolFlags.Namespace;
}
if (node.flags & NodeFlags.Export || (node.kind !== SyntaxKind.ImportDeclaration && isAmbientContext(container))) {
if (exportKind) {
var local = declareSymbol(container.locals, undefined, node, exportKind, exportExcludes);
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
}
else {
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
}
}
else {
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes | exportKind);
}
}
function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
switch (container.kind) {
case SyntaxKind.ModuleDeclaration:
declareModuleMember(node, symbolKind, symbolExcludes);
break;
case SyntaxKind.SourceFile:
if (container.flags & NodeFlags.ExternalModule) {
declareModuleMember(node, symbolKind, symbolExcludes);
break;
}
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
case SyntaxKind.Method:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
break;
case SyntaxKind.ClassDeclaration:
if (node.flags & NodeFlags.Static) {
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
break;
}
case SyntaxKind.TypeLiteral:
case SyntaxKind.ObjectLiteral:
case SyntaxKind.InterfaceDeclaration:
declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes);
break;
case SyntaxKind.EnumDeclaration:
declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
break;
}
if (symbolKind & SymbolFlags.HasLocals) node.locals = {};
var saveParent = parent;
var saveContainer = container;
parent = node;
if (symbolKind & SymbolFlags.IsContainer) container = node;
forEachChild(node, bind);
container = saveContainer;
parent = saveParent;
}
function bindConstructorDeclaration(node: ConstructorDeclaration) {
bindDeclaration(node, SymbolFlags.Constructor, 0);
forEach(node.parameters, p => {
if (p.flags & (NodeFlags.Public | NodeFlags.Private)) {
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
}
});
}
function bindModuleDeclaration(node: ModuleDeclaration) {
if (node.name.kind === SyntaxKind.StringLiteral) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
}
else if (isInstantiated(node)) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
}
else {
bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
}
}
function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string) {
var symbol = createSymbol(symbolKind, name);
addDeclarationToSymbol(symbol, node, symbolKind);
if (symbolKind & SymbolFlags.HasLocals) node.locals = {};
var saveParent = parent;
var saveContainer = container;
parent = node;
container = node;
forEachChild(node, bind);
container = saveContainer;
parent = saveParent;
}
function bindCatchVariableDeclaration(node: CatchBlock) {
var symbol = createSymbol(SymbolFlags.Variable, node.variable.text || "__missing");
addDeclarationToSymbol(symbol, node.variable, SymbolFlags.Variable);
var saveParent = parent;
parent = node;
forEachChild(node, bind);
parent = saveParent;
}
function bind(node: Node) {
node.parent = parent;
switch (node.kind) {
case SyntaxKind.TypeParameter:
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
break;
case SyntaxKind.Parameter:
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes);
break;
case SyntaxKind.VariableDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Variable, SymbolFlags.VariableExcludes);
break;
case SyntaxKind.Property:
case SyntaxKind.PropertyAssignment:
bindDeclaration(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
break;
case SyntaxKind.EnumMember:
bindDeclaration(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
break;
case SyntaxKind.CallSignature:
bindDeclaration(<Declaration>node, SymbolFlags.CallSignature, 0);
break;
case SyntaxKind.Method:
bindDeclaration(<Declaration>node, SymbolFlags.Method, SymbolFlags.MethodExcludes);
break;
case SyntaxKind.ConstructSignature:
bindDeclaration(<Declaration>node, SymbolFlags.ConstructSignature, 0);
break;
case SyntaxKind.IndexSignature:
bindDeclaration(<Declaration>node, SymbolFlags.IndexSignature, 0);
break;
case SyntaxKind.FunctionDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
break;
case SyntaxKind.Constructor:
bindConstructorDeclaration(<ConstructorDeclaration>node);
break;
case SyntaxKind.GetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes);
break;
case SyntaxKind.SetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
break;
case SyntaxKind.TypeLiteral:
bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type");
break;
case SyntaxKind.ObjectLiteral:
bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
break;
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
bindAnonymousDeclaration(node, SymbolFlags.Function, "__function");
break;
case SyntaxKind.CatchBlock:
bindCatchVariableDeclaration(<CatchBlock>node);
break;
case SyntaxKind.ClassDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
break;
case SyntaxKind.InterfaceDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
break;
case SyntaxKind.EnumDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Enum, SymbolFlags.EnumExcludes);
break;
case SyntaxKind.ModuleDeclaration:
bindModuleDeclaration(<ModuleDeclaration>node);
break;
case SyntaxKind.ImportDeclaration:
bindDeclaration(<Declaration>node, SymbolFlags.Import, SymbolFlags.ImportExcludes);
break;
case SyntaxKind.SourceFile:
if (node.flags & NodeFlags.ExternalModule) {
bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + getModuleNameFromFilename((<SourceFile>node).filename) + '"');
break;
}
default:
var saveParent = parent;
parent = node;
forEachChild(node, bind);
parent = saveParent;
}
}
}
}

5797
src/compiler/checker.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
/// <reference path="sys.ts"/>
/// <reference path="types.ts"/>
/// <reference path="core.ts"/>
/// <reference path="scanner.ts"/>
module ts {
var shortOptionNames: Map<string> = {
"d": "declaration",
"h": "help",
"m": "module",
"o": "out",
"t": "target",
"v": "version",
};
var options: CommandLineOption[] = [
{ name: "codepage", type: "number" },
{ name: "declaration", type: "boolean" },
{ name: "diagnostics", type: "boolean" },
{ name: "help", type: "boolean" },
{ name: "locale", type: "string" },
{ name: "mapRoot", type: "string" },
{ name: "module", type: { "commonjs": ModuleKind.CommonJS, "amd": ModuleKind.AMD }, error: Diagnostics.Argument_for_module_option_must_be_commonjs_or_amd },
{ name: "noImplicitAny", type: "boolean" },
{ name: "noLib", type: "boolean" },
{ name: "noLibCheck", type: "boolean" },
{ name: "noResolve", type: "boolean" },
{ name: "out", type: "string" },
{ name: "outDir", type: "string" },
{ name: "removeComments", type: "boolean" },
{ name: "sourceMap", type: "boolean" },
{ name: "sourceRoot", type: "string" },
{ name: "target", type: { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5 }, error: Diagnostics.Argument_for_target_option_must_be_es3_or_es5 },
{ name: "version", type: "boolean" }
];
// Map command line switches to compiler options' property descriptors. Keys must be lower case spellings of command line switches.
// The 'name' property specifies the property name in the CompilerOptions type. The 'type' property specifies the type of the option.
var optionDeclarations: Map<CommandLineOption> = {};
forEach(options, option => {
optionDeclarations[option.name.toLowerCase()] = option;
});
export function parseCommandLine(commandLine: string[]): ParsedCommandLine {
// Set default compiler option values
var options: CompilerOptions = {
target: ScriptTarget.ES3
};
var filenames: string[] = [];
var errors: Diagnostic[] = [];
parseStrings(commandLine);
return {
options: options,
filenames: filenames,
errors: errors
};
function parseStrings(args: string[]) {
var i = 0;
while (i < args.length) {
var s = args[i++];
if (s.charCodeAt(0) === CharacterCodes.at) {
parseResponseFile(s.slice(1));
}
else if (s.charCodeAt(0) === CharacterCodes.minus) {
s = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase();
// Try to translate short option names to their full equivalents.
if (hasProperty(shortOptionNames, s)) {
s = shortOptionNames[s];
}
if (hasProperty(optionDeclarations, s)) {
var opt = optionDeclarations[s];
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
if (!args[i] && opt.type !== "boolean") {
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
}
switch (opt.type) {
case "number":
options[opt.name] = parseInt(args[i++]);
break;
case "boolean":
options[opt.name] = true;
break;
case "string":
options[opt.name] = args[i++] || "";
break;
// If not a primitive, the possible types are specified in what is effectively a map of options.
default:
var value = (args[i++] || "").toLowerCase();
if (hasProperty(opt.type, value)) {
options[opt.name] = opt.type[value];
}
else {
errors.push(createCompilerDiagnostic(opt.error));
}
}
}
else {
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, s));
}
}
else {
filenames.push(s);
}
}
}
function parseResponseFile(filename: string) {
var text = sys.readFile(filename);
if (!text) {
errors.push(createCompilerDiagnostic(Diagnostics.File_0_not_found, filename));
return;
}
var args: string[] = [];
var pos = 0;
while (true) {
while (pos < text.length && text.charCodeAt(pos) <= CharacterCodes.space) pos++;
if (pos >= text.length) break;
var start = pos;
if (text.charCodeAt(start) === CharacterCodes.doubleQuote) {
pos++;
while (pos < text.length && text.charCodeAt(pos) !== CharacterCodes.doubleQuote) pos++;
if (pos < text.length) {
args.push(text.substring(start + 1, pos));
pos++;
}
else {
errors.push(createCompilerDiagnostic(Diagnostics.Unterminated_quoted_string_in_response_file_0, filename));
}
}
else {
while (text.charCodeAt(pos) > CharacterCodes.space) pos++;
args.push(text.substring(start, pos));
}
}
parseStrings(args);
}
}
}

534
src/compiler/core.ts Normal file
View File

@ -0,0 +1,534 @@
/// <reference path="types.ts"/>
module ts {
export interface Map<T> {
[index: string]: T;
}
export function forEach<T, U>(array: T[], callback: (element: T) => U): U {
var result: U;
if (array) {
for (var i = 0, len = array.length; i < len; i++) {
if (result = callback(array[i])) break;
}
}
return result;
}
export function contains<T>(array: T[], value: T): boolean {
if (array) {
var len = array.length;
for (var i = 0; i < len; i++) {
if (array[i] === value) return true;
}
}
return false;
}
export function indexOf<T>(array: T[], value: T): number {
if (array) {
var len = array.length;
for (var i = 0; i < len; i++) {
if (array[i] === value) return i;
}
}
return -1;
}
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
var result: T[];
if (array) {
result = [];
for (var i = 0, len = array.length; i < len; i++) {
var item = array[i];
if (f(item)) result.push(item);
}
}
return result;
}
export function map<T, U>(array: T[], f: (x: T) => U): U[] {
var result: U[];
if (array) {
result = [];
var len = array.length;
for (var i = 0; i < len; i++) {
result.push(f(array[i]));
}
}
return result;
}
export function concatenate<T>(array1: T[], array2: T[]): T[] {
if (!array2.length) return array1;
if (!array1.length) return array2;
return array1.concat(array2);
}
export function sum(array: any[], prop: string): number {
var result = 0;
for (var i = 0; i < array.length; i++) {
result += array[i][prop];
}
return result;
}
export function binarySearch(array: number[], value: number): number {
var low = 0;
var high = array.length - 1;
while (low <= high) {
var middle = low + ((high - low) >> 1);
var midValue = array[middle];
if (midValue === value) {
return middle;
}
else if (midValue > value) {
high = middle - 1;
}
else {
low = middle + 1;
}
}
return ~low;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
export function hasProperty<T>(map: Map<T>, key: string): boolean {
return hasOwnProperty.call(map, key);
}
export function getProperty<T>(map: Map<T>, key: string): T {
return hasOwnProperty.call(map, key) ? map[key] : undefined;
}
export function isEmpty<T>(map: Map<T>) {
for (var id in map) return false;
return true;
}
export function clone<T>(object: T): T {
var result: any = {};
for (var id in object) {
result[id] = (<any>object)[id];
}
return <T>result;
}
export function forEachValue<T, U>(map: Map<T>, callback: (value: T) => U): U {
var result: U;
for (var id in map) {
if (result = callback(map[id])) break;
}
return result;
}
export function mapToArray<T>(map: Map<T>): T[] {
var result: T[] = [];
for (var id in map) result.push(map[id]);
return result;
}
function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string {
baseIndex = baseIndex || 0;
return text.replace(/{(\d+)}/g, (match, index?) => args[+index + baseIndex]);
}
export var localizedDiagnosticMessages: Map<string> = undefined;
function getLocaleSpecificMessage(message: string) {
if (ts.localizedDiagnosticMessages) {
message = localizedDiagnosticMessages[message];
}
/* Check to see that we got an actual value back. */
Debug.assert(message, "Diagnostic message does not exist in locale map.");
return message;
}
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
var text = getLocaleSpecificMessage(message.key);
if (arguments.length > 4) {
text = formatStringFromArgs(text, arguments, 4);
}
return {
file: file,
start: start,
length: length,
messageText: text,
category: message.category,
code: message.code
};
}
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
var text = getLocaleSpecificMessage(message.key);
if (arguments.length > 1) {
text = formatStringFromArgs(text, arguments, 1);
}
return {
file: undefined,
start: undefined,
length: undefined,
messageText: text,
category: message.category,
code: message.code
};
}
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
var text = getLocaleSpecificMessage(message.key);
if (arguments.length > 2) {
text = formatStringFromArgs(text, arguments, 2);
}
return {
messageText: text,
category: message.category,
code: message.code,
next: details
}
}
export function flattenDiagnosticChain(file: SourceFile, start: number, length: number, diagnosticChain: DiagnosticMessageChain): Diagnostic {
var code = diagnosticChain.code;
var category = diagnosticChain.category;
var messageText = "";
var indent = 0;
while (diagnosticChain) {
if (indent) {
messageText += sys.newLine;
for (var i = 0; i < indent; i++) {
messageText += " ";
}
}
messageText += diagnosticChain.messageText;
indent++;
diagnosticChain = diagnosticChain.next;
}
return {
file: file,
start: start,
length: length,
code: code,
category: category,
messageText: messageText
};
}
function compareValues(a: any, b: any): number {
if (a === b) return 0;
if (a === undefined) return -1;
if (b === undefined) return 1;
return a < b ? -1 : 1;
}
function getDiagnosticFilename(diagnostic: Diagnostic): string {
return diagnostic.file ? diagnostic.file.filename : undefined;
}
export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): number {
return compareValues(getDiagnosticFilename(d1), getDiagnosticFilename(d2)) ||
compareValues(d1.start, d2.start) ||
compareValues(d1.length, d2.length) ||
compareValues(d1.code, d2.code) ||
compareValues(d1.messageText, d2.messageText) ||
0;
}
export function deduplicateSortedDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] {
if (diagnostics.length < 2) {
return diagnostics;
}
var newDiagnostics = [diagnostics[0]];
var previousDiagnostic = diagnostics[0];
for (var i = 1; i < diagnostics.length; i++) {
var currentDiagnostic = diagnostics[i];
var isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === 0;
if (!isDupe) {
newDiagnostics.push(currentDiagnostic);
previousDiagnostic = currentDiagnostic;
}
}
return newDiagnostics;
}
export function normalizeSlashes(path: string): string {
return path.replace(/\\/g, "/");
}
// Returns length of path root (i.e. length of "/", "x:/", "//server/share/")
function getRootLength(path: string): number {
if (path.charCodeAt(0) === CharacterCodes.slash) {
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
var p1 = path.indexOf("/", 2);
if (p1 < 0) return 2;
var p2 = path.indexOf("/", p1 + 1);
if (p2 < 0) return p1 + 1;
return p2 + 1;
}
if (path.charCodeAt(1) === CharacterCodes.colon) {
if (path.charCodeAt(2) === CharacterCodes.slash) return 3;
return 2;
}
return 0;
}
export var directorySeparator = "/";
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
var parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
var normalized: string[] = [];
for (var i = 0; i < parts.length; i++) {
var part = parts[i];
if (part !== ".") {
if (part === ".." && normalized.length > 0 && normalized[normalized.length - 1] !== "..") {
normalized.pop();
}
else {
normalized.push(part);
}
}
}
return normalized;
}
export function normalizePath(path: string): string {
var path = normalizeSlashes(path);
var rootLength = getRootLength(path);
var normalized = getNormalizedParts(path, rootLength);
return path.substr(0, rootLength) + normalized.join(directorySeparator);
}
export function getDirectoryPath(path: string) {
return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator)));
}
export function isUrl(path: string) {
return path && !isRootedDiskPath(path) && path.indexOf("://") !== -1;
}
export function isRootedDiskPath(path: string) {
return getRootLength(path) !== 0;
}
function normalizedPathComponents(path: string, rootLength: number) {
var normalizedParts = getNormalizedParts(path, rootLength);
return [path.substr(0, rootLength)].concat(normalizedParts);
}
export function getNormalizedPathComponents(path: string, currentDirectory: string) {
var path = normalizeSlashes(path);
var rootLength = getRootLength(path);
if (rootLength == 0) {
// If the path is not rooted it is relative to current directory
path = combinePaths(normalizeSlashes(currentDirectory), path);
rootLength = getRootLength(path);
}
return normalizedPathComponents(path, rootLength);
}
export function getNormalizedPathFromPathCompoments(pathComponents: string[]) {
if (pathComponents && pathComponents.length) {
return pathComponents[0] + pathComponents.slice(1).join(directorySeparator);
}
}
function getNormalizedPathComponentsOfUrl(url: string) {
// Get root length of http://www.website.com/folder1/foler2/
// In this example the root is: http://www.website.com/
// normalized path components should be ["http://www.website.com/", "folder1", "folder2"]
var urlLength = url.length;
// Initial root length is http:// part
var rootLength = url.indexOf("://") + "://".length;
while (rootLength < urlLength) {
// Consume all immediate slashes in the protocol
// eg.initial rootlength is just file:// but it needs to consume another "/" in file:///
if (url.charCodeAt(rootLength) === CharacterCodes.slash) {
rootLength++;
}
else {
// non slash character means we continue proceeding to next component of root search
break;
}
}
// there are no parts after http:// just return current string as the pathComponent
if (rootLength === urlLength) {
return [url];
}
// Find the index of "/" after website.com so the root can be http://www.website.com/ (from existing http://)
var indexOfNextSlash = url.indexOf(directorySeparator, rootLength);
if (indexOfNextSlash !== -1) {
// Found the "/" after the website.com so the root is length of http://www.website.com/
// and get components afetr the root normally like any other folder components
rootLength = indexOfNextSlash + 1;
return normalizedPathComponents(url, rootLength);
}
else {
// Can't find the host assume the rest of the string as component
// but make sure we append "/" to it as root is not joined using "/"
// eg. if url passed in was http://website.com we want to use root as [http://website.com/]
// so that other path manipulations will be correct and it can be merged with relative paths correctly
return [url + directorySeparator];
}
}
function getNormalizedPathOrUrlComponents(pathOrUrl: string, currentDirectory: string) {
if (isUrl(pathOrUrl)) {
return getNormalizedPathComponentsOfUrl(pathOrUrl);
}
else {
return getNormalizedPathComponents(pathOrUrl, currentDirectory);
}
}
export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, isAbsolutePathAnUrl: boolean) {
var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory);
var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") {
// If the directory path given was of type test/cases/ then we really need components of directry to be only till its name
// that is ["test", "cases", ""] needs to be actually ["test", "cases"]
directoryComponents.length--;
}
// Find the component that differs
for (var joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) {
if (directoryComponents[joinStartIndex] !== pathComponents[joinStartIndex]) {
break;
}
}
// Get the relative path
if (joinStartIndex) {
var relativePath = "";
var relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length);
for (; joinStartIndex < directoryComponents.length; joinStartIndex++) {
if (directoryComponents[joinStartIndex] !== "") {
relativePath = relativePath + ".." + directorySeparator;
}
}
return relativePath + relativePathComponents.join(directorySeparator);
}
// Cant find the relative path, get the absolute path
var absolutePath = getNormalizedPathFromPathCompoments(pathComponents);
if (isAbsolutePathAnUrl && isRootedDiskPath(absolutePath)) {
absolutePath = "file:///" + absolutePath;
}
return absolutePath;
}
export function getBaseFilename(path: string) {
var i = path.lastIndexOf(directorySeparator);
return i < 0 ? path : path.substring(i + 1);
}
export function combinePaths(path1: string, path2: string) {
if (!(path1 && path1.length)) return path2;
if (!(path2 && path2.length)) return path1;
if (path2.charAt(0) === directorySeparator) return path2;
if (path1.charAt(path1.length - 1) === directorySeparator) return path1 + path2;
return path1 + directorySeparator + path2;
}
export function fileExtensionIs(path: string, extension: string): boolean {
var pathLen = path.length;
var extLen = extension.length;
return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension;
}
export interface ObjectAllocator {
getNodeConstructor(kind: SyntaxKind): new () => Node;
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
}
function Symbol(flags: SymbolFlags, name: string) {
this.flags = flags;
this.name = name;
this.declarations = undefined;
}
function Type(checker: TypeChecker, flags: TypeFlags) {
this.flags = flags;
}
function Signature(checker: TypeChecker) {
}
export var objectAllocator: ObjectAllocator = {
getNodeConstructor: kind => {
function Node() {
}
Node.prototype = {
kind: kind,
pos: 0,
end: 0,
flags: 0,
parent: undefined,
};
return <any>Node;
},
getSymbolConstructor: () => <any>Symbol,
getTypeConstructor: () => <any>Type,
getSignatureConstructor: () => <any>Signature
}
export enum AssertionLevel {
None = 0,
Normal = 1,
Aggressive = 2,
VeryAggressive = 3,
}
export module Debug {
var currentAssertionLevel = AssertionLevel.None;
export function shouldAssert(level: AssertionLevel): boolean {
return this.currentAssertionLevel >= level;
}
export function assert(expression: any, message?: string, verboseDebugInfo?: () => string): void {
if (!expression) {
var verboseDebugString = "";
if (verboseDebugInfo) {
verboseDebugString = "\r\nVerbose Debug Information: " + verboseDebugInfo();
}
throw new Error("Debug Failure. False expression: " + (message || "") + verboseDebugString);
}
}
export function fail(message?: string): void {
Debug.assert(false, message);
}
}
}

View File

@ -0,0 +1,296 @@
// <auto-generated />
/// <reference path="types.ts" />
module ts {
export var Diagnostics = {
Unknown_compiler_option_0: { code: 6001, category: DiagnosticCategory.Error, key: "Unknown compiler option '{0}'." },
File_0_not_found: { code: 6002, category: DiagnosticCategory.Error, key: "File '{0}' not found." },
File_0_must_have_extension_ts_or_d_ts: { code: 6003, category: DiagnosticCategory.Error, key: "File '{0}' must have extension '.ts' or '.d.ts'." },
Unrecognized_escape_sequence: { code: 1000, category: DiagnosticCategory.Error, key: "Unrecognized escape sequence." },
Unexpected_character_0: { code: 1001, category: DiagnosticCategory.Error, key: "Unexpected character {0}." },
Missing_close_quote_character: { code: 1002, category: DiagnosticCategory.Error, key: "Missing close quote character." },
Identifier_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Identifier expected." },
_0_keyword_expected: { code: 1004, category: DiagnosticCategory.Error, key: "'{0}' keyword expected." },
_0_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "'{0}' expected." },
Identifier_expected_0_is_a_keyword: { code: 1006, category: DiagnosticCategory.Error, key: "Identifier expected; '{0}' is a keyword." },
Automatic_semicolon_insertion_not_allowed: { code: 1007, category: DiagnosticCategory.Error, key: "Automatic semicolon insertion not allowed." },
Trailing_comma_not_allowed: { code: 1009, category: DiagnosticCategory.Error, key: "Trailing comma not allowed." },
Asterisk_Slash_expected: { code: 1010, category: DiagnosticCategory.Error, key: "'*/' expected." },
public_or_private_modifier_must_precede_static: { code: 1011, category: DiagnosticCategory.Error, key: "'public' or 'private' modifier must precede 'static'." },
Unexpected_token: { code: 1012, category: DiagnosticCategory.Error, key: "Unexpected token." },
Catch_clause_parameter_cannot_have_a_type_annotation: { code: 1013, category: DiagnosticCategory.Error, key: "Catch clause parameter cannot have a type annotation." },
A_rest_parameter_must_be_last_in_a_parameter_list: { code: 1014, category: DiagnosticCategory.Error, key: "A rest parameter must be last in a parameter list." },
Parameter_cannot_have_question_mark_and_initializer: { code: 1015, category: DiagnosticCategory.Error, key: "Parameter cannot have question mark and initializer." },
A_required_parameter_cannot_follow_an_optional_parameter: { code: 1016, category: DiagnosticCategory.Error, key: "A required parameter cannot follow an optional parameter." },
An_index_signature_cannot_have_a_rest_parameter: { code: 1017, category: DiagnosticCategory.Error, key: "An index signature cannot have a rest parameter." },
An_index_signature_parameter_cannot_have_an_accessibility_modifier: { code: 1018, category: DiagnosticCategory.Error, key: "An index signature parameter cannot have an accessibility modifier." },
An_index_signature_parameter_cannot_have_a_question_mark: { code: 1019, category: DiagnosticCategory.Error, key: "An index signature parameter cannot have a question mark." },
An_index_signature_parameter_cannot_have_an_initializer: { code: 1020, category: DiagnosticCategory.Error, key: "An index signature parameter cannot have an initializer." },
An_index_signature_must_have_a_type_annotation: { code: 1021, category: DiagnosticCategory.Error, key: "An index signature must have a type annotation." },
An_index_signature_parameter_must_have_a_type_annotation: { code: 1022, category: DiagnosticCategory.Error, key: "An index signature parameter must have a type annotation." },
An_index_signature_parameter_type_must_be_string_or_number: { code: 1023, category: DiagnosticCategory.Error, key: "An index signature parameter type must be 'string' or 'number'." },
extends_clause_already_seen: { code: 1024, category: DiagnosticCategory.Error, key: "'extends' clause already seen." },
extends_clause_must_precede_implements_clause: { code: 1025, category: DiagnosticCategory.Error, key: "'extends' clause must precede 'implements' clause." },
Classes_can_only_extend_a_single_class: { code: 1026, category: DiagnosticCategory.Error, key: "Classes can only extend a single class." },
implements_clause_already_seen: { code: 1027, category: DiagnosticCategory.Error, key: "'implements' clause already seen." },
Accessibility_modifier_already_seen: { code: 1028, category: DiagnosticCategory.Error, key: "Accessibility modifier already seen." },
_0_modifier_must_precede_1_modifier: { code: 1029, category: DiagnosticCategory.Error, key: "'{0}' modifier must precede '{1}' modifier." },
_0_modifier_already_seen: { code: 1030, category: DiagnosticCategory.Error, key: "'{0}' modifier already seen." },
_0_modifier_cannot_appear_on_a_class_element: { code: 1031, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot appear on a class element." },
Interface_declaration_cannot_have_implements_clause: { code: 1032, category: DiagnosticCategory.Error, key: "Interface declaration cannot have 'implements' clause." },
super_invocation_cannot_have_type_arguments: { code: 1034, category: DiagnosticCategory.Error, key: "'super' invocation cannot have type arguments." },
Only_ambient_modules_can_use_quoted_names: { code: 1035, category: DiagnosticCategory.Error, key: "Only ambient modules can use quoted names." },
Statements_are_not_allowed_in_ambient_contexts: { code: 1036, category: DiagnosticCategory.Error, key: "Statements are not allowed in ambient contexts." },
A_function_implementation_cannot_be_declared_in_an_ambient_context: { code: 1037, category: DiagnosticCategory.Error, key: "A function implementation cannot be declared in an ambient context." },
A_declare_modifier_cannot_be_used_in_an_already_ambient_context: { code: 1038, category: DiagnosticCategory.Error, key: "A 'declare' modifier cannot be used in an already ambient context." },
Initializers_are_not_allowed_in_ambient_contexts: { code: 1039, category: DiagnosticCategory.Error, key: "Initializers are not allowed in ambient contexts." },
_0_modifier_cannot_appear_on_a_module_element: { code: 1044, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot appear on a module element." },
A_declare_modifier_cannot_be_used_with_an_interface_declaration: { code: 1045, category: DiagnosticCategory.Error, key: "A 'declare' modifier cannot be used with an interface declaration." },
A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: { code: 1046, category: DiagnosticCategory.Error, key: "A 'declare' modifier is required for a top level declaration in a .d.ts file." },
A_rest_parameter_cannot_be_optional: { code: 1047, category: DiagnosticCategory.Error, key: "A rest parameter cannot be optional." },
A_rest_parameter_cannot_have_an_initializer: { code: 1048, category: DiagnosticCategory.Error, key: "A rest parameter cannot have an initializer." },
A_set_accessor_must_have_exactly_one_parameter: { code: 1049, category: DiagnosticCategory.Error, key: "A 'set' accessor must have exactly one parameter." },
A_set_accessor_cannot_have_an_optional_parameter: { code: 1051, category: DiagnosticCategory.Error, key: "A 'set' accessor cannot have an optional parameter." },
A_set_accessor_parameter_cannot_have_an_initializer: { code: 1052, category: DiagnosticCategory.Error, key: "A 'set' accessor parameter cannot have an initializer." },
A_set_accessor_cannot_have_rest_parameter: { code: 1053, category: DiagnosticCategory.Error, key: "A 'set' accessor cannot have rest parameter." },
A_get_accessor_cannot_have_parameters: { code: 1054, category: DiagnosticCategory.Error, key: "A 'get' accessor cannot have parameters." },
Modifiers_cannot_appear_here: { code: 1055, category: DiagnosticCategory.Error, key: "Modifiers cannot appear here." },
Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1056, category: DiagnosticCategory.Error, key: "Accessors are only available when targeting ECMAScript 5 and higher." },
Enum_member_must_have_initializer: { code: -9999999, category: DiagnosticCategory.Error, key: "Enum member must have initializer." },
An_export_assignment_cannot_be_used_in_an_internal_module: { code: 1063, category: DiagnosticCategory.Error, key: "An export assignment cannot be used in an internal module." },
Ambient_enum_elements_can_only_have_integer_literal_initializers: { code: 1066, category: DiagnosticCategory.Error, key: "Ambient enum elements can only have integer literal initializers." },
module_class_interface_enum_import_or_statement: { code: 1067, category: DiagnosticCategory.NoPrefix, key: "module, class, interface, enum, import or statement" },
Unexpected_token_A_constructor_method_accessor_or_property_was_expected: { code: 1068, category: DiagnosticCategory.Error, key: "Unexpected token. A constructor, method, accessor, or property was expected." },
statement: { code: 1069, category: DiagnosticCategory.NoPrefix, key: "statement" },
case_or_default_clause: { code: 1070, category: DiagnosticCategory.NoPrefix, key: "case or default clause" },
identifier: { code: 1071, category: DiagnosticCategory.NoPrefix, key: "identifier" },
call_construct_index_property_or_function_signature: { code: 1072, category: DiagnosticCategory.NoPrefix, key: "call, construct, index, property or function signature" },
expression: { code: 1073, category: DiagnosticCategory.NoPrefix, key: "expression" },
type_name: { code: 1074, category: DiagnosticCategory.NoPrefix, key: "type name" },
property_or_accessor: { code: 1075, category: DiagnosticCategory.NoPrefix, key: "property or accessor" },
parameter: { code: 1076, category: DiagnosticCategory.NoPrefix, key: "parameter" },
type: { code: 1077, category: DiagnosticCategory.NoPrefix, key: "type" },
type_parameter: { code: 1078, category: DiagnosticCategory.NoPrefix, key: "type parameter" },
A_declare_modifier_cannot_be_used_with_an_import_declaration: { code: 1079, category: DiagnosticCategory.Error, key: "A 'declare' modifier cannot be used with an import declaration." },
Invalid_reference_directive_syntax: { code: 1084, category: DiagnosticCategory.Error, key: "Invalid 'reference' directive syntax." },
Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher: { code: 1085, category: DiagnosticCategory.Error, key: "Octal literals are not available when targeting ECMAScript 5 and higher." },
An_accessor_cannot_be_declared_in_an_ambient_context: { code: 1086, category: DiagnosticCategory.Error, key: "An accessor cannot be declared in an ambient context." },
_0_modifier_cannot_appear_on_a_constructor_declaration: { code: 1089, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot appear on a constructor declaration." },
_0_modifier_cannot_appear_on_a_parameter: { code: 1090, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot appear on a parameter." },
Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: { code: 1091, category: DiagnosticCategory.Error, key: "Only a single variable declaration is allowed in a 'for...in' statement." },
Type_parameters_cannot_appear_on_a_constructor_declaration: { code: 1092, category: DiagnosticCategory.Error, key: "Type parameters cannot appear on a constructor declaration." },
Type_annotation_cannot_appear_on_a_constructor_declaration: { code: 1093, category: DiagnosticCategory.Error, key: "Type annotation cannot appear on a constructor declaration." },
An_accessor_cannot_have_type_parameters: { code: 1094, category: DiagnosticCategory.Error, key: "An accessor cannot have type parameters." },
A_set_accessor_cannot_have_a_return_type_annotation: { code: 1095, category: DiagnosticCategory.Error, key: "A 'set' accessor cannot have a return type annotation." },
An_index_signature_must_have_exactly_one_parameter: { code: 1096, category: DiagnosticCategory.Error, key: "An index signature must have exactly one parameter." },
_0_list_cannot_be_empty: { code: 1097, category: DiagnosticCategory.Error, key: "'{0}' list cannot be empty." },
Type_parameter_list_cannot_be_empty: { code: 1098, category: DiagnosticCategory.Error, key: "Type parameter list cannot be empty." },
Type_argument_list_cannot_be_empty: { code: 1099, category: DiagnosticCategory.Error, key: "Type argument list cannot be empty." },
Invalid_use_of_0_in_strict_mode: { code: 1100, category: DiagnosticCategory.Error, key: "Invalid use of '{0}' in strict mode." },
with_statements_are_not_allowed_in_strict_mode: { code: 1101, category: DiagnosticCategory.Error, key: "'with' statements are not allowed in strict mode." },
delete_cannot_be_called_on_an_identifier_in_strict_mode: { code: 1102, category: DiagnosticCategory.Error, key: "'delete' cannot be called on an identifier in strict mode." },
Invalid_left_hand_side_in_for_in_statement: { code: 1103, category: DiagnosticCategory.Error, key: "Invalid left-hand side in 'for...in' statement." },
continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: { code: 1104, category: DiagnosticCategory.Error, key: "'continue' statement can only be used within an enclosing iteration statement." },
break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: { code: 1105, category: DiagnosticCategory.Error, key: "'break' statement can only be used within an enclosing iteration or switch statement." },
Jump_target_not_found: { code: 1106, category: DiagnosticCategory.Error, key: "Jump target not found." },
Jump_target_cannot_cross_function_boundary: { code: 1107, category: DiagnosticCategory.Error, key: "Jump target cannot cross function boundary." },
return_statement_must_be_contained_within_a_function_body: { code: 1108, category: DiagnosticCategory.Error, key: "'return' statement must be contained within a function body." },
Expression_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Expression expected." },
Type_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Type expected." },
A_constructor_implementation_cannot_be_declared_in_an_ambient_context: { code: 1111, category: DiagnosticCategory.Error, key: "A constructor implementation cannot be declared in an ambient context." },
A_class_member_cannot_be_declared_optional: { code: 1112, category: DiagnosticCategory.Error, key: "A class member cannot be declared optional." },
Duplicate_identifier_0: { code: 2000, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 2068, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
Multiple_constructor_implementations_are_not_allowed: { code: 2070, category: DiagnosticCategory.Error, key: "Multiple constructor implementations are not allowed." },
A_class_may_only_implement_another_class_or_interface: { code: 2074, category: DiagnosticCategory.Error, key: "A class may only implement another class or interface." },
get_and_set_accessor_must_have_the_same_type: { code: 2096, category: DiagnosticCategory.Error, key: "'get' and 'set' accessor must have the same type." },
Static_members_cannot_reference_class_type_parameters: { code: 2099, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: { code: 2102, category: DiagnosticCategory.Error, key: "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class" },
The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2112, category: DiagnosticCategory.Error, key: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2113, category: DiagnosticCategory.Error, key: "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: { code: 2114, category: DiagnosticCategory.Error, key: "An arithmetic operand must be of type 'any', 'number' or an enum type." },
Variable_declarations_of_a_for_statement_cannot_use_a_type_annotation: { code: 2115, category: DiagnosticCategory.Error, key: "Variable declarations of a 'for' statement cannot use a type annotation." },
Variable_declarations_of_a_for_statement_must_be_of_types_string_or_any: { code: 2116, category: DiagnosticCategory.Error, key: "Variable declarations of a 'for' statement must be of types 'string' or 'any'." },
The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2117, category: DiagnosticCategory.Error, key: "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter." },
The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: { code: 2118, category: DiagnosticCategory.Error, key: "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'." },
The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2119, category: DiagnosticCategory.Error, key: "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter" },
Getters_must_return_a_value: { code: 2126, category: DiagnosticCategory.Error, key: "Getters must return a value." },
Getter_and_setter_accessors_do_not_agree_in_visibility: { code: 2127, category: DiagnosticCategory.Error, key: "Getter and setter accessors do not agree in visibility." },
Untyped_function_calls_may_not_accept_type_arguments: { code: 2158, category: DiagnosticCategory.Error, key: "Untyped function calls may not accept type arguments." },
The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2120, category: DiagnosticCategory.Error, key: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." },
The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: { code: 2121, category: DiagnosticCategory.Error, key: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type." },
Setters_cannot_return_a_value: { code: 2122, category: DiagnosticCategory.Error, key: "Setters cannot return a value." },
Invalid_left_hand_side_of_assignment_expression: { code: 2130, category: DiagnosticCategory.Error, key: "Invalid left-hand side of assignment expression." },
Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: { code: 2134, category: DiagnosticCategory.Error, key: "Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'." },
The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer: { code: 2139, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator must be a variable, property or indexer." },
Overload_signatures_must_all_be_public_or_private: { code: 2150, category: DiagnosticCategory.Error, key: "Overload signatures must all be public or private." },
Overload_signatures_must_all_be_exported_or_not_exported: { code: 2151, category: DiagnosticCategory.Error, key: "Overload signatures must all be exported or not exported." },
Overload_signatures_must_all_be_ambient_or_non_ambient: { code: 2152, category: DiagnosticCategory.Error, key: "Overload signatures must all be ambient or non-ambient." },
Overload_signatures_must_all_be_optional_or_required: { code: 2153, category: DiagnosticCategory.Error, key: "Overload signatures must all be optional or required." },
this_cannot_be_referenced_in_constructor_arguments: { code: 2155, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in constructor arguments." },
Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: { code: 2161, category: DiagnosticCategory.Error, key: "Value of type '{0}' is not callable. Did you mean to include 'new'?" },
A_signature_with_an_implementation_cannot_use_a_string_literal_type: { code: 2163, category: DiagnosticCategory.Error, key: "A signature with an implementation cannot use a string literal type." },
Interface_0_cannot_simultaneously_extend_types_1_and_2_Colon: { code: 2189, category: DiagnosticCategory.Error, key: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}':" },
Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: { code: 2190, category: DiagnosticCategory.Error, key: "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it." },
super_cannot_be_referenced_in_constructor_arguments: { code: 2193, category: DiagnosticCategory.Error, key: "'super' cannot be referenced in constructor arguments." },
Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: { code: 2194, category: DiagnosticCategory.Error, key: "Return type of constructor signature must be assignable to the instance type of the class" },
Ambient_external_module_declaration_cannot_specify_relative_module_name: { code: 2196, category: DiagnosticCategory.Error, key: "Ambient external module declaration cannot specify relative module name." },
Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name: { code: 2197, category: DiagnosticCategory.Error, key: "Import declaration in an ambient external module declaration cannot reference external module through relative external module name." },
Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: { code: 2205, category: DiagnosticCategory.Error, key: "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference." },
Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: { code: 2207, category: DiagnosticCategory.Error, key: "Expression resolves to '_super' that compiler uses to capture base class reference." },
Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter: { code: 2224, category: DiagnosticCategory.Error, key: "Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter." },
Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2225, category: DiagnosticCategory.Error, key: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." },
Constraint_of_a_type_parameter_cannot_reference_any_type_parameter_from_the_same_type_parameter_list: { code: 2229, category: DiagnosticCategory.Error, key: "Constraint of a type parameter cannot reference any type parameter from the same type parameter list." },
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2230, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
Parameter_0_cannot_be_referenced_in_its_initializer: { code: 2231, category: DiagnosticCategory.Error, key: "Parameter '{0}' cannot be referenced in its initializer." },
Duplicate_string_index_signature: { code: 2232, category: DiagnosticCategory.Error, key: "Duplicate string index signature." },
Duplicate_number_index_signature: { code: 2233, category: DiagnosticCategory.Error, key: "Duplicate number index signature." },
All_declarations_of_an_interface_must_have_identical_type_parameters: { code: 2234, category: DiagnosticCategory.Error, key: "All declarations of an interface must have identical type parameters." },
Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter: { code: 2235, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter." },
Constructor_implementation_expected: { code: 2240, category: DiagnosticCategory.Error, key: "Constructor implementation expected." },
An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: { code: 2245, category: DiagnosticCategory.Error, key: "An export assignment cannot be used in a module with other exported elements." },
A_parameter_property_is_only_allowed_in_a_constructor_implementation: { code: 2246, category: DiagnosticCategory.Error, key: "A parameter property is only allowed in a constructor implementation." },
Circular_definition_of_import_alias_0: { code: 3000, category: DiagnosticCategory.Error, key: "Circular definition of import alias '{0}'." },
Cannot_find_name_0: { code: 3001, category: DiagnosticCategory.Error, key: "Cannot find name '{0}'." },
Module_0_has_no_exported_member_1: { code: 3002, category: DiagnosticCategory.Error, key: "Module '{0}' has no exported member '{1}'." },
Cannot_find_external_module_0: { code: 3003, category: DiagnosticCategory.Error, key: "Cannot find external module '{0}'." },
A_module_cannot_have_more_than_one_export_assignment: { code: 3004, category: DiagnosticCategory.Error, key: "A module cannot have more than one export assignment." },
Type_0_recursively_references_itself_as_a_base_type: { code: 3005, category: DiagnosticCategory.Error, key: "Type '{0}' recursively references itself as a base type." },
A_class_may_only_extend_another_class: { code: 3006, category: DiagnosticCategory.Error, key: "A class may only extend another class." },
An_interface_may_only_extend_a_class_or_another_interface: { code: 3007, category: DiagnosticCategory.Error, key: "An interface may only extend a class or another interface." },
Generic_type_0_requires_1_type_argument_s: { code: 3008, category: DiagnosticCategory.Error, key: "Generic type '{0}' requires {1} type argument(s)." },
Type_0_is_not_generic: { code: 3009, category: DiagnosticCategory.Error, key: "Type '{0}' is not generic." },
Cannot_find_global_type_0: { code: 3010, category: DiagnosticCategory.Error, key: "Cannot find global type '{0}'." },
Global_type_0_must_be_a_class_or_interface_type: { code: 3011, category: DiagnosticCategory.Error, key: "Global type '{0}' must be a class or interface type." },
Global_type_0_must_have_1_type_parameter_s: { code: 3012, category: DiagnosticCategory.Error, key: "Global type '{0}' must have {1} type parameter(s)." },
this_cannot_be_referenced_in_a_module_body: { code: 3013, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in a module body." },
this_cannot_be_referenced_in_a_static_property_initializer: { code: 3014, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in a static property initializer." },
this_cannot_be_referenced_in_current_location: { code: -9999999, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in current location." },
super_can_only_be_referenced_in_a_derived_class: { code: 3015, category: DiagnosticCategory.Error, key: "'super' can only be referenced in a derived class." },
Property_0_does_not_exist_on_type_1: { code: 3017, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on type '{1}'." },
An_index_expression_argument_must_be_of_type_string_number_or_any: { code: 3018, category: DiagnosticCategory.Error, key: "An index expression argument must be of type 'string', 'number', or 'any'." },
Type_0_does_not_satisfy_the_constraint_1_Colon: { code: 3019, category: DiagnosticCategory.Error, key: "Type '{0}' does not satisfy the constraint '{1}':" },
Type_0_does_not_satisfy_the_constraint_1: { code: 3019, category: DiagnosticCategory.Error, key: "Type '{0}' does not satisfy the constraint '{1}'." },
Supplied_parameters_do_not_match_any_signature_of_call_target: { code: 3020, category: DiagnosticCategory.Error, key: "Supplied parameters do not match any signature of call target." },
Cannot_invoke_an_expression_whose_type_lacks_a_call_signature: { code: 3021, category: DiagnosticCategory.Error, key: "Cannot invoke an expression whose type lacks a call signature." },
Only_a_void_function_can_be_called_with_the_new_keyword: { code: 3022, category: DiagnosticCategory.Error, key: "Only a void function can be called with the 'new' keyword." },
Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: { code: 3023, category: DiagnosticCategory.Error, key: "Cannot use 'new' with an expression whose type lacks a call or construct signature." },
Neither_type_0_nor_type_1_is_assignable_to_the_other_Colon: { code: 3024, category: DiagnosticCategory.Error, key: "Neither type '{0}' nor type '{1}' is assignable to the other:" },
Neither_type_0_nor_type_1_is_assignable_to_the_other: { code: 3024, category: DiagnosticCategory.Error, key: "Neither type '{0}' nor type '{1}' is assignable to the other." },
No_best_common_type_exists_among_return_expressions: { code: 3027, category: DiagnosticCategory.Error, key: "No best common type exists among return expressions." },
Operator_0_cannot_be_applied_to_types_1_and_2: { code: 3028, category: DiagnosticCategory.Error, key: "Operator '{0}' cannot be applied to types '{1}' and '{2}'." },
No_best_common_type_exists_between_0_and_1: { code: 3029, category: DiagnosticCategory.Error, key: "No best common type exists between '{0}' and '{1}'." },
No_best_common_type_exists_between_0_1_and_2: { code: 3030, category: DiagnosticCategory.Error, key: "No best common type exists between '{0}', '{1}', and '{2}'." },
A_rest_parameter_must_be_of_an_array_type: { code: 3031, category: DiagnosticCategory.Error, key: "A rest parameter must be of an array type." },
A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: { code: 3032, category: DiagnosticCategory.Error, key: "A parameter initializer is only allowed in a function or constructor implementation." },
Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: { code: 3033, category: DiagnosticCategory.Error, key: "Specialized overload signature is not assignable to any non-specialized signature." },
Duplicate_function_implementation: { code: 3034, category: DiagnosticCategory.Error, key: "Duplicate function implementation." },
Overload_signature_is_not_compatible_with_function_implementation: { code: 3035, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." },
Index_signature_is_missing_in_type_0: { code: 4003, category: DiagnosticCategory.Error, key: "Index signature is missing in type '{0}'." },
Index_signatures_are_incompatible_Colon: { code: 4004, category: DiagnosticCategory.Error, key: "Index signatures are incompatible:" },
Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 4016, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function." },
Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 4017, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function." },
Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: { code: 4018, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor." },
Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: { code: 4019, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property." },
Named_properties_0_of_types_1_and_2_are_not_identical: { code: 4032, category: DiagnosticCategory.NoPrefix, key: "Named properties '{0}' of types '{1}' and '{2}' are not identical." },
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." },
Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" },
Unsupported_file_encoding: { code: 5013, category: DiagnosticCategory.NoPrefix, key: "Unsupported file encoding." },
Could_not_write_file_0: { code: 5033, category: DiagnosticCategory.Error, key: "Could not write file '{0}'." },
Could_not_create_directory_0: { code: 5035, category: DiagnosticCategory.Error, key: "Could not create directory '{0}'." },
Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5038, category: DiagnosticCategory.Error, key: "Option mapRoot cannot be specified without specifying sourcemap option." },
Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5039, category: DiagnosticCategory.Error, key: "Option sourceRoot cannot be specified without specifying sourcemap option." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." },
new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: { code: 7009, category: DiagnosticCategory.Error, key: "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type." },
_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: { code: 7010, category: DiagnosticCategory.Error, key: "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type." },
Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: { code: 7011, category: DiagnosticCategory.Error, key: "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type." },
Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7013, category: DiagnosticCategory.Error, key: "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type." },
Lambda_function_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: { code: 7014, category: DiagnosticCategory.Error, key: "Lambda function, which lacks return-type annotation, implicitly has an '{0}' return type." },
Array_literal_implicitly_has_an_0_type: { code: 7015, category: DiagnosticCategory.Error, key: "Array literal implicitly has an '{0}' type." },
Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation: { code: 7016, category: DiagnosticCategory.Error, key: "Property '{0}' implicitly has type 'any', because its 'set' accessor lacks a type annotation." },
Index_signature_of_object_type_implicitly_has_an_any_type: { code: 7017, category: DiagnosticCategory.Error, key: "Index signature of object type implicitly has an 'any' type." },
Object_literal_s_property_0_implicitly_has_an_1_type: { code: 7018, category: DiagnosticCategory.Error, key: "Object literal's property '{0}' implicitly has an '{1}' type." },
Rest_parameter_0_implicitly_has_an_any_type: { code: 7019, category: DiagnosticCategory.Error, key: "Rest parameter '{0}' implicitly has an 'any[]' type." },
Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7020, category: DiagnosticCategory.Error, key: "Call signature, which lacks return-type annotation, implicitly has an 'any' return type." },
Variable_declaration_list_cannot_be_empty: { code: -9999999, category: DiagnosticCategory.Error, key: "Variable declaration list cannot be empty." },
Digit_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Digit expected." },
Hexadecimal_digit_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Hexadecimal digit expected." },
Unexpected_end_of_text: { code: -9999999, category: DiagnosticCategory.Error, key: "Unexpected end of text." },
Unterminated_string_constant: { code: -9999999, category: DiagnosticCategory.Error, key: "Unterminated string constant." },
Invalid_character: { code: -9999999, category: DiagnosticCategory.Error, key: "Invalid character." },
Declaration_or_statement_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Declaration or statement expected." },
Statement_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Statement expected." },
case_or_default_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "'case' or 'default' expected." },
Property_or_signature_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Property or signature expected." },
Enum_member_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Enum member expected." },
Type_reference_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Type reference expected." },
Variable_declaration_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Variable declaration expected." },
Argument_expression_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Argument expression expected." },
Property_assignment_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Property assignment expected." },
Expression_or_comma_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Expression or comma expected." },
Parameter_declaration_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Parameter declaration expected." },
Type_parameter_declaration_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Type parameter declaration expected." },
Type_argument_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Type argument expected." },
String_literal_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "String literal expected." },
not_preceded_by_parameter_list: { code: -9999999, category: DiagnosticCategory.Error, key: "'=>' not preceded by parameter list." },
Invalid_assignment_target: { code: -9999999, category: DiagnosticCategory.Error, key: "Invalid assignment target." },
super_must_be_followed_by_argument_list_or_member_access: { code: -9999999, category: DiagnosticCategory.Error, key: "'super' must be followed by argument list or member access." },
Line_break_not_permitted_here: { code: -9999999, category: DiagnosticCategory.Error, key: "Line break not permitted here." },
catch_or_finally_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "'catch' or 'finally' expected." },
Block_or_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Block or ';' expected." },
Modifiers_not_permitted_on_index_signature_members: { code: -9999999, category: DiagnosticCategory.Error, key: "Modifiers not permitted on index signature members." },
Class_member_declaration_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Class member declaration expected." },
Declaration_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Declaration expected." },
Invalid_reference_comment: { code: -9999999, category: DiagnosticCategory.Error, key: "Invalid reference comment." },
File_0_is_not_an_external_module: { code: -9999999, category: DiagnosticCategory.Error, key: "File '{0}' is not an external module." },
Excessive_stack_depth_comparing_types_0_and_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Excessive stack depth comparing types '{0}' and '{1}'." },
Type_0_is_not_assignable_to_type_1_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Type '{0}' is not assignable to type '{1}':" },
Type_0_is_not_assignable_to_type_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Type '{0}' is not assignable to type '{1}'." },
Property_0_is_missing_in_type_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Property '{0}' is missing in type '{1}'." },
Private_property_0_cannot_be_reimplemented: { code: -9999999, category: DiagnosticCategory.Error, key: "Private property '{0}' cannot be reimplemented." },
Required_property_0_cannot_be_reimplemented_with_optional_property_in_1: { code: 2012, category: DiagnosticCategory.Error, key: "Required property '{0}' cannot be reimplemented with optional property in '{1}'." },
Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: { code: -9999999, category: DiagnosticCategory.Error, key: "Super calls are not permitted outside constructors or in nested functions inside constructors" },
Only_public_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: -9999999, category: DiagnosticCategory.Error, key: "Only public methods of the base class are accessible via the 'super' keyword" },
A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: { code: -9999999, category: DiagnosticCategory.Error, key: "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties." },
Constructors_for_derived_classes_must_contain_a_super_call: { code: -9999999, category: DiagnosticCategory.Error, key: "Constructors for derived classes must contain a 'super' call." },
Import_name_cannot_be_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Import name cannot be '{0}'" },
Type_parameter_name_cannot_be_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Type parameter name cannot be '{0}'" },
Class_name_cannot_be_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Class name cannot be '{0}'" },
Interface_name_cannot_be_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Interface name cannot be '{0}'" },
Enum_name_cannot_be_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Enum name cannot be '{0}'" },
Types_of_property_0_are_incompatible_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Types of property '{0}' are incompatible:" },
Types_of_parameters_0_and_1_are_incompatible_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Types of parameters '{0}' and '{1}' are incompatible:" },
Unknown_identifier_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Unknown identifier '{0}'." },
Property_0_is_inaccessible: { code: -9999999, category: DiagnosticCategory.Error, key: "Property '{0}' is inaccessible." },
Function_implementation_expected: { code: -9999999, category: DiagnosticCategory.Error, key: "Function implementation expected." },
return_statement_has_no_containing_function: { code: -9999999, category: DiagnosticCategory.Error, key: "'return' statement has no containing function." },
Property_0_of_type_1_is_not_assignable_to_string_index_type_2: { code: -9999999, category: DiagnosticCategory.Error, key: "Property '{0}' of type '{1}' is not assignable to string index type '{2}'." },
Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: { code: -9999999, category: DiagnosticCategory.Error, key: "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'." },
Numeric_index_type_0_is_not_assignable_to_string_index_type_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Numeric index type '{0}' is not assignable to string index type '{1}'." },
Class_0_incorrectly_extends_base_class_1_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Class '{0}' incorrectly extends base class '{1}':" },
Class_0_incorrectly_extends_base_class_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Class '{0}' incorrectly extends base class '{1}'." },
Class_static_side_0_incorrectly_extends_base_class_static_side_1_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Class static side '{0}' incorrectly extends base class static side '{1}':" },
Class_static_side_0_incorrectly_extends_base_class_static_side_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Class static side '{0}' incorrectly extends base class static side '{1}'." },
Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Type name '{0}' in extends clause does not reference constructor function for '{0}'." },
Class_0_incorrectly_implements_interface_1_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Class '{0}' incorrectly implements interface '{1}':" },
Class_0_incorrectly_implements_interface_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Class '{0}' incorrectly implements interface '{1}'." },
Interface_0_incorrectly_extends_interface_1_Colon: { code: -9999999, category: DiagnosticCategory.Error, key: "Interface '{0}' incorrectly extends interface '{1}':" },
Interface_0_incorrectly_extends_interface_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Interface '{0}' incorrectly extends interface '{1}'." },
Ambient_external_modules_require_a_declare_modifier: { code: -9999999, category: DiagnosticCategory.Error, key: "Ambient external modules require a 'declare' modifier." },
Ambient_external_modules_cannot_be_nested_in_other_modules: { code: -9999999, category: DiagnosticCategory.Error, key: "Ambient external modules cannot be nested in other modules." },
Import_declarations_in_an_internal_module_cannot_reference_an_external_module: { code: -9999999, category: DiagnosticCategory.Error, key: "Import declarations in an internal module cannot reference an external module." },
Cannot_compile_external_modules_unless_the_module_flag_is_provided: { code: -9999999, category: DiagnosticCategory.Error, key: "Cannot compile external modules unless the '--module' flag is provided." },
Import_declaration_conflicts_with_local_declaration_of_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Import declaration conflicts with local declaration of '{0}'" },
Filename_0_differs_from_already_included_filename_1_only_in_casing: { code: -9999999, category: DiagnosticCategory.Error, key: "Filename '{0}' differs from already included filename '{1}' only in casing" },
Argument_for_module_option_must_be_commonjs_or_amd: { code: -9999999, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs' or 'amd'." },
Argument_for_target_option_must_be_es3_or_es5: { code: -9999999, category: DiagnosticCategory.Error, key: "Argument for '--target' option must be 'es3' or 'es5'." },
Compiler_option_0_expects_an_argument: { code: -9999999, category: DiagnosticCategory.Error, key: "Compiler option '{0}' expects an argument." },
Unterminated_quoted_string_in_response_file_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Unterminated quoted string in response file '{0}'." },
Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: { code: -9999999, category: DiagnosticCategory.Error, key: "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'." },
Unsupported_locale_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Unsupported locale {0}." },
Unable_to_open_file_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Unable to open file {0}." },
Corrupted_locale_file_0: { code: -9999999, category: DiagnosticCategory.Error, key: "Corrupted locale file {0}." },
No_input_files_specified: { code: -9999999, category: DiagnosticCategory.Error, key: "No input files specified." },
};
}

File diff suppressed because it is too large Load Diff

2284
src/compiler/emitter.ts Normal file

File diff suppressed because it is too large Load Diff

3104
src/compiler/parser.ts Normal file

File diff suppressed because it is too large Load Diff

915
src/compiler/scanner.ts Normal file

File diff suppressed because one or more lines are too long

259
src/compiler/sys.ts Normal file
View File

@ -0,0 +1,259 @@
interface System {
args: string[];
newLine: string;
write(s: string): void;
writeErr(s: string): void;
readFile(fileName: string): string;
writeFile(fileName: string, data: string): void;
resolvePath(path: string): string;
fileExists(path: string): boolean;
directoryExists(path: string): boolean;
createDirectory(directoryName: string): void;
getExecutingFilePath(): string;
getCurrentDirectory(): string;
getMemoryUsage(): number;
exit(exitCode?: number): void;
useCaseSensitiveFileNames: boolean;
}
enum ErrorCodes {
UnsupportedFileEncoding = 1,
CannotReadFile = 2,
}
declare var require: any;
declare var module: any;
declare var process: any;
declare var global: any;
var sys: System = (function () {
function getWScriptSystem(): System {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var args: string[] = [];
for (var i = 0; i < WScript.Arguments.length; i++) {
args[i] = WScript.Arguments.Item(i);
}
var fileStreamObjectPool: any[] = [];
function getFileStreamObject(): any {
if (fileStreamObjectPool.length > 0) {
return fileStreamObjectPool.pop();
}
else {
return new ActiveXObject("ADODB.Stream");
}
}
function releaseFileStreamObject(obj: any) {
fileStreamObjectPool.push(obj);
}
return {
args: args,
newLine: "\r\n",
write(s: string): void {
WScript.StdOut.Write(s);
},
writeErr(s: string): void {
WScript.StdErr.Write(s);
},
readFile(fileName: string): string {
var contents: string;
try {
// Initially just read the first two bytes of the file to see if there's a bom.
var fileStream = getFileStreamObject();
fileStream.Open();
fileStream.Type = 2; // Text data
// Start reading individual chars without any interpretation. That way we can check for a byte-order-mark.
fileStream.Charset = "x-ansi";
fileStream.LoadFromFile(fileName);
var byteOrderMarkSeq: string = fileStream.ReadText(2) || ""; // Read the BOM char-seq or fall back to an empty string
// Position has to be at 0 before changing the encoding
fileStream.Position = 0;
if (byteOrderMarkSeq.charCodeAt(0) === 0xFE && byteOrderMarkSeq.charCodeAt(1) === 0xFF) {
// utf16-be
fileStream.Charset = "unicode";
}
else if (byteOrderMarkSeq.charCodeAt(0) === 0xFF && byteOrderMarkSeq.charCodeAt(1) === 0xFE) {
// utf16-le
fileStream.Charset = "unicode";
}
else if (byteOrderMarkSeq.charCodeAt(0) === 0xEF && byteOrderMarkSeq.charCodeAt(1) === 0xBB) {
// utf-8
fileStream.Charset = "utf-8";
}
else {
// Always read a file as utf8 if it has no bom.
fileStream.Charset = "utf-8";
}
contents = fileStream.ReadText(-1 /* Read from beginning to end-of-stream */);
fileStream.Close();
releaseFileStreamObject(fileStream);
}
catch (err) {
// -2147024809 is the javascript value for 0x80070057 which is the HRESULT for
// "the parameter is incorrect".
if (err.number === -2147024809) {
err.code = ErrorCodes.UnsupportedFileEncoding;
}
else {
err.code = ErrorCodes.CannotReadFile;
}
throw err;
}
return contents;
},
writeFile(fileName: string, data: string): void {
var textStream = getFileStreamObject();
textStream.Charset = "utf-8";
textStream.Open();
textStream.WriteText(data, 0 /*do not add newline*/);
textStream.SaveToFile(fileName, 2 /*overwrite*/);
textStream.Close();
releaseFileStreamObject(textStream);
},
resolvePath(path: string): string {
return fso.GetAbsolutePathName(path);
},
fileExists(path: string): boolean {
return fso.FileExists(path);
},
directoryExists(path: string) {
return fso.FolderExists(path);
},
createDirectory(directoryName: string) {
if (!this.directoryExists(directoryName)) {
fso.CreateFolder(directoryName);
}
},
getExecutingFilePath() {
return WScript.ScriptFullName;
},
getCurrentDirectory() {
return new ActiveXObject("WScript.Shell").CurrentDirectory;
},
getMemoryUsage() {
return 0;
},
exit(exitCode?: number): void {
WScript.Quit(exitCode);
},
useCaseSensitiveFileNames: false,
};
}
function getNodeSystem(): System {
var _fs = require("fs");
var _path = require("path");
var _os = require("os");
var platform: string = _os.platform();
// win32\win64 are case insensitive platforms, MacOS (darwin) by default is also case insensitive
var useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
return {
args: process.argv.slice(2),
newLine: _os.EOL,
write(s: string): void {
process.stdout.write(s);
},
writeErr(s: string): void {
process.stderr.write(s);
},
readFile(fileName: string): string {
try {
var buffer = _fs.readFileSync(fileName);
// Make sure buffer got initialized and that we don't try to read into a completely empty file.
if (!buffer || buffer.length === 0) {
return "";
}
switch (buffer[0]) {
case 0xFE:
if (buffer[1] === 0xFF) {
// utf16-be. Reading the buffer as big endian is not supported, so convert it to
// Little Endian first
var i = 0;
while ((i + 1) < buffer.length) {
var temp = buffer[i];
buffer[i] = buffer[i + 1];
buffer[i + 1] = temp;
i += 2;
}
return buffer.toString("utf16le", 2);
}
break;
case 0xFF:
if (buffer[1] === 0xFE) {
// utf16-le
return buffer.toString("utf16le", 2);
}
break;
case 0xEF:
if (buffer[1] === 0xBB) {
// utf-8
return buffer.toString("utf8", 3);
}
}
return buffer.toString("utf8", 0);
}
catch (err) {
err.code = ErrorCodes.CannotReadFile;
throw err;
}
},
writeFile(fileName: string, data: string): void {
// TODO (drosen): bring back the old environment code if necessary
_fs.writeFileSync(fileName, data, "utf8");
},
resolvePath: function (path: string): string {
return _path.resolve(path);
},
fileExists(path: string): boolean {
return _fs.existsSync(path);
},
directoryExists(path: string) {
return _fs.existsSync(path) && _fs.statSync(path).isDirectory();
},
createDirectory(directoryName: string) {
if (!this.directoryExists(directoryName)) {
_fs.mkdirSync(directoryName);
}
},
getExecutingFilePath() {
return process.mainModule.filename;
},
getCurrentDirectory() {
return (<any>process).cwd();
},
getMemoryUsage() {
global.gc();
return process.memoryUsage().heapUsed;
},
exit(exitCode?: number): void {
process.exit(exitCode);
},
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
};
}
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
return getWScriptSystem();
}
else if (typeof module !== "undefined" && module.exports) {
return getNodeSystem();
}
else {
return undefined; // Unsupported host
}
})();
function getCanonicalFileName(fileName: string): string {
// if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form.
// otherwise use toLowerCase as a canonical form.
return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
}

241
src/compiler/tc.ts Normal file
View File

@ -0,0 +1,241 @@
/// <reference path="core.ts"/>
/// <reference path="sys.ts"/>
/// <reference path="types.ts"/>
/// <reference path="scanner.ts"/>
/// <reference path="parser.ts"/>
/// <reference path="binder.ts"/>
/// <reference path="checker.ts"/>
/// <reference path="emitter.ts"/>
/// <reference path="commandLineParser.ts"/>
module ts {
/// Checks to see if the locale is in the appropriate format,
/// and if it is, attempt to set the appropriate language.
function validateLocaleAndSetLanguage(locale: string, errors: Diagnostic[]): boolean {
var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
if (!matchResult) {
errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, 'en', 'ja-jp'));
return false;
}
var language = matchResult[1];
var territory = matchResult[3];
// First try the entire locale, then fall back to just language if that's all we have.
if (!trySetLanguageAndTerritory(language, territory, errors) &&
!trySetLanguageAndTerritory(language, undefined, errors)) {
errors.push(createCompilerDiagnostic(Diagnostics.Unsupported_locale_0, locale));
return false;
}
return true;
}
function trySetLanguageAndTerritory(language: string, territory: string, errors: Diagnostic[]): boolean {
var compilerFilePath = sys.getExecutingFilePath();
var containingDirectoryPath = getDirectoryPath(compilerFilePath);
var filePath = combinePaths(containingDirectoryPath, language);
if (territory) {
filePath = filePath + "-" + territory;
}
filePath = sys.resolvePath(combinePaths(filePath, "diagnosticMessages.generated.json"));
if (!sys.fileExists(filePath)) {
return false;
}
// TODO: Add codePage support for readFile?
try {
var fileContents = sys.readFile(filePath);
}
catch (e) {
errors.push(createCompilerDiagnostic(Diagnostics.Unable_to_open_file_0, filePath));
return false;
}
try {
localizedDiagnosticMessages = JSON.parse(fileContents);
}
catch (e) {
errors.push(createCompilerDiagnostic(Diagnostics.Corrupted_locale_file_0, filePath));
return false;
}
return true;
}
function countLines(program: Program): number {
var count = 0;
forEach(program.getSourceFiles(), file => {
count += file.getLineAndCharacterFromPosition(file.end).line;
});
return count;
}
// TODO (drosen): Make localize-friendly
var hasReportedErrors = false;
function reportErrors(errors: Diagnostic[]) {
for (var i = 0; i < errors.length; i++) {
var error = errors[i];
// TODO(jfreeman): Remove assert
Debug.assert(error.messageText.indexOf("{NL}") < 0);
if (error.file) {
var loc = error.file.getLineAndCharacterFromPosition(error.start);
sys.writeErr(error.file.filename + "(" + loc.line + "," + loc.character + "): " + error.messageText + sys.newLine);
}
else {
sys.writeErr(error.messageText + sys.newLine);
}
hasReportedErrors = true;
}
}
function padLeft(s: string, length: number) {
while (s.length < length) s = " " + s;
return s;
}
function padRight(s: string, length: number) {
while (s.length < length) s = s + " ";
return s;
}
function reportDiagnostic(name: string, value: string) {
sys.writeErr(padRight(name + ":", 12) + padLeft(value.toString(), 10) + sys.newLine);
}
function reportDiagnosticCount(name: string, count: number) {
reportDiagnostic(name, "" + count);
}
function reportDiagnosticTime(name: string, time: number) {
reportDiagnostic(name, (time / 1000).toFixed(2) + "s");
}
function getSourceFile(filename: string, languageVersion: ScriptTarget): SourceFile {
try {
var text = sys.readFile(filename);
}
catch (err) {
return undefined;
}
return createSourceFile(filename, text, languageVersion);
}
function writeFile(fileName: string, data: string) {
function ensureDirectoryStructure(directoryName: string) {
if (directoryName) {
if (!sys.directoryExists(directoryName)) {
var parentDirectory = getDirectoryPath(directoryName);
// If we arent at the root path ensure that the folder exists
if (parentDirectory !== directoryName) {
if (ensureDirectoryStructure(parentDirectory)) {
// If parent directory was present, create the current directory
try {
sys.createDirectory(directoryName);
}
catch (e) {
reportErrors([createCompilerDiagnostic(Diagnostics.Could_not_create_directory_0, [directoryName])]);
return false;
}
}
}
}
}
return true;
}
// If parent directory structure is present create the file
if (ensureDirectoryStructure(getDirectoryPath(normalizePath(fileName)))) {
try {
sys.writeFile(fileName, data);
}
catch (e) {
reportErrors([createCompilerDiagnostic(Diagnostics.Could_not_write_file_0, [fileName])]);
}
}
}
var currentDirectory: string;
function getCurrentDictory() {
currentDirectory = currentDirectory || sys.getCurrentDirectory();
return currentDirectory;
}
function createCompilerHost(): CompilerHost {
return {
getSourceFile: getSourceFile,
getDefaultLibFilename: () => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), "lib.d.ts"),
writeFile: writeFile,
getCurrentDirectory: getCurrentDictory,
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames,
getCanonicalFileName: getCanonicalFileName
};
}
export function executeCommandLine(args: string[]): number {
var cmds = parseCommandLine(args);
if (cmds.filenames.length === 0 && !(cmds.options.help || cmds.options.version)) {
cmds.errors.push(createCompilerDiagnostic(Diagnostics.No_input_files_specified));
}
if (cmds.options.version) {
}
if (cmds.filenames.length === 0 || cmds.options.help) {
// TODO (drosen): Usage.
}
// If a locale has been set but fails to load, act as if it was never specified,
// but collect the errors to report along the way.
if (cmds.options.locale) {
validateLocaleAndSetLanguage(cmds.options.locale, cmds.errors);
}
if (cmds.errors.length) {
reportErrors(cmds.errors);
return 1;
}
var parseStart = new Date().getTime();
var program = createProgram(cmds.filenames, cmds.options, createCompilerHost());
var bindStart = new Date().getTime();
var errors = program.getDiagnostics();
if (errors.length) {
var checkStart = bindStart;
var emitStart = bindStart;
var reportStart = bindStart;
}
else {
var checker = program.getTypeChecker();
var checkStart = new Date().getTime();
errors = checker.getDiagnostics();
var emitStart = new Date().getTime();
checker.emitFiles();
var reportStart = new Date().getTime();
}
reportErrors(errors);
if (cmds.options.diagnostics) {
reportDiagnosticCount("Files", program.getSourceFiles().length);
reportDiagnosticCount("Lines", countLines(program));
reportDiagnosticCount("Nodes", checker.getNodeCount());
reportDiagnosticCount("Identifiers", checker.getIdentifierCount());
reportDiagnosticCount("Symbols", checker.getSymbolCount());
reportDiagnosticCount("Types", checker.getTypeCount());
reportDiagnosticTime("Parse time", bindStart - parseStart);
reportDiagnosticTime("Bind time", checkStart - bindStart);
reportDiagnosticTime("Check time", emitStart - checkStart);
reportDiagnosticTime("Emit time", reportStart - emitStart);
reportDiagnosticTime("Total time", reportStart - parseStart);
}
return hasReportedErrors ? 1 : 0;
}
}
ts.executeCommandLine(sys.args);

1075
src/compiler/types.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,468 @@
/// <reference path='harness.ts' />
/// <reference path='runnerbase.ts' />
/// <reference path='typeWriter.ts' />
/// <reference path='syntacticCleaner.ts' />
enum CompilerTestType {
Conformance,
Regressions,
Test262
}
class CompilerBaselineRunner extends RunnerBase {
private basePath = 'tests/cases';
private errors: boolean;
private emit: boolean;
private decl: boolean;
private output: boolean;
public options: string;
constructor(public testType?: CompilerTestType) {
super();
this.errors = true;
this.emit = true;
this.decl = true;
this.output = true;
if (testType === CompilerTestType.Conformance) {
this.basePath += '/conformance';
}
else if (testType === CompilerTestType.Regressions) {
this.basePath += '/compiler';
}
else if (testType === CompilerTestType.Test262) {
this.basePath += '/test262';
} else {
this.basePath += '/compiler'; // default to this for historical reasons
}
}
public checkTestCodeOutput(fileName: string) {
describe('compiler tests for ' + fileName, () => {
// strips the fileName from the path.
var justName = fileName.replace(/^.*[\\\/]/, '');
var content = Harness.IO.readFile(fileName);
var testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
var units = testCaseContent.testUnitData;
var tcSettings = testCaseContent.settings;
var createNewInstance = false;
var lastUnit = units[units.length - 1];
var result: Harness.Compiler.CompilerResult;
var options: ts.CompilerOptions;
// equivalent to the files that will be passed on the command line
var toBeCompiled: { unitName: string; content: string }[];
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
var otherFiles: { unitName: string; content: string }[];
var harnessCompiler: Harness.Compiler.HarnessCompiler;
var createNewInstance = false;
before(() => {
harnessCompiler = Harness.Compiler.getCompiler();
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
toBeCompiled = [];
otherFiles = [];
var rootDir = lastUnit.originalFilePath.indexOf('conformance') === -1 ? 'tests/cases/compiler/' : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf('/')) + '/';
if (/require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
toBeCompiled.push({ unitName: rootDir + lastUnit.name, content: lastUnit.content });
units.forEach(unit => {
if (unit.name !== lastUnit.name) {
otherFiles.push({ unitName: rootDir + unit.name, content: unit.content });
}
});
} else {
toBeCompiled = units.map(unit => {
return { unitName: rootDir + unit.name, content: unit.content };
});
}
options = harnessCompiler.compileFiles(toBeCompiled, otherFiles, function (compileResult) {
result = compileResult;
}, function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
});
});
beforeEach(() => {
/* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need
a fresh compiler instance for themselves and then create a fresh one for the next test. Would be nice to get dev fixes
eventually to remove this limitation. */
for (var i = 0; i < tcSettings.length; ++i) {
if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) {
harnessCompiler = Harness.Compiler.getCompiler({
useExistingInstance: false,
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: tcSettings[i].flag === "noimplicitany" }
});
harnessCompiler.setCompilerSettings(tcSettings);
createNewInstance = true;
}
}
});
afterEach(() => {
if (createNewInstance) {
harnessCompiler = Harness.Compiler.getCompiler({
useExistingInstance: false,
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
});
createNewInstance = false;
}
});
// check errors
it('Correct errors for ' + fileName, () => {
if (this.errors) {
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.ts$/, '.errors.txt'), (): string => {
if (result.errors.length === 0) return null;
var outputLines: string[] = [];
// Count up all the errors we find so we don't miss any
var totalErrorsReported = 0;
// 'merge' the lines of each input file with any errors associated with it
toBeCompiled.concat(otherFiles).forEach(inputFile => {
// Filter down to the errors in the file
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
var fileErrors = result.errors.filter(e => {
var errFn = e.filename;
return errFn && errFn.indexOf(inputFile.unitName) === errFn.length - inputFile.unitName.length;
});
// Add this to the number of errors we've seen so far
totalErrorsReported += fileErrors.length;
// Header
outputLines.push('==== ' + inputFile.unitName + ' (' + fileErrors.length + ' errors) ====');
// Make sure we emit something for every error
var markedErrorCount = 0;
// For each line, emit the line followed by any error squiggles matching this line
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
// we have to string-based splitting instead and try to figure out the delimiting chars
// var fileLineMap = TypeScript.LineMap1.fromString(inputFile.content);
var lines = inputFile.content.split('\n');
var currentLineStart = 0;
lines.forEach((line, lineIndex) => {
if (line.length > 0 && line.charAt(line.length - 1) === '\r') {
line = line.substr(0, line.length - 1);
}
var thisLineStart = currentLineStart; //fileLineMap.getLineStartPosition(lineIndex);
var nextLineStart: number;
// On the last line of the file, fake the next line start number so that we handle errors on the last character of the file correctly
if (lineIndex === lines.length - 1) {
nextLineStart = inputFile.content.length;
} else {
nextLineStart = currentLineStart + line.length + 1; //fileLineMap.getLineStartPosition(lineIndex + 1);
}
// Emit this line from the original file
outputLines.push(' ' + line);
fileErrors.forEach(err => {
// Does any error start or continue on to this line? Emit squiggles
if ((err.end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
// How many characters from the start of this line the error starts at (could be positive or negative)
var relativeOffset = err.start - thisLineStart;
// How many characters of the error are on this line (might be longer than this line in reality)
var length = (err.end - err.start) - Math.max(0, thisLineStart - err.start);
// Calculate the start of the squiggle
var squiggleStart = Math.max(0, relativeOffset);
// TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another
outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~'));
// If the error ended here, or we're at the end of the file, emit its message
if ((lineIndex === lines.length - 1) || nextLineStart > err.end) {
// Just like above, we need to do a split on a string instead of on a regex
// because the JS engine does regexes wrong
var errLines = RunnerBase.removeFullPaths(err.message)
.split('\n')
.map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s)
.filter(s => s.length > 0)
.map(s => '!!! ' + s);
errLines.forEach(e => outputLines.push(e));
markedErrorCount++;
}
}
});
currentLineStart += line.length + 1; // +1 for the \n character
});
// Verify we didn't miss any errors in this file
assert.equal(markedErrorCount, fileErrors.length, 'count of errors in ' + inputFile.unitName);
});
// Verify we didn't miss any errors in total
// NEWTODO: Re-enable this -- somehow got broken
// assert.equal(totalErrorsReported, result.errors.length, 'total number of errors');
return outputLines.join('\r\n');
});
}
});
// Source maps?
it('Correct sourcemap content for ' + fileName, () => {
if (result.sourceMapRecord) {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.ts$/, '.sourcemap.txt'), () => {
return result.sourceMapRecord;
});
}
});
/*
it(".d.ts compiles without error", () => {
// if the .d.ts is non-empty, confirm it compiles correctly as well
if (this.decl && result.declFilesCode.length > 0 && result.errors.length === 0) {
var declErrors: string[] = undefined;
var declOtherFiles: { unitName: string; content: string }[] = [];
// use other files if it is dts
for (var i = 0; i < otherFiles.length; i++) {
if (TypeScript.isDTSFile(otherFiles[i].unitName)) {
declOtherFiles.push(otherFiles[i]);
}
}
for (var i = 0; i < result.declFilesCode.length; i++) {
var declCode = result.declFilesCode[i];
// don't want to use the fullpath for the unitName or the file won't be resolved correctly
// TODO: wrong path for conformance tests?
var declFile = { unitName: 'tests/cases/compiler/' + Harness.getFileName(declCode.fileName), content: declCode.code };
if (i != result.declFilesCode.length - 1) {
declOtherFiles.push(declFile);
}
}
harnessCompiler.compileFiles(
[declFile],
declOtherFiles,
(result) => {
declErrors = result.errors.map(err => err.message + "\r\n");
},
function (settings) {
harnessCompiler.setCompilerSettings(tcSettings);
});
if (declErrors && declErrors.length) {
throw new Error('.d.ts file output of ' + fileName + ' did not compile. Errors: ' + declErrors.map(err => JSON.stringify(err)).join('\r\n'));
}
}
});
*/
it('Correct JS output for ' + fileName, () => {
if (!ts.fileExtensionIs(lastUnit.name, '.d.ts') && this.emit) {
if (result.files.length === 0 && result.errors.length === 0) {
throw new Error('Expected at least one js file to be emitted or at least one error to be created.');
}
// check js output
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.ts/, '.js'), () => {
var tsCode = '';
var tsSources = otherFiles.concat(toBeCompiled);
if (tsSources.length > 1) {
tsCode += '//// [' + fileName + '] ////\r\n\r\n';
}
for (var i = 0; i < tsSources.length; i++) {
tsCode += '//// [' + Harness.Path.getFileName(tsSources[i].unitName) + ']\r\n';
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? '\r\n' : '');
}
var jsCode = '';
for (var i = 0; i < result.files.length; i++) {
jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n';
jsCode += result.files[i].code;
// Re-enable this if we want to do another comparison of old vs new compiler baselines
// jsCode += SyntacticCleaner.clean(result.files[i].code);
}
if (result.declFilesCode.length > 0) {
jsCode += '\r\n\r\n';
for (var i = 0; i < result.files.length; i++) {
jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n';
jsCode += result.declFilesCode[i].code;
}
}
if (jsCode.length > 0) {
return tsCode + '\r\n\r\n' + jsCode;
} else {
return null;
}
});
}
});
it('Correct Sourcemap output for ' + fileName, () => {
if (options.sourceMap) {
if (result.sourceMaps.length !== result.files.length) {
throw new Error('Number of sourcemap files should be same as js files.');
}
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.ts/, '.js.map'), () => {
var sourceMapCode = '';
for (var i = 0; i < result.sourceMaps.length; i++) {
sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n';
sourceMapCode += result.sourceMaps[i].code;
}
return sourceMapCode;
});
}
});
it('Correct type baselines for ' + fileName, () => {
// NEWTODO: Type baselines
if (/* ! */ false && /* ! */ result.errors.length === 0) {
Harness.Baseline.runBaseline('Correct expression types for ' + fileName, justName.replace(/\.ts/, '.types'), () => {
// TODO: Rewrite this part
//var compiler = new TypeScript.TypeScriptCompiler(
// new TypeScript.NullLogger(), TypeScript.ImmutableCompilationSettings.defaultSettings());
//compiler.addFile('lib.d.ts', TypeScript.ScriptSnapshot.fromString(Harness.Compiler.libTextMinimal),
// TypeScript.ByteOrderMark.None, /*version:*/ "0", /*isOpen:*/ true);
//var allFiles = toBeCompiled.concat(otherFiles);
//allFiles.forEach(file => {
// compiler.addFile(file.unitName, TypeScript.ScriptSnapshot.fromString(file.content),
// TypeScript.ByteOrderMark.None, /*version:*/ "0", /*isOpen:*/ true);
//});
var allFiles: any[] = [];
var compiler: any = undefined;
var typeBaselineText = '';
var typeLines: string[] = [];
var typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
allFiles.forEach(file => {
var codeLines = file.content.split('\n');
var walker = new TypeWriterWalker(file.unitName, compiler);
walker.run();
walker.results.forEach(result => {
var formattedLine = result.identifierName + " : " + result.type;
if (!typeMap[file.unitName]) {
typeMap[file.unitName] = {}
}
var typeInfo = [formattedLine];
var existingTypeInfo = typeMap[file.unitName][result.line];
if (existingTypeInfo) {
typeInfo = existingTypeInfo.concat(typeInfo);
}
typeMap[file.unitName][result.line] = typeInfo;
});
var typeBaselineText = '';
var typeLines: string[] = [];
var typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
allFiles.forEach(file => {
var codeLines = file.content.split('\n');
var walker = new TypeWriterWalker(file.unitName, compiler);
walker.run();
walker.results.forEach(result => {
var formattedLine = result.identifierName + " : " + result.type;
if (!typeMap[file.unitName]) {
typeMap[file.unitName] = {}
} else {
typeLines.push('No type information for this code.');
}
});
});
typeLines.push('=== ' + file.unitName + ' ===\r\n');
for (var i = 0; i < codeLines.length; i++) {
var currentCodeLine = codeLines[i];
var lastLine = typeLines[typeLines.length];
typeLines.push(currentCodeLine + '\r\n');
if (typeMap[file.unitName]) {
var typeInfo = typeMap[file.unitName][i];
if (typeInfo) {
var leadingSpaces = '';
typeInfo.forEach(ty => {
typeLines.push('>' + ty + '\r\n');
});
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === '')) {
} else {
typeLines.push('\r\n');
}
}
} else {
typeLines.push('No type information for this code.');
}
}
});
return typeLines.join('');
});
}
});
});
}
public initializeTests() {
describe("Setup compiler for compiler baselines", () => {
var harnessCompiler = Harness.Compiler.getCompiler({
useExistingInstance: false,
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
});
this.parseOptions();
});
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
if (this.tests.length === 0) {
var testFiles = this.enumerateFiles(this.basePath, /\.ts$/, { recursive: true });
testFiles.forEach(fn => {
fn = fn.replace(/\\/g, "/");
this.checkTestCodeOutput(fn);
});
}
else {
this.tests.forEach(test => this.checkTestCodeOutput(test));
}
describe("Cleanup after compiler baselines", () => {
var harnessCompiler = Harness.Compiler.getCompiler({
useExistingInstance: false,
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
});
});
}
private parseOptions() {
if (this.options && this.options.length > 0) {
this.errors = false;
this.emit = false;
this.decl = false;
this.output = false;
var opts = this.options.split(',');
for (var i = 0; i < opts.length; i++) {
switch (opts[i]) {
case 'error':
this.errors = true;
break;
case 'emit':
this.emit = true;
break;
case 'decl':
this.decl = true;
break;
case 'output':
this.output = true;
break;
default:
throw new Error('unsupported flag');
}
}
}
}
}

74
src/harness/exec.ts Normal file
View File

@ -0,0 +1,74 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Allows for executing a program with command-line arguments and reading the result
interface IExec {
exec: (fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) => void;
}
class ExecResult {
public stdout = "";
public stderr = "";
public exitCode: number;
}
class WindowsScriptHostExec implements IExec {
public exec(fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) : void {
var result = new ExecResult();
var shell = new ActiveXObject('WScript.Shell');
try {
var process = shell.Exec(fileName + ' ' + cmdLineArgs.join(' '));
} catch(e) {
result.stderr = e.message;
result.exitCode = 1
handleResult(result);
return;
}
// Wait for it to finish running
while (process.Status != 0) { /* todo: sleep? */ }
result.exitCode = process.ExitCode;
if(!process.StdOut.AtEndOfStream) result.stdout = process.StdOut.ReadAll();
if(!process.StdErr.AtEndOfStream) result.stderr = process.StdErr.ReadAll();
handleResult(result);
}
}
class NodeExec implements IExec {
public exec(fileName: string, cmdLineArgs: string[], handleResult: (ExecResult: ExecResult) => void) : void {
var nodeExec = require('child_process').exec;
var result = new ExecResult();
result.exitCode = null;
var cmdLine = fileName + ' ' + cmdLineArgs.join(' ');
var process = nodeExec(cmdLine, function(error: any, stdout: string, stderr: string) {
result.stdout = stdout;
result.stderr = stderr;
result.exitCode = error ? error.code : 0;
handleResult(result);
});
}
}
var Exec: IExec = function() : IExec {
var global = <any>Function("return this;").call(null);
if(typeof global.ActiveXObject !== "undefined") {
return new WindowsScriptHostExec();
} else {
return new NodeExec();
}
}();

175
src/harness/external/chai.d.ts vendored Normal file
View File

@ -0,0 +1,175 @@
// Type definitions for chai 1.7.2
// Project: http://chaijs.com/
// Definitions by: Jed Hunsaker <https://github.com/jedhunsaker/>
// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
declare module chai {
function expect(target: any, message?: string): Expect;
// Provides a way to extend the internals of Chai
function use(fn: (chai: any, utils: any) => void): any;
interface ExpectStatic {
(target: any): Expect;
}
interface Assertions {
attr(name: string, value?: string): any;
css(name: string, value?: string): any;
data(name: string, value?: string): any;
class(className: string): any;
id(id: string): any;
html(html: string): any;
text(text: string): any;
value(value: string): any;
visible: any;
hidden: any;
selected: any;
checked: any;
disabled: any;
empty: any;
exist: any;
}
interface Expect extends LanguageChains, NumericComparison, TypeComparison, Assertions {
not: Expect;
deep: Deep;
a: TypeComparison;
an: TypeComparison;
include: Include;
contain: Include;
ok: Expect;
true: Expect;
false: Expect;
null: Expect;
undefined: Expect;
exist: Expect;
empty: Expect;
arguments: Expect;
Arguments: Expect;
equal: Equal;
equals: Equal;
eq: Equal;
eql: Equal;
eqls: Equal;
property: Property;
ownProperty: OwnProperty;
haveOwnProperty: OwnProperty;
length: Length;
lengthOf: Length;
match(RegularExpression: RegExp, message?: string): Expect;
string(string: string, message?: string): Expect;
keys: Keys;
key(string: string): Expect;
throw: Throw;
throws: Throw;
Throw: Throw;
respondTo(method: string, message?: string): Expect;
itself: Expect;
satisfy(matcher: Function, message?: string): Expect;
closeTo(expected: number, delta: number, message?: string): Expect;
members: Members;
}
interface LanguageChains {
to: Expect;
be: Expect;
been: Expect;
is: Expect;
that: Expect;
and: Expect;
have: Expect;
with: Expect;
at: Expect;
of: Expect;
same: Expect;
}
interface NumericComparison {
above: NumberComparer;
gt: NumberComparer;
greaterThan: NumberComparer;
least: NumberComparer;
gte: NumberComparer;
below: NumberComparer;
lt: NumberComparer;
lessThan: NumberComparer;
most: NumberComparer;
lte: NumberComparer;
within(start: number, finish: number, message?: string): Expect;
}
interface NumberComparer {
(value: number, message?: string): Expect;
}
interface TypeComparison {
(type: string, message?: string): Expect;
instanceof: InstanceOf;
instanceOf: InstanceOf;
}
interface InstanceOf {
(constructor: Object, message?: string): Expect;
}
interface Deep {
equal: Equal;
property: Property;
}
interface Equal {
(value: any, message?: string): Expect;
}
interface Property {
(name: string, value?: any, message?: string): Expect;
}
interface OwnProperty {
(name: string, message?: string): Expect;
}
interface Length extends LanguageChains, NumericComparison {
(length: number, message?: string): Expect;
}
interface Include {
(value: Object, message?: string): Expect;
(value: string, message?: string): Expect;
(value: number, message?: string): Expect;
keys: Keys;
members: Members;
}
interface Keys {
(...keys: string[]): Expect;
(keys: any[]): Expect;
}
interface Members {
(set: any[], message?: string): Expect;
}
interface Throw {
(): Expect;
(expected: string, message?: string): Expect;
(expected: RegExp, message?: string): Expect;
(constructor: Error, expected?: string, message?: string): Expect;
(constructor: Error, expected?: RegExp, message?: string): Expect;
(constructor: Function, expected?: string, message?: string): Expect;
(constructor: Function, expected?: RegExp, message?: string): Expect;
}
function assert(expression: any, message?: string): void;
module assert {
function equal(actual: any, expected: any, message?: string): void;
function notEqual(actual: any, expected: any, message?: string): void;
function isTrue(value: any, message?: string): void;
function isFalse(value: any, message?: string): void;
function isNull(value: any, message?: string): void;
function isNotNull(value: any, message?: string): void;
}
}

225
src/harness/external/es5compat.js vendored Normal file
View File

@ -0,0 +1,225 @@
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement, fromIndex) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) {
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function (fun, thisp) {
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var res = [];
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
if (fun.call(thisp, val, i, t))
res.push(val);
}
}
return res;
};
}
if (!Array.prototype.map) {
Array.prototype.map = function (callback, thisArg) {
var T = undefined, A, k;
if (this == null) {
throw new TypeError(" this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
if ({}.toString.call(callback) != "[object Function]") {
throw new TypeError(callback + " is not a function");
}
if (thisArg) {
T = thisArg;
}
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
// the standard built-in constructor with that name and len is the value of len.
A = new Array(len);
// 7. Let k be 0
k = 0;
while (k < len) {
var kValue, mappedValue;
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Let mappedValue be the result of calling the Call internal method of callback
// with T as the this value and argument list containing kValue, k, and O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Call the DefineOwnProperty internal method of A with arguments
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
// and false.
// In browsers that support Object.defineProperty, use the following:
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
// For best browser support, use the following:
A[k] = mappedValue;
}
// d. Increase k by 1.
k++;
}
// 9. return A
return A;
};
}
if (!Array.prototype.reduce) {
Array.prototype.reduce = function reduce(accumulator) {
if (this === null || this === undefined)
throw new TypeError("Object is null or undefined");
var i = 0, l = this.length >> 0, curr;
if (typeof accumulator !== "function")
throw new TypeError("First argument is not callable");
if (arguments.length < 2) {
if (l === 0)
throw new TypeError("Array length is 0 and no second argument");
curr = this[0];
i = 1;
} else
curr = arguments[1];
while (i < l) {
if (i in this)
curr = accumulator.call(undefined, curr, this[i], i, this);
++i;
}
return curr;
};
}
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(" this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
if ({}.toString.call(callback) != "[object Function]") {
throw new TypeError(callback + " is not a function");
}
if (thisArg) {
T = thisArg;
} else {
T = undefined;
}
// 6. Let k be 0
k = 0;
while (k < len) {
var kValue;
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
if (!Date.now) {
Date.now = function () {
return (new Date()).getTime();
};
}
if (!Array.prototype.some) {
Array.prototype.some = function (fun/*, thisp */ ) {
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++) {
var idx = i.toString();
if (idx in t && fun.call(thisp, t[i], i, t))
return true;
}
return false;
};
}

354
src/harness/external/es5compat.ts vendored Normal file
View File

@ -0,0 +1,354 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/*----------------- ThirdPartyNotices -------------------------------------------------------
This file is based on or incorporates material from the projects listed below
(collectively "Third Party Code"). Microsoft is not the original author of the
Third Party Code. The original copyright notice and the license, under which
Microsoft received such Third Party Code, are set forth below. Such license and
notices are provided for informational purposes only. Microsoft licenses the Third
Party Code to you under the terms of the Apache 2.0 License.
--
Array filter Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
Array forEach Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
Array indexOf Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
Array map Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map
Array Reduce Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce
Array some Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some
String Trim Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim
Date now Compatibility Method,
Available at https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now
Copyright (c) 2007 - 2012 Mozilla Developer Network and individual contributors
Licensed by Microsoft under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and
limitations under the License.
--
Original License provided for Informational Purposes Only
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------- End of ThirdPartyNotices --------------------------------------------------- */
// Compatibility with non ES5 compliant engines
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
};
}
// Compatibility with non ES5 compliant engines
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement: any, fromIndex?: any) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len: any = t.length >>> 0;
if (len === 0) {
return -1;
}
var n: any = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
}
else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || <any>-1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k: any = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun: any, thisp?: any)
{
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var res: any[] = [];
for (var i = 0; i < len; i++)
{
if (<any>i in t)
{
var val = t[i]; // in case fun mutates this
if (fun.call(thisp, val, i, t))
res.push(val);
}
}
return res;
};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.com/#x15.4.4.19
if (!Array.prototype.map) {
Array.prototype.map = function(callback: any, thisArg?: any) {
var T: any = undefined, A: any, k: any;
if (this == null) {
throw new TypeError(" this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if ({}.toString.call(callback) != "[object Function]") {
throw new TypeError(callback + " is not a function");
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (thisArg) {
T = thisArg;
}
// 6. Let A be a new array created as if by the expression new Array(len) where Array is
// the standard built-in constructor with that name and len is the value of len.
A = new Array(len);
// 7. Let k be 0
k = 0;
// 8. Repeat, while k < len
while(k < len) {
var kValue: any, mappedValue: any;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[ k ];
// ii. Let mappedValue be the result of calling the Call internal method of callback
// with T as the this value and argument list containing kValue, k, and O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Call the DefineOwnProperty internal method of A with arguments
// Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
// and false.
// In browsers that support Object.defineProperty, use the following:
// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
// For best browser support, use the following:
A[ k ] = mappedValue;
}
// d. Increase k by 1.
k++;
}
// 9. return A
return A;
};
}
if (!Array.prototype.reduce) {
Array.prototype.reduce = function reduce(accumulator: any){
if (this===null || this===undefined) throw new TypeError("Object is null or undefined");
var i = 0, l = this.length >> 0, curr: any;
if(typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."
throw new TypeError("First argument is not callable");
if(arguments.length < 2) {
if (l === 0) throw new TypeError("Array length is 0 and no second argument");
curr = this[0];
i = 1; // start accumulating at the second element
}
else
curr = arguments[1];
while (i < l) {
if(<any>i in this) curr = accumulator.call(undefined, curr, this[i], i, this);
++i;
}
return curr;
};
}
// Compatibility with non ES5 compliant engines
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.com/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback: any, thisArg?: any) {
var T: any, k: any;
if (this == null) {
throw new TypeError(" this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0; // Hack to convert O.length to a UInt32
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if ({ }.toString.call(callback) != "[object Function]") {
throw new TypeError(callback + " is not a function");
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (thisArg) {
T = thisArg;
}
else {
T = undefined; // added to stop definite assignment error
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue: any;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
// Compatibility with non ES5 compliant engines
if (!Date.now) {
Date.now = function() {
return (new Date()).getTime();
};
}
// Compatibility with non ES5 compliant engines
// Production steps of ECMA-262, Edition 5.1, 15.4.4.17
if (!Array.prototype.some)
{
Array.prototype.some = function(fun: any /*, thisp */)
{
"use strict";
if (this == null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
var idx = i.toString(); // REVIEW: this line is not from the Mozilla page, necessary to avoid our compile time checks against non-string/any types in an in expression
if (idx in t && fun.call(thisp, t[i], i, t))
return true;
}
return false;
};
}

486
src/harness/external/json2.js vendored Normal file
View File

@ -0,0 +1,486 @@
/*
json2.js
2013-05-26
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, regexp: true */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (typeof JSON !== 'object') {
JSON = {};
}
(function () {
'use strict';
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function () {
return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z'
: null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function () {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0
? '[]'
: gap
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
: '[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function'
? walk({'': j}, '')
: j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());

486
src/harness/external/json2.ts vendored Normal file
View File

@ -0,0 +1,486 @@
/*
json2.js
2013-05-26
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, regexp: true */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (typeof JSON !== 'object') {
JSON = <any>{};
}
(function () {
'use strict';
function f(n: any) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function () {
return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z'
: null;
};
(<any>String.prototype).toJSON =
(<any>Number.prototype).toJSON =
(<any>Boolean.prototype).toJSON = function () {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap: any,
indent: any,
meta = <any>{ // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep: any;
function quote(string: string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key: any, holder: any) {
// Produce a string from holder[key].
var i: any, // The loop counter.
k: any, // The member key.
v: any, // The member value.
length: number,
mind = gap,
partial: any,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0
? '[]'
: gap
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
: '[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = <any>function (value: any, replacer: any, space: any) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i: any;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j: any;
function walk(holder: any, key: any) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k: any, v: any, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function'
? walk({'': j}, '')
: j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());

45
src/harness/external/mocha.d.ts vendored Normal file
View File

@ -0,0 +1,45 @@
// Type definitions for mocha 1.9.0
// Project: http://visionmedia.github.io/mocha/
// Definitions by: Kazi Manzur Rashid <https://github.com/kazimanzurrashid/>
// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped
declare var describe : {
(description: string, spec: () => void): void;
only(description: string, spec: () => void): void;
skip(description: string, spec: () => void): void;
timeout(ms: number): void;
}
declare var it: {
(expectation: string, assertion?: () => void): void;
(expectation: string, assertion?: (done: () => void) => void): void;
only(expectation: string, assertion?: () => void): void;
only(expectation: string, assertion?: (done: () => void) => void): void;
skip(expectation: string, assertion?: () => void): void;
skip(expectation: string, assertion?: (done: () => void) => void): void;
timeout(ms: number): void;
};
/** Runs once before any 'it' blocks in the current 'describe' are run */
declare function before(action: () => void): void;
/** Runs once before any 'it' blocks in the current 'describe' are run */
declare function before(action: (done: () => void) => void): void;
/** Runs once after all 'it' blocks in the current 'describe' are run */
declare function after(action: () => void): void;
/** Runs once after all 'it' blocks in the current 'describe' are run */
declare function after(action: (done: () => void) => void): void;
/** Runs before each individual 'it' block in the current 'describe' is run */
declare function beforeEach(action: () => void): void;
/** Runs before each individual 'it' block in the current 'describe' is run */
declare function beforeEach(action: (done: () => void) => void): void;
/** Runs after each individual 'it' block in the current 'describe' is run */
declare function afterEach(action: () => void): void;
/** Runs after each individual 'it' block in the current 'describe' is run */
declare function afterEach(action: (done: () => void) => void): void;

1296
src/harness/external/node.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

2340
src/harness/fourslash.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/// <reference path="fourslash.ts" />
var testList: string[] = [];
if (IO.arguments.length === 0) {
IO.dir(Harness.userSpecifiedroot + 'tests/ls/fourslash', /\.ts$/).forEach(fn => {
if (!fn.match(/fourslash.ts$/i)) {
testList.push(fn);
}
});
} else {
IO.arguments.forEach(tests => tests.split(',').forEach(test => {
testList.push(test);
}));
}
var passCount = 0, failCount = 0;
testList.forEach(test => {
try {
IO.print('Running ' + test.substr(IO.dirName(test).length + 1) + '... ');
FourSlash.runFourSlashTest(test);
IO.printLine('passed.');
passCount++;
} catch (e) {
IO.printLine(e);
if (e.stack) {
IO.printLine(e.stack);
}
failCount++;
}
});
IO.printLine(passCount + ' passed, ' + failCount + ' failed.');

View File

@ -0,0 +1,98 @@
///<reference path='fourslash.ts' />
///<reference path='harness.ts'/>
///<reference path='runnerbase.ts' />
class FourslashRunner extends RunnerBase {
public basePath = 'tests/cases/fourslash';
constructor() {
super();
}
public initializeTests() {
if (this.tests.length === 0) {
this.tests = this.enumerateFiles(this.basePath);
}
describe("fourslash tests", () => {
before(() => {
Harness.Compiler.getCompiler({ useExistingInstance: false });
});
this.tests.forEach((fn: string) => {
fn = Harness.Path.switchToForwardSlashes(fn);
var justName = fn.replace(/^.*[\\\/]/, '');
// Convert to relative path
var testIndex = fn.indexOf('tests/');
if (testIndex >= 0) fn = fn.substr(testIndex);
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
it('FourSlash test ' + justName + ' runs correctly', function () {
FourSlash.runFourSlashTest(fn);
});
}
});
after(() => {
Harness.Compiler.getCompiler({ useExistingInstance: false });
});
});
describe('Generate Tao XML', () => {
var invalidReasons: any = {};
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1;
}
});
var invalidReport: { reason: string; count: number }[] = [];
for (var reason in invalidReasons) {
if (invalidReasons.hasOwnProperty(reason)) {
invalidReport.push({ reason: reason, count: invalidReasons[reason] });
}
}
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
var lines: string[] = [];
lines.push('<!-- Blocked Test Report');
invalidReport.forEach((reasonAndCount) => {
lines.push(reasonAndCount.count + ' tests blocked by ' + reasonAndCount.reason);
});
lines.push('-->');
lines.push('<TaoTest xmlns="http://microsoft.com/schemas/VSLanguages/TAO">');
lines.push(' <InitTest>');
lines.push(' <StartTarget />');
lines.push(' </InitTest>');
lines.push(' <ScenarioList>');
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
lines.push('<!-- Skipped ' + xml.originalName + ', reason: ' + xml.invalidReason + ' -->');
} else {
lines.push(' <Scenario Name="' + xml.originalName + '">');
xml.actions.forEach(action => {
lines.push(' ' + action);
});
lines.push(' </Scenario>');
}
});
lines.push(' </ScenarioList>');
lines.push(' <CleanupScenario>');
lines.push(' <CloseAllDocuments />');
lines.push(' <CleanupCreatedFiles />');
lines.push(' </CleanupScenario>');
lines.push(' <CleanupTest>');
lines.push(' <CloseTarget />');
lines.push(' </CleanupTest>');
lines.push('</TaoTest>');
Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n'));
});
}
}
class GeneratedFourslashRunner extends FourslashRunner {
constructor() {
super();
this.basePath += '/generated/';
}
}

1113
src/harness/harness.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,385 @@
module Harness.LanguageService {
export class ScriptInfo {
public version: number = 1;
public editRanges: { length: number; textChangeRange: TypeScript.TextChangeRange; }[] = [];
public lineMap: TypeScript.LineMap = null;
constructor(public fileName: string, public content: string, public isOpen = true, public byteOrderMark: TypeScript.ByteOrderMark = TypeScript.ByteOrderMark.None) {
this.setContent(content);
}
private setContent(content: string): void {
this.content = content;
this.lineMap = TypeScript.LineMap1.fromString(content);
}
public updateContent(content: string): void {
this.editRanges = [];
this.setContent(content);
this.version++;
}
public editContent(minChar: number, limChar: number, newText: string): void {
// Apply edits
var prefix = this.content.substring(0, minChar);
var middle = newText;
var suffix = this.content.substring(limChar);
this.setContent(prefix + middle + suffix);
// Store edit range + new length of script
this.editRanges.push({
length: this.content.length,
textChangeRange: new TypeScript.TextChangeRange(
TypeScript.TextSpan.fromBounds(minChar, limChar), newText.length)
});
// Update version #
this.version++;
}
public getTextChangeRangeBetweenVersions(startVersion: number, endVersion: number): TypeScript.TextChangeRange {
if (startVersion === endVersion) {
// No edits!
return TypeScript.TextChangeRange.unchanged;
}
var initialEditRangeIndex = this.editRanges.length - (this.version - startVersion);
var lastEditRangeIndex = this.editRanges.length - (this.version - endVersion);
var entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex);
return TypeScript.TextChangeRange.collapseChangesAcrossMultipleVersions(entries.map(e => e.textChangeRange));
}
}
class ScriptSnapshotShim implements TypeScript.Services.IScriptSnapshotShim {
private lineMap: TypeScript.LineMap = null;
private textSnapshot: string;
private version: number;
constructor(private scriptInfo: ScriptInfo) {
this.textSnapshot = scriptInfo.content;
this.version = scriptInfo.version;
}
public getText(start: number, end: number): string {
return this.textSnapshot.substring(start, end);
}
public getLength(): number {
return this.textSnapshot.length;
}
public getLineStartPositions(): string {
if (this.lineMap === null) {
this.lineMap = TypeScript.LineMap1.fromString(this.textSnapshot);
}
return JSON.stringify(this.lineMap.lineStarts());
}
public getChangeRange(oldScript: TypeScript.Services.IScriptSnapshotShim): string {
var oldShim = <ScriptSnapshotShim>oldScript;
var range = this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version);
if (range === null) {
return null;
}
return JSON.stringify({ span: { start: range.span().start(), length: range.span().length() }, newLength: range.newLength() });
}
}
export class TypeScriptLS implements TypeScript.Services.ILanguageServiceShimHost {
IO = TypeScript.Environment ? TypeScript.Environment : Network.getEnvironment();
private ls: TypeScript.Services.ILanguageServiceShim = null;
public newLS: ts.LanguageService;
private fileNameToScript = new TypeScript.StringHashTable<ScriptInfo>();
constructor(private cancellationToken: TypeScript.ICancellationToken = TypeScript.CancellationToken.None) {
}
public addDefaultLibrary() {
this.addScript("lib.d.ts", Harness.Compiler.libText);
}
public getHostIdentifier(): string {
return "TypeScriptLS";
}
public addFile(fileName: string) {
var code = Harness.Environment.readFile(fileName);
this.addScript(fileName, code);
}
private getScriptInfo(fileName: string): ScriptInfo {
return this.fileNameToScript.lookup(fileName);
}
public addScript(fileName: string, content: string) {
var script = new ScriptInfo(fileName, content);
this.fileNameToScript.add(fileName, script);
}
public updateScript(fileName: string, content: string) {
var script = this.getScriptInfo(fileName);
if (script !== null) {
script.updateContent(content);
return;
}
this.addScript(fileName, content);
}
public editScript(fileName: string, minChar: number, limChar: number, newText: string) {
var script = this.getScriptInfo(fileName);
if (script !== null) {
script.editContent(minChar, limChar, newText);
return;
}
throw new Error("No script with name '" + fileName + "'");
}
//////////////////////////////////////////////////////////////////////
// ILogger implementation
//
public information(): boolean { return false; }
public debug(): boolean { return true; }
public warning(): boolean { return true; }
public error(): boolean { return true; }
public fatal(): boolean { return true; }
public log(s: string): void {
// For debugging...
//TypeScript.Environment.standardOut.WriteLine("TypeScriptLS:" + s);
}
//////////////////////////////////////////////////////////////////////
// ILanguageServiceShimHost implementation
//
/// Returns json for Tools.CompilationSettings
public getCompilationSettings(): string {
return ""; // i.e. default settings
}
public getCancellationToken(): TypeScript.ICancellationToken {
return this.cancellationToken;
}
public getScriptFileNames(): string {
return JSON.stringify(this.fileNameToScript.getAllKeys());
}
public getScriptSnapshot(fileName: string): TypeScript.Services.IScriptSnapshotShim {
return new ScriptSnapshotShim(this.getScriptInfo(fileName));
}
public getScriptVersion(fileName: string): string {
return this.getScriptInfo(fileName).version.toString();
}
public getScriptIsOpen(fileName: string): boolean {
return this.getScriptInfo(fileName).isOpen;
}
public getScriptByteOrderMark(fileName: string): TypeScript.ByteOrderMark {
return this.getScriptInfo(fileName).byteOrderMark;
}
public getDiagnosticsObject(): TypeScript.Services.ILanguageServicesDiagnostics {
return new LanguageServicesDiagnostics("");
}
public getLocalizedDiagnosticMessages(): string {
return "";
}
public fileExists(s: string) {
return this.IO.fileExists(s);
}
public directoryExists(s: string) {
return this.IO.directoryExists(s);
}
public resolveRelativePath(path: string, directory: string): string {
if (TypeScript.isRooted(path) || !directory) {
return this.IO.absolutePath(path);
}
else {
return this.IO.absolutePath(TypeScript.IOUtils.combine(directory, path));
}
}
public getParentDirectory(path: string): string {
return this.IO.directoryName(path);
}
/** Return a new instance of the language service shim, up-to-date wrt to typecheck.
* To access the non-shim (i.e. actual) language service, use the "ls.languageService" property.
*/
public getLanguageService(): TypeScript.Services.ILanguageServiceShim {
var ls = new TypeScript.Services.TypeScriptServicesFactory().createLanguageServiceShim(this);
this.ls = ls;
var hostAdapter = new ts.LanguageServiceShimHostAdapter(this);
this.newLS = ts.createLanguageService(hostAdapter);
return ls;
}
/** Parse file given its source text */
public parseSourceText(fileName: string, sourceText: TypeScript.IScriptSnapshot): TypeScript.SourceUnitSyntax {
var compilationSettings = new TypeScript.CompilationSettings();
compilationSettings.codeGenTarget = TypeScript.LanguageVersion.EcmaScript5;
var settings = TypeScript.ImmutableCompilationSettings.fromCompilationSettings(compilationSettings);
var parseOptions = settings.codeGenTarget();
return TypeScript.Parser.parse(fileName, TypeScript.SimpleText.fromScriptSnapshot(sourceText), parseOptions, TypeScript.isDTSFile(fileName)).sourceUnit();
}
/** Parse a file on disk given its fileName */
public parseFile(fileName: string) {
var sourceText = TypeScript.ScriptSnapshot.fromString(this.IO.readFile(fileName, /*codepage:*/ null).contents)
return this.parseSourceText(fileName, sourceText);
}
/**
* @param line 1 based index
* @param col 1 based index
*/
public lineColToPosition(fileName: string, line: number, col: number): number {
var script: ScriptInfo = this.fileNameToScript.lookup(fileName);
assert.isNotNull(script);
assert.isTrue(line >= 1);
assert.isTrue(col >= 1);
return script.lineMap.getPosition(line - 1, col - 1);
}
/**
* @param line 0 based index
* @param col 0 based index
*/
public positionToZeroBasedLineCol(fileName: string, position: number): TypeScript.ILineAndCharacter {
var script: ScriptInfo = this.fileNameToScript.lookup(fileName);
assert.isNotNull(script);
var result = script.lineMap.getLineAndCharacterFromPosition(position);
assert.isTrue(result.line() >= 0);
assert.isTrue(result.character() >= 0);
return { line: result.line(), character: result.character() };
}
/** Verify that applying edits to sourceFileName result in the content of the file baselineFileName */
public checkEdits(sourceFileName: string, baselineFileName: string, edits: TypeScript.Services.TextChange[]) {
var script = Utils.readFile(sourceFileName);
var formattedScript = this.applyEdits(script.contents, edits);
var baseline = Utils.readFile(baselineFileName).contents;
function noDiff(text1: string, text2: string) {
text1 = text1.replace(/^\s+|\s+$/g, "").replace(/\r\n?/g, "\n");
text2 = text2.replace(/^\s+|\s+$/g, "").replace(/\r\n?/g, "\n");
if (text1 !== text2) {
var errorString = "";
var text1Lines = text1.split(/\n/);
var text2Lines = text2.split(/\n/);
for (var i = 0; i < text1Lines.length; i++) {
if (text1Lines[i] !== text2Lines[i]) {
errorString += "Difference at line " + (i + 1) + ":\n";
errorString += " Left File: " + text1Lines[i] + "\n";
errorString += " Right File: " + text2Lines[i] + "\n\n";
}
}
throw (new Error(errorString));
}
}
assert.isTrue(noDiff(formattedScript, baseline));
assert.equal(formattedScript, baseline);
}
/** Apply an array of text edits to a string, and return the resulting string. */
public applyEdits(content: string, edits: TypeScript.Services.TextChange[]): string {
var result = content;
edits = this.normalizeEdits(edits);
for (var i = edits.length - 1; i >= 0; i--) {
var edit = edits[i];
var prefix = result.substring(0, edit.span.start());
var middle = edit.newText;
var suffix = result.substring(edit.span.end());
result = prefix + middle + suffix;
}
return result;
}
/** Normalize an array of edits by removing overlapping entries and sorting entries on the minChar position. */
private normalizeEdits(edits: TypeScript.Services.TextChange[]): TypeScript.Services.TextChange[] {
var result: TypeScript.Services.TextChange[] = [];
function mapEdits(edits: TypeScript.Services.TextChange[]): { edit: TypeScript.Services.TextChange; index: number; }[] {
var result: { edit: TypeScript.Services.TextChange; index: number; }[] = [];
for (var i = 0; i < edits.length; i++) {
result.push({ edit: edits[i], index: i });
}
return result;
}
var temp = mapEdits(edits).sort(function (a, b) {
var result = a.edit.span.start() - b.edit.span.start();
if (result === 0)
result = a.index - b.index;
return result;
});
var current = 0;
var next = 1;
while (current < temp.length) {
var currentEdit = temp[current].edit;
// Last edit
if (next >= temp.length) {
result.push(currentEdit);
current++;
continue;
}
var nextEdit = temp[next].edit;
var gap = nextEdit.span.start() - currentEdit.span.end();
// non-overlapping edits
if (gap >= 0) {
result.push(currentEdit);
current = next;
next++;
continue;
}
// overlapping edits: for now, we only support ignoring an next edit
// entirely contained in the current edit.
if (currentEdit.span.end() >= nextEdit.span.end()) {
next++;
continue;
}
else {
throw new Error("Trying to apply overlapping edits");
}
}
return result;
}
}
export class LanguageServicesDiagnostics implements TypeScript.Services.ILanguageServicesDiagnostics {
constructor(private destination: string) { }
public log(content: string): void {
//Imitates the LanguageServicesDiagnostics object when not in Visual Studio
}
}
}

279
src/harness/loggedIO.ts Normal file
View File

@ -0,0 +1,279 @@
/// <reference path="..\..\src\compiler\sys.ts" />
interface FileInformation {
contents: string;
codepage: number;
}
interface FindFileResult {
}
interface IOLog {
arguments: string[];
executingPath: string;
currentDirectory: string;
filesRead: {
path: string;
codepage: number;
result?: FileInformation;
}[];
filesWritten: {
path: string;
contents: string;
bom: boolean;
}[];
filesDeleted: string[];
filesAppended: {
path: string;
contents: string;
}[];
fileExists: {
path: string;
result?: boolean;
}[];
filesFound: {
path: string;
pattern: string;
result?: FindFileResult;
}[];
dirs: {
path: string;
re: string;
re_m: boolean;
re_g: boolean;
re_i: boolean;
opts: { recursive?: boolean; };
result?: string[];
}[];
dirExists: {
path: string;
result?: boolean;
}[];
dirsCreated: string[];
pathsResolved: {
path: string;
result?: string;
}[];
}
interface PlaybackControl {
startReplayFromFile(logFilename: string): void;
startReplayFromString(logContents: string): void;
startReplayFromData(log: IOLog): void;
endReplay(): void;
startRecord(logFilename: string): void;
endRecord(): void;
}
module Playback {
var recordLog: IOLog = undefined;
var replayLog: IOLog = undefined;
var recordLogFilenameBase = '';
interface Memoized<T> {
(s: string): T;
reset(): void;
}
function memoize<T>(func: (s: string) => T): Memoized<T> {
var lookup: { [s: string]: T } = {};
var run: Memoized<T> = <Memoized<T>>((s: string) => {
if (lookup.hasOwnProperty(s)) return lookup[s];
return lookup[s] = func(s);
});
run.reset = () => {
lookup = null;
};
return run;
}
export interface PlaybackSystem extends System, PlaybackControl { }
function createEmptyLog(): IOLog {
return {
arguments: [],
currentDirectory: '',
filesRead: [],
filesWritten: [],
filesDeleted: [],
filesAppended: [],
fileExists: [],
filesFound: [],
dirs: [],
dirExists: [],
dirsCreated: [],
pathsResolved: [],
executingPath: ''
};
}
function initWrapper<T>(wrapper: PlaybackControl, underlying: T) {
Object.keys(underlying).forEach(prop => {
(<any>wrapper)[prop] = (<any>underlying)[prop];
});
wrapper.startReplayFromString = logString => {
wrapper.startReplayFromData(JSON.parse(logString));
};
wrapper.startReplayFromData = log => {
replayLog = log;
};
wrapper.endReplay = () => {
replayLog = undefined;
};
wrapper.startRecord = (filenameBase) => {
recordLogFilenameBase = filenameBase;
recordLog = createEmptyLog();
};
}
function recordReplay<T extends Function>(original: T, underlying: any) {
function createWrapper(record: T, replay: T): T {
return <any>(() => {
if (replayLog !== undefined) {
return replay.apply(undefined, arguments);
} else if (recordLog !== undefined) {
return record.apply(undefined, arguments);
} else {
return original.apply(underlying, arguments);
}
});
}
return createWrapper;
}
function callAndRecord<T, U>(underlyingResult: T, logArray: U[], logEntry: U): T {
if (underlyingResult !== undefined) {
(<any>logEntry).result = underlyingResult;
}
logArray.push(logEntry);
return underlyingResult;
}
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T {
var predicate = (entry: { result?: T }) => {
return Object.getOwnPropertyNames(expectedFields).every((name) => (<any>entry)[name] === (<any>expectedFields)[name]);
};
var results = logArray.filter(entry => predicate(entry));
if (results.length === 0) {
if (defaultValue !== undefined) {
return defaultValue;
} else {
throw new Error('No matching result in log array for: ' + JSON.stringify(expectedFields));
}
}
return results[0].result;
}
function findResultByPath<T>(wrapper: { resolvePath(s: string): string }, logArray: { path: string; result?: T }[], expectedPath: string, defaultValue?: T): T {
var results = logArray.filter(e => pathsAreEquivalent(e.path, expectedPath, wrapper));
if (results.length === 0) {
if (defaultValue === undefined) {
console.log('Resolved path: ' + wrapper.resolvePath(expectedPath));
console.log('Filenames were: ' + logArray.map(x => x.path).join(', '));
throw new Error('No matching result in log array for path: ' + expectedPath);
} else {
return defaultValue;
}
}
return results[0].result;
}
function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) {
function areSame(a: string, b: string) {
return Harness.Path.switchToForwardSlashes(a).toLowerCase() === Harness.Path.switchToForwardSlashes(b).toLowerCase();
}
return areSame(left, right) || areSame(wrapper.resolvePath(left), right) || areSame(left, wrapper.resolvePath(right)) || areSame(wrapper.resolvePath(left), wrapper.resolvePath(right));
}
function noOpReplay(name: string) {
console.log("Swallowed write operation during replay: " + name);
}
export function wrapSystem(underlying: System): PlaybackSystem {
var wrapper: PlaybackSystem = <any>{};
initWrapper(wrapper, underlying);
wrapper.startReplayFromFile = logFn => {
wrapper.startReplayFromString(underlying.readFile(logFn));
};
wrapper.endRecord = () => {
if (recordLog !== undefined) {
var i = 0;
var fn = () => recordLogFilenameBase + i + '.json';
while (underlying.fileExists(fn())) i++;
underlying.writeFile(fn(), JSON.stringify(recordLog));
recordLog = undefined;
}
};
Object.defineProperty(wrapper, 'args', {
get() {
if (replayLog !== undefined) {
return replayLog.arguments;
} else if (recordLog !== undefined) {
recordLog.arguments = underlying.args;
}
return underlying.args;
}
});
wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)(
(path) => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path: path }),
memoize((path) => {
// If we read from the file, it must exist
if (findResultByPath(wrapper, replayLog.filesRead, path, null) !== null) {
return true;
} else {
return findResultByFields(replayLog.fileExists, { path: path }, false);
}
})
);
wrapper.getExecutingFilePath = () => {
if (replayLog !== undefined) {
return replayLog.executingPath;
} else if (recordLog !== undefined) {
return recordLog.executingPath = underlying.getExecutingFilePath();
} else {
return underlying.getExecutingFilePath();
}
};
wrapper.getCurrentDirectory = () => {
if (replayLog !== undefined) {
return replayLog.currentDirectory || '';
} else if (recordLog !== undefined) {
return recordLog.currentDirectory = underlying.getCurrentDirectory();
} else {
return underlying.getCurrentDirectory();
}
};
wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)(
(path) => callAndRecord(underlying.resolvePath(path), recordLog.pathsResolved, { path: path }),
memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, replayLog.currentDirectory ? replayLog.currentDirectory + '/' + path : path)));
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
(path) => callAndRecord(underlying.readFile(path), recordLog.filesRead, { path: path, codepage: 0 }),
memoize((path) => findResultByPath(wrapper, replayLog.filesRead, path).contents));
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
(path, contents) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path: path, contents: contents, bom: false }),
(path, contents) => noOpReplay('writeFile'));
wrapper.exit = (exitCode) => {
if (recordLog !== undefined) {
wrapper.endRecord();
}
underlying.exit(exitCode);
};
return wrapper;
}
}

19
src/harness/project.ts Normal file
View File

@ -0,0 +1,19 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/// <reference path="exec.ts" />
/// <reference path="generate.ts" />
/// <reference path="harness.ts" />
/// <reference path="diff.ts" />

View File

@ -0,0 +1,381 @@
///<reference path="harness.ts" />
///<reference path="runnerbase.ts" />
// Test case is json of below type in tests/cases/project/
interface ProjectRunnerTestCase {
scenario: string;
projectRoot: string; // project where it lives - this also is the current dictory when compiling
inputFiles: string[]; // list of input files to be given to program
out?: string; // --out
outDir?: string; // --outDir
sourceMap?: boolean; // --map
mapRoot?: string; // --mapRoot
resolveMapRoot?: boolean; // should we resolve this map root and give compiler the absolute disk path as map root?
sourceRoot?: string; // --sourceRoot
resolveSourceRoot?: boolean; // should we resolve this source root and give compiler the absolute disk path as map root?
declaration?: boolean; // --d
baselineCheck?: boolean; // Verify the baselines of output files, if this is false, we will write to output to the disk but there is no verification of baselines
runTest?: boolean; // Run the resulting test
bug?: string; // If there is any bug associated with this test case
}
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
// Apart from actual test case the results of the resolution
resolvedInputFiles: string[]; // List of files that were asked to read by compiler
emittedFiles: string[]; // List of files that wre emitted by the compiler
}
interface BatchCompileProjectTestCaseEmittedFile {
emittedFileName: string;
code: string;
fileName: string;
}
interface BatchCompileProjectTestCaseResult {
moduleKind: ts.ModuleKind;
program: ts.Program;
readInputFiles: ts.SourceFile[];
sourceMapData: ts.SourceMapData[];
outputFiles: BatchCompileProjectTestCaseEmittedFile[];
errors: ts.Diagnostic[];
nonSubfolderDiskFiles: number;
}
class ProjectRunner extends RunnerBase {
public initializeTests() {
if (this.tests.length === 0) {
var testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true });
testFiles.forEach(fn => {
fn = fn.replace(/\\/g, "/");
this.runProjectTestCase(fn);
});
}
else {
this.tests.forEach(test => this.runProjectTestCase(test));
}
}
private runProjectTestCase(testCaseFileName: string) {
var testCase: ProjectRunnerTestCase;
try {
var testFileText = sys.readFile(testCaseFileName);
}
catch (e) {
assert(false, "Unable to open testcase file: " + testCaseFileName + ": " + e.message);
}
try {
testCase = <ProjectRunnerTestCase>JSON.parse(testFileText);
}
catch (e) {
assert(false, "Testcase: " + testCaseFileName + " doesnt not contain valid json format: " + e.message);
}
var testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, "");
function moduleNameToString(moduleKind: ts.ModuleKind) {
return moduleKind === ts.ModuleKind.AMD
? "amd"
: moduleKind === ts.ModuleKind.CommonJS
? "node"
: "none";
}
// Project baselines verified go in project/testCaseName/moduleKind/
function getBaselineFolder(moduleKind: ts.ModuleKind) {
return "project/" + testCaseJustName + "/" + moduleNameToString(moduleKind) + "/";
}
// When test case output goes to tests/baselines/local/projectOutput/testCaseName/moduleKind/
// We have these two separate locations because when compairing baselines the baseline verifier will delete the existing file
// so even if it was created by compiler in that location, the file will be deleted by verified before we can read it
// so lets keep these two locations separate
function getProjectOutputFolder(filename: string, moduleKind: ts.ModuleKind) {
return Harness.Baseline.localPath("projectOutput/" + testCaseJustName + "/" + moduleNameToString(moduleKind) + "/" + filename);
}
function cleanProjectUrl(url: string) {
var diskProjectPath = ts.normalizeSlashes(sys.resolvePath(testCase.projectRoot));
var projectRootUrl = "file:///" + diskProjectPath;
var normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot);
diskProjectPath = diskProjectPath.substr(0, diskProjectPath.lastIndexOf(normalizedProjectRoot));
projectRootUrl = projectRootUrl.substr(0, projectRootUrl.lastIndexOf(normalizedProjectRoot));
if (url && url.length) {
if (url.indexOf(projectRootUrl) === 0) {
// replace the disk specific project url path into project root url
url = "file:///" + url.substr(projectRootUrl.length);
}
else if (url.indexOf(diskProjectPath) === 0) {
// Replace the disk specific path into the project root path
url = url.substr(diskProjectPath.length);
if (url.charCodeAt(0) != ts.CharacterCodes.slash) {
url = "/" + url;
}
}
}
return url;
}
function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult{
var nonSubfolderDiskFiles = 0;
var readInputFiles: ts.SourceFile[] = [];
var sourceMapData: ts.SourceMapData[] = null;
var outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
function createCompilerOptions(): ts.CompilerOptions {
return {
declaration: !!testCase.declaration,
sourceMap: !!testCase.sourceMap,
out: testCase.out,
outDir: testCase.outDir,
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? sys.resolvePath(testCase.mapRoot) : testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? sys.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
module: moduleKind
};
}
function getSourceFile(filename: string, languageVersion: ts.ScriptTarget): ts.SourceFile {
var sourceFile: ts.SourceFile = undefined;
if (filename === 'lib.d.ts') {
sourceFile = ts.createSourceFile('lib.d.ts', Harness.Compiler.libTextMinimal, languageVersion);
}
else {
assert.isTrue(!ts.filter(readInputFiles, sourceFile => sourceFile.filename == filename).length, "Compiler trying to read same file again: " + filename);
try {
var text = sys.readFile(ts.isRootedDiskPath(filename)
? filename
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(filename));
}
catch (e) {
// text doesn't get defined.
}
if (text !== undefined) {
sourceFile = ts.createSourceFile(filename, text, languageVersion)
}
}
if (sourceFile) {
readInputFiles.push(sourceFile);
}
return sourceFile;
}
function writeFile(filename: string, data: string) {
var diskFileName = ts.isRootedDiskPath(filename)
? filename
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(filename);
var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory(), false);
if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") {
// If the generated output file recides in the parent folder or is rooted path,
// we need to instead create files that can live in the project reference folder
// but make sure extension of these files matches with the filename the compiler asked to write
diskRelativeName = "diskFile" + nonSubfolderDiskFiles++ +
(Harness.Compiler.stringEndsWith(filename, ".d.ts") ? ".d.ts" :
Harness.Compiler.stringEndsWith(filename, ".js") ? ".js" : ".js.map");
}
if (Harness.Compiler.stringEndsWith(filename, ".js")) {
// Make sure if there is URl we have it cleaned up
var indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
if (indexOfSourceMapUrl != -1) {
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
}
}
else if (Harness.Compiler.stringEndsWith(filename, ".js.map")) {
// Make sure sources list is cleaned
var sourceMapData = JSON.parse(data);
for (var i = 0; i < sourceMapData.sources.length; i++) {
sourceMapData.sources[i] = cleanProjectUrl(sourceMapData.sources[i]);
}
sourceMapData.sourceRoot = cleanProjectUrl(sourceMapData.sourceRoot);
data = JSON.stringify(sourceMapData);
}
var outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind);
// Actual writing of file as in tc.ts
function ensureDirectoryStructure(directoryname: string) {
if (directoryname) {
if (!sys.directoryExists(directoryname)) {
ensureDirectoryStructure(ts.getDirectoryPath(directoryname));
sys.createDirectory(directoryname);
}
}
}
ensureDirectoryStructure(ts.getDirectoryPath(ts.normalizePath(outputFilePath)));
sys.writeFile(outputFilePath, data);
outputFiles.push({ emittedFileName: filename, code: data, fileName: diskRelativeName });
}
function getCurrentDirectory() {
return sys.resolvePath(testCase.projectRoot);
}
function createCompilerHost(): ts.CompilerHost {
return {
getSourceFile: getSourceFile,
getDefaultLibFilename: () => "lib.d.ts",
writeFile: writeFile,
getCurrentDirectory: getCurrentDirectory,
getCanonicalFileName: getCanonicalFileName,
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames
};
}
var program = ts.createProgram(testCase.inputFiles, createCompilerOptions(), createCompilerHost());
var errors = program.getDiagnostics();
if (!errors.length) {
var checker = program.getTypeChecker();
errors = checker.getDiagnostics();
sourceMapData = checker.emitFiles();
// Clean up source map data that will be used in baselining
if (sourceMapData) {
for (var i = 0; i < sourceMapData.length; i++) {
for (var j = 0; j < sourceMapData[i].sourceMapSources.length; j++) {
sourceMapData[i].sourceMapSources[j] = cleanProjectUrl(sourceMapData[i].sourceMapSources[j]);
}
sourceMapData[i].jsSourceMappingURL = cleanProjectUrl(sourceMapData[i].jsSourceMappingURL);
sourceMapData[i].sourceMapSourceRoot = cleanProjectUrl(sourceMapData[i].sourceMapSourceRoot);
}
}
}
return {
moduleKind: moduleKind,
program: program,
readInputFiles: readInputFiles,
sourceMapData: sourceMapData,
outputFiles: outputFiles,
errors: errors,
nonSubfolderDiskFiles: nonSubfolderDiskFiles,
};
}
describe('Compiling project for ' + testCase.scenario +': testcase ' + testCaseFileName, () => {
function verifyCompilerResults(compilerResult: BatchCompileProjectTestCaseResult) {
function getCompilerResolutionInfo() {
var resolutionInfo: ProjectRunnerTestCaseResolutionInfo = {
scenario: testCase.scenario,
projectRoot: testCase.projectRoot,
inputFiles: testCase.inputFiles,
out: testCase.out,
outDir: testCase.outDir,
sourceMap: testCase.sourceMap,
mapRoot: testCase.mapRoot,
resolveMapRoot: testCase.resolveMapRoot,
sourceRoot: testCase.sourceRoot,
resolveSourceRoot: testCase.resolveSourceRoot,
declaration: testCase.declaration,
baselineCheck: testCase.baselineCheck,
runTest: testCase.runTest,
bug: testCase.bug,
resolvedInputFiles: ts.map(compilerResult.readInputFiles, inputFile => inputFile.filename),
emittedFiles: ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName)
};
return resolutionInfo;
}
it('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, () => {
assert.equal(compilerResult.program.getSourceFiles().length, compilerResult.readInputFiles.length, "Compiler missing/has extra source files that were read during compilation");
Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => {
return JSON.stringify(getCompilerResolutionInfo(), undefined, " ");
});
});
if (compilerResult.errors.length) {
it('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, () => {
Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => {
// This is copied from tc.ts's reportError to replicate what tc does
var errors = "";
for (var i = 0; i < compilerResult.errors.length; i++) {
var error = compilerResult.errors[i];
// TODO(jfreeman): Remove assert
ts.Debug.assert(error.messageText.indexOf("{NL}") < 0);
if (error.file) {
var loc = error.file.getLineAndCharacterFromPosition(error.start);
errors += error.file.filename + "(" + loc.line + "," + loc.character + "): " + error.messageText + sys.newLine;
}
else {
errors += error.messageText + sys.newLine;
}
}
return errors;
});
});
}
if (testCase.baselineCheck) {
ts.forEach(compilerResult.outputFiles, outputFile => {
it('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, () => {
Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
try {
return sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind));
}
catch (e) {
return undefined;
}
});
});
});
if (compilerResult.sourceMapData) {
it('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, () => {
Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => {
return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program,
ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.stringEndsWith(outputFile.emittedFileName, ".js")));
});
});
}
}
}
// Compile using node
var nodeCompilerResult = batchCompilerProjectTestCase(ts.ModuleKind.CommonJS);
verifyCompilerResults(nodeCompilerResult);
// Compile using amd
var amdCompilerResult = batchCompilerProjectTestCase(ts.ModuleKind.AMD);
verifyCompilerResults(amdCompilerResult);
if (testCase.runTest) {
//TODO(ryanca/danquirk): Either support this or remove this option from the interface as well as test case json files
// Node results
assert.isTrue(!nodeCompilerResult.nonSubfolderDiskFiles, "Cant run test case that generates parent folders/absolute path");
//it("runs without error: (" + moduleNameToString(nodeCompilerResult.moduleKind) + ')', function (done: any) {
// Exec.exec("node.exe", ['"' + baseLineLocalPath(nodeCompilerResult.outputFiles[0].diskRelativeName, nodeCompilerResult.moduleKind) + '"'], function (res) {
// Harness.Assert.equal(res.stdout, "");
// Harness.Assert.equal(res.stderr, "");
// done();
// })
//});
// Amd results
assert.isTrue(!amdCompilerResult.nonSubfolderDiskFiles, "Cant run test case that generates parent folders/absolute path");
//var amdDriverTemplate = "var requirejs = require('../r.js');\n\n" +
// "requirejs.config({\n" +
// " nodeRequire: require\n" +
// "});\n\n" +
// "requirejs(['{0}'],\n" +
// "function ({0}) {\n" +
// "});";
//var moduleName = baseLineLocalPath(amdCompilerResult.outputFiles[0].diskRelativeName, amdCompilerResult.moduleKind).replace(/\.js$/, "");
//sys.writeFile(testCase.projectRoot + '/driver.js', amdDriverTemplate.replace(/\{0}/g, moduleName));
//it("runs without error (" + moduleNameToString(amdCompilerResult.moduleKind) + ')', function (done: any) {
// Exec.exec("node.exe", ['"' + testCase.projectRoot + '/driver.js"'], function (res) {
// Harness.Assert.equal(res.stdout, "");
// Harness.Assert.equal(res.stderr, "");
// done();
// })
//});
}
});
}
}

107
src/harness/runner.ts Normal file
View File

@ -0,0 +1,107 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/// <reference path='compilerRunner.ts' />
// TODO: re-enable
// ///<reference path='fourslashRunner.ts' />
/// <reference path='projectsRunner.ts' />
/// <reference path='rwcRunner.ts' />
/// <reference path='unittestrunner.ts' />
function runTests(runners: RunnerBase[]) {
if (reverse) {
runners = runners.reverse();
}
for (var i = iterations; i > 0; i--) {
for (var j = 0; j < runners.length; j++) {
runners[j].initializeTests();
}
}
}
var runners: RunnerBase[] = [];
global.runners = runners;
var reverse: boolean = false;
var iterations: number = 1;
// users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options
var mytestconfig = 'mytest.config';
var testconfig = 'test.config';
var testConfigFile =
Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) :
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '')
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]] : [];
for (var i = 0; i < options.length; i++) {
switch (options[i]) {
case 'compiler':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
runners.push(new ProjectRunner());
break;
case 'conformance':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
break;
case 'project':
runners.push(new ProjectRunner());
break;
case 'fourslash':
// TODO: Re-enable Fourslash tests
// runners.push(new FourslashRunner());
break;
case 'fourslash-generated':
// TODO: Re-enable Fourslash tests
// runners.push(new GeneratedFourslashRunner());
break;
case 'unittests':
runners.push(new UnitTestRunner(UnittestTestType.Compiler));
break;
case 'rwc':
runners.push(new RWCRunner());
break;
case 'ls':
runners.push(new UnitTestRunner(UnittestTestType.LanguageService));
break;
case 'services':
runners.push(new UnitTestRunner(UnittestTestType.Services));
break;
case 'reverse':
reverse = true;
break;
}
}
}
if (runners.length === 0) {
// compiler
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
// TODO: project tests don't work in the browser yet
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
runners.push(new ProjectRunner());
}
//// language services
// TODO: Re-enable Fourslash runner
// runners.push(new FourslashRunner());
// runners.push(new GeneratedFourslashRunner());
}
runTests(runners);

41
src/harness/runnerbase.ts Normal file
View File

@ -0,0 +1,41 @@
/// <reference path="harness.ts" />
class RunnerBase {
constructor() { }
// contains the tests to run
public tests: string[] = [];
/** Add a source file to the runner's list of tests that need to be initialized with initializeTests */
public addTest(fileName: string) {
this.tests.push(fileName);
}
public enumerateFiles(folder: string, regex?: RegExp, options?: { recursive: boolean }): string[] {
return Harness.IO.listFiles(Harness.userSpecifiedroot + folder, regex, { recursive: (options ? options.recursive : false) });
}
/** Setup the runner's tests so that they are ready to be executed by the harness
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
*/
public initializeTests(): void {
throw new Error('method not implemented');
}
/** Replaces instances of full paths with filenames only */
static removeFullPaths(path: string) {
var fixedPath = path;
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.ts/g;
var fullPathList = fixedPath.match(fullPath);
if (fullPathList) {
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));
}
// when running in the browser the 'full path' is the host name, shows up in error baselines
var localHost = /http:\/localhost:\d+/g;
fixedPath = fixedPath.replace(localHost, '');
return fixedPath;
}
}

223
src/harness/rwcRunner.ts Normal file
View File

@ -0,0 +1,223 @@
/// <reference path='harness.ts'/>
/// <reference path='runnerbase.ts' />
/// <reference path='syntacticCleaner.ts' />
/// <reference path='loggedIO.ts' />
/// <reference path='..\compiler\commandLineParser.ts'/>
module RWC {
class RWCEmitter implements Harness.Compiler.IEmitterIOHost {
public outputs: { [filename: string]: string; } = {};
constructor() { }
writeFile(path: string, contents: string, writeByteOrderMark: boolean) {
if (path in this.outputs) throw new Error('Emitter attempted to write to "' + path + '" twice');
this.outputs[path] = contents;
}
directoryExists(s: string) {
return false;
}
fileExists(s: string) {
return true;
}
resolvePath(s: string) {
return s;
}
}
function runWithIOLog(ioLog: IOLog, fn: () => void) {
var oldSys = sys;
var wrappedSys = Playback.wrapSystem(sys);
wrappedSys.startReplayFromData(ioLog);
sys = wrappedSys;
try {
fn();
} finally {
wrappedSys.endReplay();
sys = oldSys;
}
}
function collateOutputs(emitterIOHost: RWCEmitter, fnTest: (s: string) => {}, clean?: (s: string) => string) {
// Collect, test, and sort the filenames
var files: string[] = [];
for (var fn in emitterIOHost.outputs) {
if (emitterIOHost.outputs.hasOwnProperty(fn) && fnTest(fn)) {
files.push(fn);
}
}
function cleanName(fn: string) {
var lastSlash = Harness.Path.switchToForwardSlashes(fn).lastIndexOf('/');
return fn.substr(lastSlash + 1).toLowerCase();
}
files.sort((a, b) => cleanName(a).localeCompare(cleanName(b)));
// Emit them
var result = '';
files.forEach(fn => {
// Some extra spacing if this isn't the first file
if (result.length) result = result + '\r\n\r\n';
// Filename header + content
result = result + '/*====== ' + fn + ' ======*/\r\n';
if (clean) {
result = result + clean(emitterIOHost.outputs[fn]);
} else {
result = result + emitterIOHost.outputs[fn];
}
});
return result;
}
export function runRWCTest(jsonPath: string) {
var harnessCompiler = Harness.Compiler.getCompiler();
var opts: ts.ParsedCommandLine;
var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
var errors = '';
it('has parsable options', () => {
runWithIOLog(ioLog, () => {
opts = ts.parseCommandLine(ioLog.arguments);
assert.equal(opts.errors.length, 0);
});
});
var emitterIOHost = new RWCEmitter();
it('can compile', () => {
runWithIOLog(ioLog, () => {
harnessCompiler.reset();
var inputList: string[] = opts.filenames;
var noDefaultLib = false;
var libPath = Harness.IO.directoryName(sys.getExecutingFilePath()) + '/lib.d.ts';
if (!opts.options.noResolve) {
var filemap: any = {};
var host: ts.CompilerHost = {
getCurrentDirectory: () => sys.getCurrentDirectory(),
getCancellationToken: (): any => undefined,
getSourceFile: (fileName, languageVersion) => {
var fileContents: string;
try {
fileContents = sys.readFile(fileName);
}
catch (e) {
// Leave fileContents undefined;
}
return ts.createSourceFile(fileName, fileContents, languageVersion);
},
getDefaultLibFilename: () => libPath,
writeFile: (fn, contents) => emitterIOHost.writeFile(fn, contents, false),
getCanonicalFileName: getCanonicalFileName,
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames
};
var resolvedProgram = ts.createProgram(opts.filenames, opts.options, host);
resolvedProgram.getSourceFiles().forEach(sourceFile => {
noDefaultLib = noDefaultLib || sourceFile.hasNoDefaultLib;
if (inputList.indexOf(sourceFile.filename) === -1) {
inputList.push(sourceFile.filename);
}
});
}
if (!opts.options.noLib && !noDefaultLib) {
inputList.push(libPath);
}
harnessCompiler.reset();
harnessCompiler.setCompilerSettingsFromOptions(opts.options);
// Load the files
inputList.forEach((item: string) => {
var resolvedPath = Harness.Path.switchToForwardSlashes(sys.resolvePath(item));
try {
var content = sys.readFile(resolvedPath);
}
catch (e) {
// Leave content undefined.
}
harnessCompiler.addInputFile({ unitName: resolvedPath, content: content });
});
harnessCompiler.compile();
// Emit the results
harnessCompiler.emitAll(emitterIOHost);
harnessCompiler.emitAllDeclarations();
var compilationErrors = harnessCompiler.reportCompilationErrors();
// Create an error baseline
compilationErrors.forEach(err => {
errors += err.filename + ' line ' + err.line + ': ' + err.message + '\r\n';
});
});
});
// Baselines
var baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc' };
var baseName = /(.*)\/(.*).json/.exec(Harness.Path.switchToForwardSlashes(jsonPath))[2];
it('has the expected emitted code', () => {
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
return collateOutputs(emitterIOHost, fn => fn.substr(fn.length - '.js'.length) === '.js', s => SyntacticCleaner.clean(s));
}, false, baselineOpts);
});
it('has the expected declaration file content', () => {
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
var result = collateOutputs(emitterIOHost, fn => fn.substr(fn.length - '.d.ts'.length) === '.d.ts');
return result.length > 0 ? result : null;
}, false, baselineOpts);
});
/*
it('has the expected source maps', () => {
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
var result = collateOutputs(emitterIOHost, fn => fn.substr(fn.length - '.map'.length) === '.map');
return result.length > 0 ? result : null;
}, false, baselineOpts);
});
*/
it('has the expected errors', () => {
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
return errors.length > 0 ? errors : null;
}, false, baselineOpts);
});
// TODO: Type baselines (need to refactor out from compilerRunner)
}
}
class RWCRunner extends RunnerBase {
private runnerPath = "tests/runners/rwc";
private sourcePath = "tests/cases/rwc/";
private harnessCompiler: Harness.Compiler.HarnessCompiler;
/** Setup the runner's tests so that they are ready to be executed by the harness
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
*/
public initializeTests(): void {
// Recreate the compiler with the default lib
Harness.Compiler.recreate({ useMinimalDefaultLib: false, noImplicitAny: false });
this.harnessCompiler = Harness.Compiler.getCompiler();
// Read in and evaluate the test list
var testList = Harness.IO.listFiles(this.sourcePath, /.+\.json$/);
for (var i = 0; i < testList.length; i++) {
this.runTest(testList[i]);
}
}
private runTest(jsonFilename: string) {
describe("Testing a RWC project: " + jsonFilename, () => {
RWC.runRWCTest(jsonFilename);
});
}
}

View File

@ -0,0 +1,460 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///<reference path='harness.ts'/>
module Harness.SourceMapRecoder {
interface SourceMapSpanWithDecodeErrors {
sourceMapSpan: ts.SourceMapSpan;
decodeErrors: string[];
}
module SourceMapDecoder {
var sourceMapMappings: string;
var sourceMapNames: string[];
var decodingIndex: number;
var prevNameIndex: number;
var decodeOfEncodedMapping: ts.SourceMapSpan;
var errorDecodeOfEncodedMapping: string;
export function initializeSourceMapDecoding(sourceMapData: ts.SourceMapData) {
sourceMapMappings = sourceMapData.sourceMapMappings;
sourceMapNames = sourceMapData.sourceMapNames;
decodingIndex = 0;
prevNameIndex = 0;
decodeOfEncodedMapping = {
emittedLine: 1,
emittedColumn: 1,
sourceLine: 1,
sourceColumn: 1,
sourceIndex: 0,
};
errorDecodeOfEncodedMapping = undefined;
}
function isSourceMappingSegmentEnd() {
if (decodingIndex == sourceMapMappings.length) {
return true;
}
if (sourceMapMappings.charAt(decodingIndex) == ',') {
return true;
}
if (sourceMapMappings.charAt(decodingIndex) == ';') {
return true;
}
return false;
}
export function decodeNextEncodedSourceMapSpan() {
errorDecodeOfEncodedMapping = undefined;
function createErrorIfCondition(condition: boolean, errormsg: string) {
if (errorDecodeOfEncodedMapping) {
// there was existing error:
return true;
}
if (condition) {
errorDecodeOfEncodedMapping = errormsg;
}
return condition;
}
function base64VLQFormatDecode() {
function base64FormatDecode() {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(sourceMapMappings.charAt(decodingIndex));
}
var moreDigits = true;
var shiftCount = 0;
var value = 0;
for (; moreDigits; decodingIndex++) {
if (createErrorIfCondition(decodingIndex >= sourceMapMappings.length, "Error in decoding base64VLQFormatDecode, past the mapping string")) {
return;
}
// 6 digit number
var currentByte = base64FormatDecode();
// If msb is set, we still have more bits to continue
moreDigits = (currentByte & 32) != 0;
// least significant 5 bits are the next msbs in the final value.
value = value | ((currentByte & 31) << shiftCount);
shiftCount += 5;
}
// Least significant bit if 1 represents negative and rest of the msb is actual absolute value
if ((value & 1) == 0) {
// + number
value = value >> 1;
}
else {
// - number
value = value >> 1;
value = -value;
}
return value;
}
while (decodingIndex < sourceMapMappings.length) {
if (sourceMapMappings.charAt(decodingIndex) == ';') {
// New line
decodeOfEncodedMapping.emittedLine++;
decodeOfEncodedMapping.emittedColumn = 1;
decodingIndex++;
continue;
}
if (sourceMapMappings.charAt(decodingIndex) == ',') {
// Next entry is on same line - no action needed
decodingIndex++;
continue;
}
// Read the current span
// 1. Column offset from prev read jsColumn
decodeOfEncodedMapping.emittedColumn += base64VLQFormatDecode();
// Incorrect emittedColumn dont support this map
if (createErrorIfCondition(decodeOfEncodedMapping.emittedColumn < 1, "Invalid emittedColumn found")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// Dont support reading mappings that dont have information about original source and its line numbers
if (createErrorIfCondition(isSourceMappingSegmentEnd(), "Unsupported Error Format: No entries after emitted column")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// 2. Relative sourceIndex
decodeOfEncodedMapping.sourceIndex += base64VLQFormatDecode();
// Incorrect sourceIndex dont support this map
if (createErrorIfCondition(decodeOfEncodedMapping.sourceIndex < 0, "Invalid sourceIndex found")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// Dont support reading mappings that dont have information about original source span
if (createErrorIfCondition(isSourceMappingSegmentEnd(), "Unsupported Error Format: No entries after sourceIndex")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// 3. Relative sourceLine 0 based
decodeOfEncodedMapping.sourceLine += base64VLQFormatDecode();
// Incorrect sourceLine dont support this map
if (createErrorIfCondition(decodeOfEncodedMapping.sourceLine < 1, "Invalid sourceLine found")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// Dont support reading mappings that dont have information about original source and its line numbers
if (createErrorIfCondition(isSourceMappingSegmentEnd(), "Unsupported Error Format: No entries after emitted Line")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// 4. Relative sourceColumn 0 based
decodeOfEncodedMapping.sourceColumn += base64VLQFormatDecode();
// Incorrect sourceColumn dont support this map
if (createErrorIfCondition(decodeOfEncodedMapping.sourceColumn < 1, "Invalid sourceLine found")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// 5. Check if there is name:
decodeOfEncodedMapping.nameIndex = -1;
if (!isSourceMappingSegmentEnd()) {
prevNameIndex += base64VLQFormatDecode();
decodeOfEncodedMapping.nameIndex = prevNameIndex;
// Incorrect nameIndex dont support this map
if (createErrorIfCondition(decodeOfEncodedMapping.nameIndex < 0 || decodeOfEncodedMapping.nameIndex >= sourceMapNames.length, "Invalid name index for the source map entry")) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
}
// Dont support reading mappings that dont have information about original source and its line numbers
if (createErrorIfCondition(!isSourceMappingSegmentEnd(), "Unsupported Error Format: There are more entries after " + (decodeOfEncodedMapping.nameIndex == -1 ? "sourceColumn" : "nameIndex"))) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
// Populated the entry
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
createErrorIfCondition(true, "No encoded entry found");
}
export function hasCompletedDecoding() {
return decodingIndex === sourceMapMappings.length;
}
export function getRemainingDecodeString() {
return sourceMapMappings.substr(decodingIndex);
}
}
module SourceMapSpanWriter {
var sourceMapRecoder: Compiler.WriterAggregator;
var sourceMapSources: string[];
var sourceMapNames: string[];
var jsFile: Compiler.GeneratedFile;
var jsLineMap: number[];
var tsCode: string;
var tsLineMap: number[];
var spansOnSingleLine: SourceMapSpanWithDecodeErrors[];
var prevWrittenSourcePos: number;
var prevWrittenJsLine: number;
var spanMarkerContinues: boolean;
export function intializeSourceMapSpanWriter(sourceMapRecordWriter: Compiler.WriterAggregator, sourceMapData: ts.SourceMapData, currentJsFile: Compiler.GeneratedFile) {
sourceMapRecoder = sourceMapRecordWriter;
sourceMapSources = sourceMapData.sourceMapSources;
sourceMapNames = sourceMapData.sourceMapNames;
jsFile = currentJsFile;
jsLineMap = ts.getLineStarts(jsFile.code);
spansOnSingleLine = [];
prevWrittenSourcePos = 0;
prevWrittenJsLine = 0;
spanMarkerContinues = false;
SourceMapDecoder.initializeSourceMapDecoding(sourceMapData);
sourceMapRecoder.WriteLine("===================================================================");
sourceMapRecoder.WriteLine("JsFile: " + sourceMapData.sourceMapFile);
sourceMapRecoder.WriteLine("mapUrl: " + sourceMapData.jsSourceMappingURL);
sourceMapRecoder.WriteLine("sourceRoot: " + sourceMapData.sourceMapSourceRoot);
sourceMapRecoder.WriteLine("sources: " + sourceMapData.sourceMapSources);
sourceMapRecoder.WriteLine("===================================================================");
}
function getSourceMapSpanString(mapEntry: ts.SourceMapSpan, getAbsentNameIndex?: boolean) {
var mapString = "Emitted(" + mapEntry.emittedLine + ", " + mapEntry.emittedColumn + ") Source(" + mapEntry.sourceLine + ", " + mapEntry.sourceColumn + ") + SourceIndex(" + mapEntry.sourceIndex + ")";
if (mapEntry.nameIndex >= 0 && mapEntry.nameIndex < sourceMapNames.length) {
mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")";
}
else {
if (mapEntry.nameIndex != -1 || getAbsentNameIndex) {
mapString += " nameIndex (" + mapEntry.nameIndex + ")";
}
}
return mapString;
}
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
// verify the decoded span is same as the new span
var decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
var decodedErrors: string[];
if (decodeResult.error
|| decodeResult.sourceMapSpan.emittedLine != sourceMapSpan.emittedLine
|| decodeResult.sourceMapSpan.emittedColumn != sourceMapSpan.emittedColumn
|| decodeResult.sourceMapSpan.sourceLine != sourceMapSpan.sourceLine
|| decodeResult.sourceMapSpan.sourceColumn != sourceMapSpan.sourceColumn
|| decodeResult.sourceMapSpan.sourceIndex != sourceMapSpan.sourceIndex
|| decodeResult.sourceMapSpan.nameIndex != sourceMapSpan.nameIndex) {
if (decodeResult.error) {
decodedErrors = ["!!^^ !!^^ There was decoding error in the sourcemap at this location: " + decodeResult.error];
}
else {
decodedErrors = ["!!^^ !!^^ The decoded span from sourcemap's mapping entry does not match what was encoded for this span:"];
}
decodedErrors.push("!!^^ !!^^ Decoded span from sourcemap's mappings entry: " + getSourceMapSpanString(decodeResult.sourceMapSpan, /*getAbsentNameIndex*/ true) + " Span encoded by the emitter:" + getSourceMapSpanString(sourceMapSpan, /*getAbsentNameIndex*/ true));
}
if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine) {
// On different line from the one that we have been recording till now,
writeRecordedSpans();
spansOnSingleLine = [{ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors }];
}
else {
spansOnSingleLine.push({ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors });
}
}
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
assert.isTrue(spansOnSingleLine.length == 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
recordSourceMapSpan(sourceMapSpan);
assert.isTrue(spansOnSingleLine.length === 1);
sourceMapRecoder.WriteLine("-------------------------------------------------------------------");
sourceMapRecoder.WriteLine("emittedFile:" + jsFile.fileName);
sourceMapRecoder.WriteLine("sourceFile:" + sourceMapSources[spansOnSingleLine[0].sourceMapSpan.sourceIndex]);
sourceMapRecoder.WriteLine("-------------------------------------------------------------------");
tsLineMap = ts.getLineStarts(newSourceFileCode);
tsCode = newSourceFileCode;
prevWrittenSourcePos = 0;
}
export function close() {
// Write the lines pending on the single line
writeRecordedSpans();
if (!SourceMapDecoder.hasCompletedDecoding()) {
sourceMapRecoder.WriteLine("!!!! **** There are more source map entries in the sourceMap's mapping than what was encoded");
sourceMapRecoder.WriteLine("!!!! **** Remaining decoded string: " + SourceMapDecoder.getRemainingDecodeString());
}
// write remaining js lines
writeJsFileLines(jsLineMap.length);
}
function getTextOfLine(line: number, lineMap: number[], code: string) {
var startPos = lineMap[line];
var endPos = lineMap[line + 1];
return code.substring(startPos, endPos);
}
function writeJsFileLines(endJsLine: number) {
for (; prevWrittenJsLine < endJsLine; prevWrittenJsLine++) {
sourceMapRecoder.Write(">>>" + getTextOfLine(prevWrittenJsLine, jsLineMap, jsFile.code));
}
}
function writeRecordedSpans() {
function getMarkerId(markerIndex: number) {
var markerId = "";
if (spanMarkerContinues) {
assert.isTrue(markerIndex === 0);
markerId = "1->";
}
else {
var markerId = "" + (markerIndex + 1);
if (markerId.length < 2) {
markerId = markerId + " ";
}
markerId += ">";
}
return markerId;
}
var prevEmittedCol: number;
function iterateSpans(fn: (currentSpan: SourceMapSpanWithDecodeErrors, index: number) => void) {
prevEmittedCol = 1;
for (var i = 0; i < spansOnSingleLine.length; i++) {
fn(spansOnSingleLine[i], i);
prevEmittedCol = spansOnSingleLine[i].sourceMapSpan.emittedColumn;
}
}
function writeSourceMapIndent(indentLength: number, indentPrefix: string) {
sourceMapRecoder.Write(indentPrefix);
for (var i = 1; i < indentLength; i++) {
sourceMapRecoder.Write(" ");
}
}
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues?: boolean) {
var markerId = getMarkerId(index);
markerIds.push(markerId);
writeSourceMapIndent(prevEmittedCol, markerId);
for (var i = prevEmittedCol; i < endColumn; i++) {
sourceMapRecoder.Write("^");
}
if (endContinues) {
sourceMapRecoder.Write("->");
}
sourceMapRecoder.WriteLine("");
spanMarkerContinues = endContinues;
}
function writeSourceMapSourceText(currentSpan: SourceMapSpanWithDecodeErrors, index: number) {
var sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1);
var sourceText = "";
if (prevWrittenSourcePos < sourcePos) {
// Position that goes forward, get text
sourceText = tsCode.substring(prevWrittenSourcePos, sourcePos);
}
if (currentSpan.decodeErrors) {
// If there are decode errors, write
for (var i = 0; i < currentSpan.decodeErrors.length; i++) {
writeSourceMapIndent(prevEmittedCol, markerIds[index]);
sourceMapRecoder.WriteLine(currentSpan.decodeErrors[i]);
}
}
var tsCodeLineMap = ts.getLineStarts(sourceText);
for (var i = 0; i < tsCodeLineMap.length; i++) {
writeSourceMapIndent(prevEmittedCol, i == 0 ? markerIds[index] : " >");
sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText));
if (i == tsCodeLineMap.length - 1) {
sourceMapRecoder.WriteLine("");
}
}
prevWrittenSourcePos = sourcePos;
}
function writeSpanDetails(currentSpan: SourceMapSpanWithDecodeErrors, index: number) {
sourceMapRecoder.WriteLine(markerIds[index] + getSourceMapSpanString(currentSpan.sourceMapSpan));
}
if (spansOnSingleLine.length) {
var currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine;
// Write js line
writeJsFileLines(currentJsLine);
// Emit markers
var markerIds: string[] = [];
iterateSpans(writeSourceMapMarker);
var jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code);
if (prevEmittedCol < jsFileText.length) {
// There is remaining text on this line that will be part of next source span so write marker that continues
writeSourceMapMarker(undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
}
// Emit Source text
iterateSpans(writeSourceMapSourceText);
// Emit column number etc
iterateSpans(writeSpanDetails);
sourceMapRecoder.WriteLine("---");
}
}
}
export function getSourceMapRecord(sourceMapDataList: ts.SourceMapData[], program: ts.Program, jsFiles: Compiler.GeneratedFile[]) {
var sourceMapRecoder = new Compiler.WriterAggregator();
for (var i = 0; i < sourceMapDataList.length; i++) {
var sourceMapData = sourceMapDataList[i];
var prevSourceFile: ts.SourceFile = null;
SourceMapSpanWriter.intializeSourceMapSpanWriter(sourceMapRecoder, sourceMapData, jsFiles[i]);
for (var j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
var decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
var currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
if (currentSourceFile != prevSourceFile) {
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
prevSourceFile = currentSourceFile;
}
else {
SourceMapSpanWriter.recordSourceMapSpan(decodedSourceMapping);
}
}
SourceMapSpanWriter.close();// If the last spans werent emitted, emit them
}
sourceMapRecoder.Close();
return sourceMapRecoder.lines.join('\r\n');
}
}

View File

@ -0,0 +1,30 @@
// Use this to get emitter-agnostic baselines
class SyntacticCleaner {
static clean(sourceFileContents: string) {
return sourceFileContents;
}
}
/* TODO: Re-implement or maybe delete
class SyntacticCleaner extends TypeScript.SyntaxWalker {
private emit: string[] = [];
public visitToken(token: TypeScript.ISyntaxToken): void {
this.emit.push(token.text());
if (token.kind() === TypeScript.SyntaxKind.SemicolonToken) {
this.emit.push('\r\n');
} else {
this.emit.push(' ');
}
}
static clean(sourceFileContents: string): string {
var parsed = TypeScript.Parser.parse('_emitted.ts', TypeScript.SimpleText.fromString(sourceFileContents), TypeScript.LanguageVersion.EcmaScript5, false);
var cleaner = new SyntacticCleaner();
cleaner.visitSourceUnit(parsed.sourceUnit());
return cleaner.emit.join('');
}
}
*/

180
src/harness/typeWriter.ts Normal file
View File

@ -0,0 +1,180 @@
/** TODO: Rewrite entirely **/
class TypeWriterWalker {
constructor(public filename: string, public compiler: any) {
}
public run() { }
public results: any[];
}
/*
class TypeWriterWalker extends TypeScript.SyntaxWalker {
private document: TypeScript.Document;
private syntaxTree: TypeScript.SyntaxTree;
private text: TypeScript.ISimpleText;
private currentPosition = 0;
public results: {
line: number;
column: number;
syntaxKind: string;
identifierName: string;
type: string;
}[] = [];
constructor(public filename: string, public compiler: TypeScript.TypeScriptCompiler) {
super();
this.document = compiler.getDocument(filename);
this.syntaxTree = this.document.syntaxTree();
this.text = this.syntaxTree.text;
}
public run() {
TypeScript.visitNodeOrToken(this, this.syntaxTree.sourceUnit());
}
private isName(token: TypeScript.ISyntaxToken) {
var parent = token.parent;
switch (parent.kind()) {
case TypeScript.SyntaxKind.ContinueStatement:
return (<TypeScript.ContinueStatementSyntax>parent).identifier === token;
case TypeScript.SyntaxKind.BreakStatement:
return (<TypeScript.BreakStatementSyntax>parent).identifier === token;
case TypeScript.SyntaxKind.LabeledStatement:
return (<TypeScript.LabeledStatementSyntax>parent).identifier === token;
}
return false;
}
public visitToken(token: TypeScript.ISyntaxToken) {
if (token.kind() === TypeScript.SyntaxKind.IdentifierName) {
if (!this.isName(token)) {
this.log(token);
}
} else if (token.kind() === TypeScript.SyntaxKind.ThisKeyword) {
this.log(token);
}
return super.visitToken(token);
}
public visitNode(node: TypeScript.ISyntaxNode) {
return super.visitNode(node);
}
private getAstForElement(element: TypeScript.ISyntaxElement) {
if (!TypeScript.isShared(element)) {
return element;
}
}
private getEnclosingScopeSymbol(ast: TypeScript.ISyntaxElement): TypeScript.PullSymbol {
var enclosingScopeAST = TypeScript.DeclarationEmitter.getEnclosingContainer(ast);
if (enclosingScopeAST) {
var typeInfo = this.compiler.pullGetSymbolInformationFromAST(enclosingScopeAST, this.document);
return typeInfo ? typeInfo.symbol : null;
}
return null;
}
private getTypeOfElement(element: TypeScript.ISyntaxElement) {
var ast = this.getAstForElement(element);
if (ast) {
var typeInfo = this.compiler.pullGetSymbolInformationFromAST(ast, this.document);
if (typeInfo.symbol && typeInfo.symbol.type) {
var enclosingScope = this.getEnclosingScopeSymbol(ast);
return typeInfo.symbol.type.toString(enclosingScope);
}
}
return "<unknown>";
}
public visitPrefixUnaryExpression(node: TypeScript.PrefixUnaryExpressionSyntax) {
this.log(node);
return super.visitPrefixUnaryExpression(node);
}
public visitArrayLiteralExpression(node: TypeScript.ArrayLiteralExpressionSyntax) {
this.log(node);
return super.visitArrayLiteralExpression(node);
}
public visitOmittedExpression(node: TypeScript.OmittedExpressionSyntax) {
this.log(node);
return super.visitOmittedExpression(node);
}
public visitParenthesizedExpression(node: TypeScript.ParenthesizedExpressionSyntax) {
this.log(node);
return super.visitParenthesizedExpression(node);
}
public visitSimpleArrowFunctionExpression(node: TypeScript.SimpleArrowFunctionExpressionSyntax) {
this.log(node);
return super.visitSimpleArrowFunctionExpression(node);
}
public visitParenthesizedArrowFunctionExpression(node: TypeScript.ParenthesizedArrowFunctionExpressionSyntax) {
this.log(node);
return super.visitParenthesizedArrowFunctionExpression(node);
}
public visitObjectCreationExpression(node: TypeScript.ObjectCreationExpressionSyntax) {
this.log(node);
return super.visitObjectCreationExpression(node);
}
public visitCastExpression(node: TypeScript.CastExpressionSyntax) {
this.log(node);
return super.visitCastExpression(node);
}
public visitObjectLiteralExpression(node: TypeScript.ObjectLiteralExpressionSyntax) {
this.log(node);
return super.visitObjectLiteralExpression(node);
}
public visitFunctionExpression(node: TypeScript.FunctionExpressionSyntax) {
this.log(node);
return super.visitFunctionExpression(node);
}
public visitTypeOfExpression(node: TypeScript.TypeOfExpressionSyntax) {
this.log(node);
return super.visitTypeOfExpression(node);
}
public visitDeleteExpression(node: TypeScript.DeleteExpressionSyntax) {
this.log(node);
return super.visitDeleteExpression(node);
}
public visitVoidExpression(node: TypeScript.VoidExpressionSyntax) {
this.log(node);
return super.visitVoidExpression(node);
}
public visitMemberAccessExpression(node: TypeScript.MemberAccessExpressionSyntax) {
this.log(node);
return super.visitMemberAccessExpression(node);
}
public visitPostfixUnaryExpression(node: TypeScript.PostfixUnaryExpressionSyntax) {
this.log(node);
return super.visitPostfixUnaryExpression(node);
}
public visitElementAccessExpression(node: TypeScript.ElementAccessExpressionSyntax) {
this.log(node);
return super.visitElementAccessExpression(node);
}
public visitInvocationExpression(node: TypeScript.InvocationExpressionSyntax) {
this.log(node);
return super.visitInvocationExpression(node);
}
public visitBinaryExpression(node: TypeScript.BinaryExpressionSyntax) {
this.log(node);
return super.visitBinaryExpression(node);
}
public visitConditionalExpression(node: TypeScript.ConditionalExpressionSyntax) {
this.log(node);
return super.visitConditionalExpression(node);
}
public log(node: TypeScript.ISyntaxNodeOrToken) {
var _fullStart = TypeScript.fullStart(node);
if (_fullStart >= 0) {
var pos = this.document.lineMap().getLineAndCharacterFromPosition(_fullStart);
this.results.push({ line: pos.line(), column: pos.character(), syntaxKind: TypeScript.SyntaxKind[node.kind()], identifierName: TypeScript.fullText(node, this.text).trim(), type: this.getTypeOfElement(node) });
}
}
}
*/

View File

@ -0,0 +1,89 @@
///<reference path="harness.ts" />
///<reference path="runnerbase.ts" />
enum UnittestTestType {
Compiler,
LanguageService,
Services,
}
class UnitTestRunner extends RunnerBase {
constructor(public testType?: UnittestTestType) {
super();
}
public initializeTests() {
switch (this.testType) {
case UnittestTestType.Compiler:
this.tests = this.enumerateFiles('tests/cases/unittests/compiler');
break;
case UnittestTestType.LanguageService:
this.tests = this.enumerateFiles('tests/cases/unittests/ls');
break;
default:
if (this.tests.length === 0) {
throw new Error('Unsupported test cases: ' + this.testType);
}
break;
}
var outfile = new Harness.Compiler.WriterAggregator()
var outerr = new Harness.Compiler.WriterAggregator();
// note this is running immediately to generate tests to be run later inside describe/it
// need a fresh instance so that the previous runner's last test is not hanging around
var harnessCompiler = Harness.Compiler.getCompiler({ useExistingInstance: false });
var toBeAdded = this.tests.map(test => {
return { unitName: test, content: Harness.IO.readFile(test) }
});
harnessCompiler.addInputFiles(toBeAdded);
harnessCompiler.compile({ noResolve: true });
var stdout = new Harness.Compiler.EmitterIOHost();
var emitDiagnostics = harnessCompiler.emitAll(stdout);
var results = stdout.toArray();
var lines: string[] = [];
results.forEach(v => lines = lines.concat(v.file.lines));
var code = lines.join("\n")
var nodeContext: any = undefined;
if (Utils.getExecutionEnvironment() === Utils.ExecutionEnvironment.Node) {
nodeContext = {
require: require,
process: process,
describe: describe,
it: it,
assert: assert,
beforeEach: beforeEach,
afterEach: afterEach,
before: before,
after: after,
Harness: Harness,
IO: Harness.IO
// FourSlash: FourSlash
};
}
describe("Setup compiler for compiler unittests", () => {
// ensures a clean compiler instance when tests are eventually executed following this describe block
harnessCompiler = Harness.Compiler.getCompiler({
useExistingInstance: false,
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
});
});
// this generated code is a series of top level describe/it blocks that will run in between the setup and cleanup blocks in this file
Utils.evalFile(code, "generated_test_code.js", nodeContext);
describe("Cleanup after unittests", () => {
var harnessCompiler = Harness.Compiler.getCompiler({
useExistingInstance: false,
optionsForFreshInstance: { useMinimalDefaultLib: true, noImplicitAny: false }
});
});
// note this runs immediately (ie before this same code in the describe block above)
// to make sure the next runner doesn't include the previous one's stuff
harnessCompiler = Harness.Compiler.getCompiler({ useExistingInstance: false });
}
}

1128
src/lib/core.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

12193
src/lib/dom.generated.d.ts vendored Normal file

File diff suppressed because it is too large Load Diff

818
src/lib/extensions.d.ts vendored Normal file
View File

@ -0,0 +1,818 @@
/////////////////////////////
/// IE10 ECMAScript Extensions
/////////////////////////////
/**
* Represents a raw buffer of binary data, which is used to store data for the
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
* but can be passed to a typed array or DataView Object to interpret the raw
* buffer as needed.
*/
interface ArrayBuffer {
/**
* Read-only. The length of the ArrayBuffer (in bytes).
*/
byteLength: number;
}
declare var ArrayBuffer: {
prototype: ArrayBuffer;
new (byteLength: number): ArrayBuffer;
}
interface ArrayBufferView {
buffer: ArrayBuffer;
byteOffset: number;
byteLength: number;
}
/**
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Int8Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Int8Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Int8Array view of the ArrayBuffer store for this array, referencing the elements at begin, inclusive, up to end, exclusive.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Int8Array;
}
declare var Int8Array: {
prototype: Int8Array;
new (length: number): Int8Array;
new (array: Int8Array): Int8Array;
new (array: number[]): Int8Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int8Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Uint8Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Uint8Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Uint8Array;
}
declare var Uint8Array: {
prototype: Uint8Array;
new (length: number): Uint8Array;
new (array: Uint8Array): Uint8Array;
new (array: number[]): Uint8Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 16-bit integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Int16Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Int16Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Int16Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Int16Array;
}
declare var Int16Array: {
prototype: Int16Array;
new (length: number): Int16Array;
new (array: Int16Array): Int16Array;
new (array: number[]): Int16Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int16Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Uint16Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Uint16Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Uint16Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Uint16Array;
}
declare var Uint16Array: {
prototype: Uint16Array;
new (length: number): Uint16Array;
new (array: Uint16Array): Uint16Array;
new (array: number[]): Uint16Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint16Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 32-bit integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Int32Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Int32Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Int32Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Int32Array;
}
declare var Int32Array: {
prototype: Int32Array;
new (length: number): Int32Array;
new (array: Int32Array): Int32Array;
new (array: number[]): Int32Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int32Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Uint32Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Uint32Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Int8Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Uint32Array;
}
declare var Uint32Array: {
prototype: Uint32Array;
new (length: number): Uint32Array;
new (array: Uint32Array): Uint32Array;
new (array: number[]): Uint32Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint32Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Float32Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Float32Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Float32Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Float32Array;
}
declare var Float32Array: {
prototype: Float32Array;
new (length: number): Float32Array;
new (array: Float32Array): Float32Array;
new (array: number[]): Float32Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float32Array;
BYTES_PER_ELEMENT: number;
}
/**
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
*/
interface Float64Array extends ArrayBufferView {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The length of the array.
*/
length: number;
[index: number]: number;
/**
* Gets the element at the specified index.
* @param index The index at which to get the element of the array.
*/
get(index: number): number;
/**
* Sets a value or an array of values.
* @param index The index of the location to set.
* @param value The value to set.
*/
set(index: number, value: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: Float64Array, offset?: number): void;
/**
* Sets a value or an array of values.
* @param A typed or untyped array of values to set.
* @param offset The index in the current array at which the values are to be written.
*/
set(array: number[], offset?: number): void;
/**
* Gets a new Float64Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
* @param begin The index of the beginning of the array.
* @param end The index of the end of the array.
*/
subarray(begin: number, end?: number): Float64Array;
}
declare var Float64Array: {
prototype: Float64Array;
new (length: number): Float64Array;
new (array: Float64Array): Float64Array;
new (array: number[]): Float64Array;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float64Array;
BYTES_PER_ELEMENT: number;
}
/**
* You can use a DataView object to read and write the different kinds of binary data to any location in the ArrayBuffer.
*/
interface DataView extends ArrayBufferView {
/**
* Gets the Int8 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getInt8(byteOffset: number): number;
/**
* Gets the Uint8 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getUint8(byteOffset: number): number;
/**
* Gets the Int16 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getInt16(byteOffset: number, littleEndian?: boolean): number;
/**
* Gets the Uint16 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getUint16(byteOffset: number, littleEndian?: boolean): number;
/**
* Gets the Int32 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getInt32(byteOffset: number, littleEndian?: boolean): number;
/**
* Gets the Uint32 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getUint32(byteOffset: number, littleEndian?: boolean): number;
/**
* Gets the Float32 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getFloat32(byteOffset: number, littleEndian?: boolean): number;
/**
* Gets the Float64 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
*/
getFloat64(byteOffset: number, littleEndian?: boolean): number;
/**
* Stores an Int8 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
*/
setInt8(byteOffset: number, value: number): void;
/**
* Stores an Uint8 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
*/
setUint8(byteOffset: number, value: number): void;
/**
* Stores an Int16 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
*/
setInt16(byteOffset: number, value: number, littleEndian?: boolean): void;
/**
* Stores an Uint16 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
*/
setUint16(byteOffset: number, value: number, littleEndian?: boolean): void;
/**
* Stores an Int32 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
*/
setInt32(byteOffset: number, value: number, littleEndian?: boolean): void;
/**
* Stores an Uint32 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
*/
setUint32(byteOffset: number, value: number, littleEndian?: boolean): void;
/**
* Stores an Float32 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
*/
setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void;
/**
* Stores an Float64 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
*/
setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void;
}
declare var DataView: {
prototype: DataView;
new (buffer: ArrayBuffer, byteOffset?: number, length?: number): DataView;
}
/////////////////////////////
/// IE11 ECMAScript Extensions
/////////////////////////////
interface Map<K, V> {
clear(): void;
delete(key: K): boolean;
forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
get(key: K): V;
has(key: K): boolean;
set(key: K, value: V): Map<K, V>;
size: number;
}
declare var Map: {
new <K, V>(): Map<K, V>;
}
interface WeakMap<K, V> {
clear(): void;
delete(key: K): boolean;
get(key: K): V;
has(key: K): boolean;
set(key: K, value: V): WeakMap<K, V>;
}
declare var WeakMap: {
new <K, V>(): WeakMap<K, V>;
}
interface Set<T> {
add(value: T): Set<T>;
clear(): void;
delete(value: T): boolean;
forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg?: any): void;
has(value: T): boolean;
size: number;
}
declare var Set: {
new <T>(): Set<T>;
}
declare module Intl {
interface CollatorOptions {
usage?: string;
localeMatcher?: string;
numeric?: boolean;
caseFirst?: string;
sensitivity?: string;
ignorePunctuation?: boolean;
}
interface ResolvedCollatorOptions {
locale: string;
usage: string;
sensitivity: string;
ignorePunctuation: boolean;
collation: string;
caseFirst: string;
numeric: boolean;
}
interface Collator {
compare(x: string, y: string): number;
resolvedOptions(): ResolvedCollatorOptions;
}
var Collator: {
new (locales?: string[], options?: CollatorOptions): Collator;
new (locale?: string, options?: CollatorOptions): Collator;
(locales?: string[], options?: CollatorOptions): Collator;
(locale?: string, options?: CollatorOptions): Collator;
supportedLocalesOf(locales: string[], options?: CollatorOptions): string[];
supportedLocalesOf(locale: string, options?: CollatorOptions): string[];
}
interface NumberFormatOptions {
localeMatcher?: string;
style?: string;
currency?: string;
currencyDisplay?: string;
useGrouping?: boolean;
}
interface ResolvedNumberFormatOptions {
locale: string;
numberingSystem: string;
style: string;
currency?: string;
currencyDisplay?: string;
minimumintegerDigits: number;
minimumFractionDigits: number;
maximumFractionDigits: number;
minimumSignificantDigits?: number;
maximumSignificantDigits?: number;
useGrouping: boolean;
}
interface NumberFormat {
format(value: number): string;
resolvedOptions(): ResolvedNumberFormatOptions;
}
var NumberFormat: {
new (locales?: string[], options?: NumberFormatOptions): Collator;
new (locale?: string, options?: NumberFormatOptions): Collator;
(locales?: string[], options?: NumberFormatOptions): Collator;
(locale?: string, options?: NumberFormatOptions): Collator;
supportedLocalesOf(locales: string[], options?: NumberFormatOptions): string[];
supportedLocalesOf(locale: string, options?: NumberFormatOptions): string[];
}
interface DateTimeFormatOptions {
localeMatcher?: string;
weekday?: string;
era?: string;
year?: string;
month?: string;
day?: string;
hour?: string;
minute?: string;
second?: string;
timeZoneName?: string;
formatMatcher?: string;
hour12: boolean;
}
interface ResolvedDateTimeFormatOptions {
locale: string;
calendar: string;
numberingSystem: string;
timeZone: string;
hour12?: boolean;
weekday?: string;
era?: string;
year?: string;
month?: string;
day?: string;
hour?: string;
minute?: string;
second?: string;
timeZoneName?: string;
}
interface DateTimeFormat {
format(date: number): string;
resolvedOptions(): ResolvedDateTimeFormatOptions;
}
var DateTimeFormat: {
new (locales?: string[], options?: DateTimeFormatOptions): Collator;
new (locale?: string, options?: DateTimeFormatOptions): Collator;
(locales?: string[], options?: DateTimeFormatOptions): Collator;
(locale?: string, options?: DateTimeFormatOptions): Collator;
supportedLocalesOf(locales: string[], options?: DateTimeFormatOptions): string[];
supportedLocalesOf(locale: string, options?: DateTimeFormatOptions): string[];
}
}
interface String {
/**
* Determines whether two strings are equivalent in the current locale.
* @param that String to compare to target string
* @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details.
* @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details.
*/
localeCompare(that: string, locales: string[], options?: Intl.CollatorOptions): number;
/**
* Determines whether two strings are equivalent in the current locale.
* @param that String to compare to target string
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details.
* @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details.
*/
localeCompare(that: string, locale: string, options?: Intl.CollatorOptions): number;
}
interface Number {
/**
* Converts a number to a string by using the current or specified locale.
* @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
* @param options An object that contains one or more properties that specify comparison options.
*/
toLocaleString(locales?: string[], options?: Intl.NumberFormatOptions): string;
/**
* Converts a number to a string by using the current or specified locale.
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
* @param options An object that contains one or more properties that specify comparison options.
*/
toLocaleString(locale?: string, options?: Intl.NumberFormatOptions): string;
}
interface Date {
/**
* Converts a date to a string by using the current or specified locale.
* @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
* @param options An object that contains one or more properties that specify comparison options.
*/
toLocaleString(locales?: string[], options?: Intl.DateTimeFormatOptions): string;
/**
* Converts a date to a string by using the current or specified locale.
* @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
* @param options An object that contains one or more properties that specify comparison options.
*/
toLocaleString(locale?: string, options?: Intl.DateTimeFormatOptions): string;
}

1
src/lib/importcore.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference path="lib.core.d.ts" />

22
src/lib/scriptHost.d.ts vendored Normal file
View File

@ -0,0 +1,22 @@
/////////////////////////////
/// Windows Script Host APIS
/////////////////////////////
declare var ActiveXObject: { new (s: string): any; };
interface ITextWriter {
Write(s: string): void;
WriteLine(s: string): void;
Close(): void;
}
declare var WScript: {
Echo(s: any): void;
StdErr: ITextWriter;
StdOut: ITextWriter;
Arguments: { length: number; Item(n: number): string; };
ScriptFullName: string;
Quit(exitCode?: number): number;
}

803
src/lib/webworker.generated.d.ts vendored Normal file
View File

@ -0,0 +1,803 @@
/////////////////////////////
/// IE Worker APIs
/////////////////////////////
interface Console {
info(message?: any, ...optionalParams: any[]): void;
warn(message?: any, ...optionalParams: any[]): void;
error(message?: any, ...optionalParams: any[]): void;
log(message?: any, ...optionalParams: any[]): void;
profile(reportName?: string): void;
assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
msIsIndependentlyComposed(element: any): boolean;
clear(): void;
dir(value?: any, ...optionalParams: any[]): void;
profileEnd(): void;
count(countTitle?: string): void;
groupEnd(): void;
time(timerName?: string): void;
timeEnd(timerName?: string): void;
trace(): void;
group(groupTitle?: string): void;
dirxml(value: any): void;
debug(message?: string, ...optionalParams: any[]): void;
groupCollapsed(groupTitle?: string): void;
select(element: any): void;
}
declare var Console: {
prototype: Console;
new(): Console;
}
interface NavigatorID {
appVersion: string;
appName: string;
userAgent: string;
platform: string;
product: string;
vendor: string;
}
interface EventTarget {
removeEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
dispatchEvent(evt: Event): boolean;
}
interface MessageEvent extends Event {
source: any;
origin: string;
data: any;
ports: any;
initMessageEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, dataArg: any, originArg: string, lastEventIdArg: string, sourceArg: any): void;
}
declare var MessageEvent: {
prototype: MessageEvent;
new(): MessageEvent;
}
interface XMLHttpRequest extends EventTarget {
responseBody: any;
status: number;
readyState: number;
responseText: string;
responseXML: any;
ontimeout: (ev: Event) => any;
statusText: string;
onreadystatechange: (ev: Event) => any;
timeout: number;
onload: (ev: Event) => any;
response: any;
withCredentials: boolean;
onprogress: (ev: ProgressEvent) => any;
onabort: (ev: any) => any;
responseType: string;
onloadend: (ev: ProgressEvent) => any;
upload: XMLHttpRequestEventTarget;
onerror: (ev: ErrorEvent) => any;
onloadstart: (ev: Event) => any;
msCaching: string;
open(method: string, url: string, async?: boolean, user?: string, password?: string): void;
send(data?: any): void;
abort(): void;
getAllResponseHeaders(): string;
setRequestHeader(header: string, value: string): void;
getResponseHeader(header: string): string;
msCachingEnabled(): boolean;
overrideMimeType(mime: string): void;
LOADING: number;
DONE: number;
UNSENT: number;
OPENED: number;
HEADERS_RECEIVED: number;
addEventListener(type: "timeout", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (ev: any) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var XMLHttpRequest: {
prototype: XMLHttpRequest;
new(): XMLHttpRequest;
LOADING: number;
DONE: number;
UNSENT: number;
OPENED: number;
HEADERS_RECEIVED: number;
create(): XMLHttpRequest;
}
interface EventListener {
(evt: Event): void;
}
interface EventException {
code: number;
message: string;
name: string;
toString(): string;
DISPATCH_REQUEST_ERR: number;
UNSPECIFIED_EVENT_TYPE_ERR: number;
}
declare var EventException: {
prototype: EventException;
new(): EventException;
DISPATCH_REQUEST_ERR: number;
UNSPECIFIED_EVENT_TYPE_ERR: number;
}
interface NavigatorOnLine {
onLine: boolean;
}
interface Event {
timeStamp: number;
defaultPrevented: boolean;
isTrusted: boolean;
currentTarget: EventTarget;
cancelBubble: boolean;
target: EventTarget;
eventPhase: number;
cancelable: boolean;
type: string;
srcElement: any;
bubbles: boolean;
initEvent(eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean): void;
stopPropagation(): void;
stopImmediatePropagation(): void;
preventDefault(): void;
CAPTURING_PHASE: number;
AT_TARGET: number;
BUBBLING_PHASE: number;
}
declare var Event: {
prototype: Event;
new(): Event;
CAPTURING_PHASE: number;
AT_TARGET: number;
BUBBLING_PHASE: number;
}
interface ImageData {
width: number;
data: number[];
height: number;
}
declare var ImageData: {
prototype: ImageData;
new(): ImageData;
}
interface DOMException {
code: number;
message: string;
name: string;
toString(): string;
HIERARCHY_REQUEST_ERR: number;
NO_MODIFICATION_ALLOWED_ERR: number;
INVALID_MODIFICATION_ERR: number;
NAMESPACE_ERR: number;
INVALID_CHARACTER_ERR: number;
TYPE_MISMATCH_ERR: number;
ABORT_ERR: number;
INVALID_STATE_ERR: number;
SECURITY_ERR: number;
NETWORK_ERR: number;
WRONG_DOCUMENT_ERR: number;
QUOTA_EXCEEDED_ERR: number;
INDEX_SIZE_ERR: number;
DOMSTRING_SIZE_ERR: number;
SYNTAX_ERR: number;
SERIALIZE_ERR: number;
VALIDATION_ERR: number;
NOT_FOUND_ERR: number;
URL_MISMATCH_ERR: number;
PARSE_ERR: number;
NO_DATA_ALLOWED_ERR: number;
NOT_SUPPORTED_ERR: number;
INVALID_ACCESS_ERR: number;
INUSE_ATTRIBUTE_ERR: number;
INVALID_NODE_TYPE_ERR: number;
DATA_CLONE_ERR: number;
TIMEOUT_ERR: number;
}
declare var DOMException: {
prototype: DOMException;
new(): DOMException;
HIERARCHY_REQUEST_ERR: number;
NO_MODIFICATION_ALLOWED_ERR: number;
INVALID_MODIFICATION_ERR: number;
NAMESPACE_ERR: number;
INVALID_CHARACTER_ERR: number;
TYPE_MISMATCH_ERR: number;
ABORT_ERR: number;
INVALID_STATE_ERR: number;
SECURITY_ERR: number;
NETWORK_ERR: number;
WRONG_DOCUMENT_ERR: number;
QUOTA_EXCEEDED_ERR: number;
INDEX_SIZE_ERR: number;
DOMSTRING_SIZE_ERR: number;
SYNTAX_ERR: number;
SERIALIZE_ERR: number;
VALIDATION_ERR: number;
NOT_FOUND_ERR: number;
URL_MISMATCH_ERR: number;
PARSE_ERR: number;
NO_DATA_ALLOWED_ERR: number;
NOT_SUPPORTED_ERR: number;
INVALID_ACCESS_ERR: number;
INUSE_ATTRIBUTE_ERR: number;
INVALID_NODE_TYPE_ERR: number;
DATA_CLONE_ERR: number;
TIMEOUT_ERR: number;
}
interface ErrorEvent extends Event {
colno: number;
filename: string;
error: any;
lineno: number;
message: string;
initErrorEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, messageArg: string, filenameArg: string, linenoArg: number): void;
}
declare var ErrorEvent: {
prototype: ErrorEvent;
new(): ErrorEvent;
}
interface MSStreamReader extends MSBaseReader {
error: DOMError;
readAsArrayBuffer(stream: MSStream, size?: number): void;
readAsBlob(stream: MSStream, size?: number): void;
readAsDataURL(stream: MSStream, size?: number): void;
readAsText(stream: MSStream, encoding?: string, size?: number): void;
}
declare var MSStreamReader: {
prototype: MSStreamReader;
new(): MSStreamReader;
}
interface MessageChannel {
port2: MessagePort;
port1: MessagePort;
}
declare var MessageChannel: {
prototype: MessageChannel;
new(): MessageChannel;
}
interface DOMError {
name: string;
toString(): string;
}
declare var DOMError: {
prototype: DOMError;
new(): DOMError;
}
interface CloseEvent extends Event {
wasClean: boolean;
reason: string;
code: number;
initCloseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, wasCleanArg: boolean, codeArg: number, reasonArg: string): void;
}
declare var CloseEvent: {
prototype: CloseEvent;
new(): CloseEvent;
}
interface WebSocket extends EventTarget {
protocol: string;
readyState: number;
bufferedAmount: number;
onopen: (ev: Event) => any;
extensions: string;
onmessage: (ev: MessageEvent) => any;
onclose: (ev: CloseEvent) => any;
onerror: (ev: ErrorEvent) => any;
binaryType: string;
url: string;
close(code?: number, reason?: string): void;
send(data: any): void;
OPEN: number;
CLOSING: number;
CONNECTING: number;
CLOSED: number;
addEventListener(type: "open", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener(type: "close", listener: (ev: CloseEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var WebSocket: {
prototype: WebSocket;
new(url: string, protocols?: string): WebSocket;
new(url: string, protocols?: string[]): WebSocket;
OPEN: number;
CLOSING: number;
CONNECTING: number;
CLOSED: number;
}
interface ProgressEvent extends Event {
loaded: number;
lengthComputable: boolean;
total: number;
initProgressEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, lengthComputableArg: boolean, loadedArg: number, totalArg: number): void;
}
declare var ProgressEvent: {
prototype: ProgressEvent;
new(): ProgressEvent;
}
interface IDBObjectStore {
indexNames: DOMStringList;
name: string;
transaction: IDBTransaction;
keyPath: string;
count(key?: any): IDBRequest;
add(value: any, key?: any): IDBRequest;
clear(): IDBRequest;
createIndex(name: string, keyPath: string, optionalParameters?: any): IDBIndex;
put(value: any, key?: any): IDBRequest;
openCursor(range?: any, direction?: string): IDBRequest;
deleteIndex(indexName: string): void;
index(name: string): IDBIndex;
get(key: any): IDBRequest;
delete(key: any): IDBRequest;
}
declare var IDBObjectStore: {
prototype: IDBObjectStore;
new(): IDBObjectStore;
}
interface IDBVersionChangeEvent extends Event {
newVersion: number;
oldVersion: number;
}
declare var IDBVersionChangeEvent: {
prototype: IDBVersionChangeEvent;
new(): IDBVersionChangeEvent;
}
interface IDBIndex {
unique: boolean;
name: string;
keyPath: string;
objectStore: IDBObjectStore;
count(key?: any): IDBRequest;
getKey(key: any): IDBRequest;
openKeyCursor(range?: IDBKeyRange, direction?: string): IDBRequest;
get(key: any): IDBRequest;
openCursor(range?: IDBKeyRange, direction?: string): IDBRequest;
}
declare var IDBIndex: {
prototype: IDBIndex;
new(): IDBIndex;
}
interface FileList {
length: number;
item(index: number): File;
[index: number]: File;
}
declare var FileList: {
prototype: FileList;
new(): FileList;
}
interface IDBCursor {
source: any;
direction: string;
key: any;
primaryKey: any;
advance(count: number): void;
delete(): IDBRequest;
continue(key?: any): void;
update(value: any): IDBRequest;
PREV: string;
PREV_NO_DUPLICATE: string;
NEXT: string;
NEXT_NO_DUPLICATE: string;
}
declare var IDBCursor: {
prototype: IDBCursor;
new(): IDBCursor;
PREV: string;
PREV_NO_DUPLICATE: string;
NEXT: string;
NEXT_NO_DUPLICATE: string;
}
interface File extends Blob {
lastModifiedDate: any;
name: string;
}
declare var File: {
prototype: File;
new(): File;
}
interface IDBCursorWithValue extends IDBCursor {
value: any;
}
declare var IDBCursorWithValue: {
prototype: IDBCursorWithValue;
new(): IDBCursorWithValue;
}
interface XMLHttpRequestEventTarget extends EventTarget {
onprogress: (ev: ProgressEvent) => any;
onerror: (ev: ErrorEvent) => any;
onload: (ev: Event) => any;
ontimeout: (ev: Event) => any;
onabort: (ev: any) => any;
onloadstart: (ev: Event) => any;
onloadend: (ev: ProgressEvent) => any;
addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "timeout", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (ev: any) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var XMLHttpRequestEventTarget: {
prototype: XMLHttpRequestEventTarget;
new(): XMLHttpRequestEventTarget;
}
interface MSBaseReader extends EventTarget {
onprogress: (ev: ProgressEvent) => any;
readyState: number;
onabort: (ev: any) => any;
onloadend: (ev: ProgressEvent) => any;
onerror: (ev: ErrorEvent) => any;
onload: (ev: Event) => any;
onloadstart: (ev: Event) => any;
result: any;
abort(): void;
LOADING: number;
EMPTY: number;
DONE: number;
addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (ev: any) => any, useCapture?: boolean): void;
addEventListener(type: "loadend", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
interface IDBKeyRange {
upper: any;
upperOpen: boolean;
lower: any;
lowerOpen: boolean;
}
declare var IDBKeyRange: {
prototype: IDBKeyRange;
new(): IDBKeyRange;
bound(lower: any, upper: any, lowerOpen?: boolean, upperOpen?: boolean): IDBKeyRange;
only(value: any): IDBKeyRange;
lowerBound(bound: any, open?: boolean): IDBKeyRange;
upperBound(bound: any, open?: boolean): IDBKeyRange;
}
interface WindowConsole {
console: Console;
}
interface IDBTransaction extends EventTarget {
oncomplete: (ev: Event) => any;
db: IDBDatabase;
mode: string;
error: DOMError;
onerror: (ev: ErrorEvent) => any;
onabort: (ev: any) => any;
abort(): void;
objectStore(name: string): IDBObjectStore;
READ_ONLY: string;
VERSION_CHANGE: string;
READ_WRITE: string;
addEventListener(type: "complete", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (ev: any) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var IDBTransaction: {
prototype: IDBTransaction;
new(): IDBTransaction;
READ_ONLY: string;
VERSION_CHANGE: string;
READ_WRITE: string;
}
interface WindowBase64 {
btoa(rawString: string): string;
atob(encodedString: string): string;
}
interface IDBDatabase extends EventTarget {
version: string;
name: string;
objectStoreNames: DOMStringList;
onerror: (ev: ErrorEvent) => any;
onabort: (ev: any) => any;
createObjectStore(name: string, optionalParameters?: any): IDBObjectStore;
close(): void;
transaction(storeNames: any, mode?: string): IDBTransaction;
deleteObjectStore(name: string): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "abort", listener: (ev: any) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var IDBDatabase: {
prototype: IDBDatabase;
new(): IDBDatabase;
}
interface DOMStringList {
length: number;
contains(str: string): boolean;
item(index: number): string;
[index: number]: string;
}
declare var DOMStringList: {
prototype: DOMStringList;
new(): DOMStringList;
}
interface IDBOpenDBRequest extends IDBRequest {
onupgradeneeded: (ev: IDBVersionChangeEvent) => any;
onblocked: (ev: Event) => any;
addEventListener(type: "success", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "upgradeneeded", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
addEventListener(type: "blocked", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var IDBOpenDBRequest: {
prototype: IDBOpenDBRequest;
new(): IDBOpenDBRequest;
}
interface MSUnsafeFunctionCallback {
(): any;
}
interface IDBRequest extends EventTarget {
source: any;
onsuccess: (ev: Event) => any;
error: DOMError;
transaction: IDBTransaction;
onerror: (ev: ErrorEvent) => any;
readyState: string;
result: any;
addEventListener(type: "success", listener: (ev: Event) => any, useCapture?: boolean): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var IDBRequest: {
prototype: IDBRequest;
new(): IDBRequest;
}
interface MessagePort extends EventTarget {
onmessage: (ev: MessageEvent) => any;
close(): void;
postMessage(message?: any, ports?: any): void;
start(): void;
addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var MessagePort: {
prototype: MessagePort;
new(): MessagePort;
}
interface FileReader extends MSBaseReader {
error: DOMError;
readAsArrayBuffer(blob: Blob): void;
readAsDataURL(blob: Blob): void;
readAsText(blob: Blob, encoding?: string): void;
}
declare var FileReader: {
prototype: FileReader;
new(): FileReader;
}
interface Blob {
type: string;
size: number;
msDetachStream(): any;
slice(start?: number, end?: number, contentType?: string): Blob;
msClose(): void;
}
declare var Blob: {
prototype: Blob;
new(): Blob;
}
interface MSStream {
type: string;
msDetachStream(): any;
msClose(): void;
}
declare var MSStream: {
prototype: MSStream;
new(): MSStream;
}
interface MSBlobBuilder {
append(data: any, endings?: string): void;
getBlob(contentType?: string): Blob;
}
declare var MSBlobBuilder: {
prototype: MSBlobBuilder;
new(): MSBlobBuilder;
}
interface IDBFactory {
open(name: string, version?: number): IDBOpenDBRequest;
cmp(first: any, second: any): number;
deleteDatabase(name: string): IDBOpenDBRequest;
}
declare var IDBFactory: {
prototype: IDBFactory;
new(): IDBFactory;
}
interface AbstractWorker extends EventTarget {
onerror: (ev: ErrorEvent) => any;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
interface MSApp {
createFileFromStorageFile(storageFile: any): File;
createBlobFromRandomAccessStream(type: string, seeker: any): Blob;
createStreamFromInputStream(type: string, inputStream: any): MSStream;
terminateApp(exceptionObject: any): void;
createDataPackage(object: any): any;
execUnsafeLocalFunction(unsafeFunction: MSUnsafeFunctionCallback): any;
getHtmlPrintDocumentSource(htmlDoc: any): any;
addPublicLocalApplicationUri(uri: string): void;
createDataPackageFromSelection(): any;
getViewOpener(): MSAppView;
suppressSubdownloadCredentialPrompts(suppress: boolean): void;
execAsyncAtPriority(asynchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): void;
isTaskScheduledAtPriorityOrHigher(priority: string): boolean;
execAtPriority(synchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): any;
createNewView(uri: string): MSAppView;
getCurrentPriority(): string;
NORMAL: string;
HIGH: string;
IDLE: string;
CURRENT: string;
}
declare var MSApp: MSApp;
interface Worker extends AbstractWorker {
onmessage: (ev: MessageEvent) => any;
postMessage(message: any, ports?: any): void;
terminate(): void;
addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
}
declare var Worker: {
prototype: Worker;
new(stringUrl: string): Worker;
}
interface MSExecAtPriorityFunctionCallback {
(...args: any[]): any;
}
interface MSAppView {
viewId: number;
close(): void;
postMessage(message: any, targetOrigin: string, ports?: any): void;
}
declare var MSAppView: {
prototype: MSAppView;
new(): MSAppView;
}
interface WorkerLocation {
hash: string;
protocol: string;
search: string;
href: string;
hostname: string;
port: string;
pathname: string;
host: string;
toString(): string;
}
declare var WorkerLocation: {
prototype: WorkerLocation;
new(): WorkerLocation;
}
interface FileReaderSync {
readAsArrayBuffer(blob: Blob): any;
readAsDataURL(blob: Blob): string;
readAsText(blob: Blob, encoding?: string): string;
}
declare var FileReaderSync: {
prototype: FileReaderSync;
new(): FileReaderSync;
}
interface WorkerGlobalScope extends EventTarget, DedicatedWorkerGlobalScope, WindowConsole, WorkerUtils {
location: WorkerLocation;
self: WorkerGlobalScope;
onerror: (ev: ErrorEvent) => any;
msWriteProfilerMark(profilerMarkName: string): void;
close(): void;
toString(): string;
}
declare var WorkerGlobalScope: {
prototype: WorkerGlobalScope;
new(): WorkerGlobalScope;
}
interface DedicatedWorkerGlobalScope {
onmessage: (ev: MessageEvent) => any;
postMessage(data: any): void;
}
interface WorkerNavigator extends NavigatorID, NavigatorOnLine {
}
declare var WorkerNavigator: {
prototype: WorkerNavigator;
new(): WorkerNavigator;
}
interface WorkerUtils extends WindowBase64 {
navigator: WorkerNavigator;
msIndexedDB: IDBFactory;
indexedDB: IDBFactory;
clearImmediate(handle: number): void;
importScripts(...urls: string[]): void;
clearTimeout(handle: number): void;
setImmediate(handler: any, ...args: any[]): number;
setTimeout(handler: any, timeout?: any, ...args: any[]): number;
clearInterval(handle: number): void;
setInterval(handler: any, timeout?: any, ...args: any[]): number;
}
declare var location: WorkerLocation;
declare var self: WorkerGlobalScope;
declare var onerror: (ev: ErrorEvent) => any;
declare function msWriteProfilerMark(profilerMarkName: string): void;
declare function close(): void;
declare function toString(): string;
declare function removeEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
declare function dispatchEvent(evt: Event): boolean;
declare var onmessage: (ev: MessageEvent) => any;
declare function postMessage(data: any): void;
declare var console: Console;
declare var navigator: WorkerNavigator;
declare var msIndexedDB: IDBFactory;
declare var indexedDB: IDBFactory;
declare function clearImmediate(handle: number): void;
declare function importScripts(...urls: string[]): void;
declare function clearTimeout(handle: number): void;
declare function setImmediate(handler: any, ...args: any[]): number;
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;
declare function clearInterval(handle: number): void;
declare function setInterval(handler: any, timeout?: any, ...args: any[]): number;
declare function btoa(rawString: string): string;
declare function atob(encodedString: string): string;

6
src/lib/webworker.importscripts.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
/////////////////////////////
/// WorkerGlobalScope APIs
/////////////////////////////
// These are only available in a Web Worker
declare function importScripts(...urls: string[]): void;

439
src/services/services.ts Normal file
View File

@ -0,0 +1,439 @@
/// <reference path="..\compiler\types.ts"/>
/// <reference path="..\compiler\core.ts"/>
/// <reference path="..\compiler\scanner.ts"/>
/// <reference path="..\compiler\parser.ts"/>
/// <reference path="..\compiler\checker.ts"/>
module ts {
export interface Node {
getSourceFile(): SourceFile;
getChildCount(): number;
getChildAt(index: number): Node;
getChildren(): Node[];
getFullWidth(): number;
getTriviaWidth(): number;
getFullText(): string;
getFirstToken(): Node;
getLastToken(): Node;
}
export interface Symbol {
getFlags(): SymbolFlags;
getName(): string;
getDeclarations(): Declaration[];
}
export interface Type {
getFlags(): TypeFlags;
getSymbol(): Symbol;
getProperties(): Symbol[];
getCallSignatures(): Signature[];
getConstructSignatures(): Signature[];
getStringIndexType(): Type;
getNumberIndexType(): Type;
}
export interface Signature {
getDeclaration(): SignatureDeclaration;
getTypeParameters(): Type[];
getParameters(): Symbol[];
getReturnType(): Type;
}
interface HostFileInformation {
version: string;
isOpen: boolean;
byteOrderMark: ByteOrderMark;
sourceText?: IScriptSnapshot;
}
//
// Public services of a language service instance associated
// with a language service host instance
//
export interface LanguageService {
getSyntacticDiagnostics(filename: string): Diagnostic[];
getSemanticDiagnostics(filename: string): Diagnostic[];
}
//
// Public interface of the host of a language service instance.
//
export interface LanguageServiceHost {
log(s: string): void;
getCompilationSettings(): CompilerOptions;
getScriptFileNames(): string[];
getScriptVersion(filename: string): string;
getScriptIsOpen(filename: string): boolean;
getScriptByteOrderMark(filename: string): ByteOrderMark;
getScriptSnapshot(filename: string): IScriptSnapshot;
getLocalizedDiagnosticMessages(): any;
//getCancellationToken(): CancellationToken;
}
// Represents an immutable snapshot of a script at a specified time. Once acquired, the
// snapshot is observably immutable. i.e. the same calls with the same parameters will return
// the same values.
export interface IScriptSnapshot {
// Get's a portion of the script snapshot specified by [start, end).
getText(start: number, end: number): string;
// Get's the length of this script snapshot.
getLength(): number;
// This call returns the array containing the start position of every line.
// i.e."[0, 10, 55]". TODO: consider making this optional. The language service could
// always determine this (albeit in a more expensive manner).
getLineStartPositions(): number[];
// Gets the TextChangeRange that describe how the text changed between this text and
// an older version. This informatoin is used by the incremental parser to determine
// what sections of the script need to be reparsed. 'null' can be returned if the
// change range cannot be determined. However, in that case, incremental parsing will
// not happen and the entire document will be reparsed.
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange;
}
export interface Span {
start(): number;
end(): number;
}
export interface TextChange {
span: Span;
newText: string;
}
export interface TextChangeRange {
span(): Span;
newLength(): number;
}
export enum ByteOrderMark {
None = 0,
Utf8 = 1,
Utf16BigEndian = 2,
Utf16LittleEndian = 3,
}
export interface CancellationToken {
isCancellationRequested(): boolean;
}
var scanner: Scanner = createScanner(ScriptTarget.ES5);
var emptyArray: any [] = [];
function createNode(kind: SyntaxKind, pos: number, end: number, flags: NodeFlags, parent?: Node): NodeObject {
var node = <NodeObject> new (getNodeConstructor(kind))();
node.pos = pos;
node.end = end;
node.flags = flags;
node.parent = parent;
return node;
}
class NodeObject implements Node {
public kind: SyntaxKind;
public pos: number;
public end: number;
public flags: NodeFlags;
public parent: Node;
private _children: Node[];
public getSourceFile(): SourceFile {
var node: Node = this;
while (node.kind !== SyntaxKind.SourceFile) node = node.parent;
return <SourceFile>node;
}
public getTextPos(): number {
return getTokenPosOfNode(this);
}
public getFullWidth(): number {
return this.end - this.pos;
}
public getTriviaWidth(): number {
return getTokenPosOfNode(this) - this.pos;
}
public getFullText(): string {
return this.getSourceFile().text.substring(this.pos, this.end);
}
private addSyntheticNodes(nodes: Node[], pos: number, end: number): number {
scanner.setTextPos(pos);
while (pos < end) {
var token = scanner.scan();
var textPos = scanner.getTextPos();
var node = nodes.push(createNode(token, pos, textPos, NodeFlags.Synthetic, this));
pos = textPos;
}
return pos;
}
private createSyntaxList(nodes: NodeArray<Node>): Node {
var list = createNode(SyntaxKind.SyntaxList, nodes.pos, nodes.end, NodeFlags.Synthetic, this);
list._children = [];
var pos = nodes.pos;
for (var i = 0, len = nodes.length; i < len; i++) {
var node = nodes[i];
if (pos < node.pos) {
pos = this.addSyntheticNodes(list._children, pos, node.pos);
}
list._children.push(node);
pos = node.end;
}
if (pos < nodes.end) {
this.addSyntheticNodes(list._children, pos, nodes.end);
}
return list;
}
private createChildren() {
if (this.kind > SyntaxKind.Missing) {
scanner.setText(this.getSourceFile().text);
var children: Node[] = [];
var pos = this.pos;
var processNode = (node: Node) => {
if (pos < node.pos) {
pos = this.addSyntheticNodes(children, pos, node.pos);
}
children.push(node);
pos = node.end;
};
var processNodes = (nodes: NodeArray<Node>) => {
if (pos < nodes.pos) {
pos = this.addSyntheticNodes(children, pos, nodes.pos);
}
children.push(this.createSyntaxList(<NodeArray<Node>>nodes));
pos = nodes.end;
};
forEachChild(this, processNode, processNodes);
if (pos < this.end) {
this.addSyntheticNodes(children, pos, this.end);
}
scanner.setText(undefined);
}
this._children = children || emptyArray;
}
public getChildCount(): number {
if (!this._children) this.createChildren();
return this._children.length;
}
public getChildAt(index: number): Node {
if (!this._children) this.createChildren();
return this._children[index];
}
public getChildren(): Node[] {
if (!this._children) this.createChildren();
return this._children;
}
public getFirstToken(): Node {
var children = this.getChildren();
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.kind < SyntaxKind.Missing) return child;
if (child.kind > SyntaxKind.Missing) return child.getFirstToken();
}
}
public getLastToken(): Node {
var children = this.getChildren();
for (var i = children.length - 1; i >= 0; i--) {
var child = children[i];
if (child.kind < SyntaxKind.Missing) return child;
if (child.kind > SyntaxKind.Missing) return child.getLastToken();
}
}
}
class SymbolObject implements Symbol {
flags: SymbolFlags;
name: string;
declarations: Declaration[];
constructor(flags: SymbolFlags, name: string) {
this.flags = flags;
this.name = name;
}
getFlags(): SymbolFlags {
return this.flags;
}
getName(): string {
return this.name;
}
getDeclarations(): Declaration[] {
return this.declarations;
}
}
class TypeObject implements Type {
checker: TypeChecker;
flags: TypeFlags;
id: number;
symbol: Symbol;
constructor(checker: TypeChecker, flags: TypeFlags) {
this.checker = checker;
this.flags = flags;
}
getFlags(): TypeFlags {
return this.flags;
}
getSymbol(): Symbol {
return this.symbol;
}
getProperties(): Symbol[] {
return this.checker.getPropertiesOfType(this);
}
getCallSignatures(): Signature[] {
return this.checker.getSignaturesOfType(this, SignatureKind.Call);
}
getConstructSignatures(): Signature[] {
return this.checker.getSignaturesOfType(this, SignatureKind.Construct);
}
getStringIndexType(): Type {
return this.checker.getIndexTypeOfType(this, IndexKind.String);
}
getNumberIndexType(): Type {
return this.checker.getIndexTypeOfType(this, IndexKind.Number);
}
}
class SignatureObject implements Signature {
checker: TypeChecker;
declaration: SignatureDeclaration;
typeParameters: TypeParameter[];
parameters: Symbol[];
resolvedReturnType: Type;
minArgumentCount: number;
hasRestParameter: boolean;
hasStringLiterals: boolean;
constructor(checker: TypeChecker) {
this.checker = checker;
}
getDeclaration(): SignatureDeclaration {
return this.declaration;
}
getTypeParameters(): Type[] {
return this.typeParameters;
}
getParameters(): Symbol[] {
return this.parameters;
}
getReturnType(): Type {
return this.checker.getReturnTypeOfSignature(this);
}
}
export function createLanguageService(host: LanguageServiceHost): LanguageService {
var program: Program;
var typeChecker: TypeChecker;
var filesByName: Map<HostFileInformation>;
function createCompilerHost(): CompilerHost {
return {
getSourceFile: (filename, languageVersion) => {
var hostFile = filesByName[filename];
// TODO use the document registry to get or update
if (!hostFile.sourceText) {
hostFile.sourceText = host.getScriptSnapshot(filename);
}
// TODO add support for IScriptSnapshot in the parser
return createSourceFile(filename, hostFile.sourceText.getText(0, hostFile.sourceText.getLength()), languageVersion);
},
// Need something that doesn't depend on sys.ts here
getDefaultLibFilename: () => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), "lib.d.ts"),
getCancellationToken: (): CancellationToken => undefined,
writeFile: (fileName, data) => {
throw Error("TODO: write file");
},
getCurrentDirectory: (): string => {
throw Error("TODO: getCurrentDirectory");
},
getCanonicalFileName: getCanonicalFileName,
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames
};
}
function synchronizeHostData(): void {
// Build the cache
filesByName = {};
var files = host.getScriptFileNames();
forEach(files, (f) => {
filesByName[f] = {
version: host.getScriptVersion(f),
isOpen: host.getScriptIsOpen(f),
byteOrderMark: host.getScriptByteOrderMark(f)
};
});
var currentProgram = program;
var options = host.getCompilationSettings();
// update the program
program = createProgram(files, options, createCompilerHost());
// Update the typeChecker
typeChecker = program.getTypeChecker();
// TODO release old sources from the registry
if (currentProgram) {
}
}
function getSyntacticDiagnostics(filename: string): Diagnostic[] {
synchronizeHostData();
var sourceFile = program.getSourceFile(filename);
return sourceFile ? program.getDiagnostics(sourceFile) : [];
}
function getSemanticDiagnostics(filename: string): Diagnostic[] {
synchronizeHostData();
var sourceFile = program.getSourceFile(filename);
return sourceFile ? typeChecker.getDiagnostics(sourceFile) : [];
}
return {
getSyntacticDiagnostics: getSyntacticDiagnostics,
getSemanticDiagnostics: getSemanticDiagnostics,
};
}
function initializeServices() {
objectAllocator = {
getNodeConstructor: kind => {
function Node() {
}
var proto = new NodeObject();
proto.kind = kind;
proto.pos = 0;
proto.end = 0;
proto.flags = 0;
proto.parent = undefined;
Node.prototype = proto;
return <any>Node;
},
getSymbolConstructor: () => SymbolObject,
getTypeConstructor: () => TypeObject,
getSignatureConstructor: () => SignatureObject,
};
}
initializeServices();
}

145
src/services/shims.ts Normal file
View File

@ -0,0 +1,145 @@
/// <reference path="services.ts"/>
module ts {
export interface LanguageServiceShimHost {
log(s: string): void;
getCompilationSettings(): string;
getScriptFileNames(): string;
getScriptVersion(fileName: string): string;
getScriptIsOpen(fileName: string): boolean;
getScriptByteOrderMark(fileName: string): number;
getScriptSnapshot(fileName: string): ScriptSnapshotShim;
getLocalizedDiagnosticMessages(): string;
// getCancellationToken(): CancellationToken
}
export interface ScriptSnapshotShim {
// Get's a portion of the script snapshot specified by [start, end).
getText(start: number, end: number): string;
// Get's the length of this script snapshot.
getLength(): number;
// This call returns the JSON encoded array of the type:
// number[]
getLineStartPositions(): string;
// Returns a JSON encoded value of the type:
// { span: { start: number; length: number }; newLength: number }
//
// Or null value if there was no change.
getChangeRange(oldSnapshot: ScriptSnapshotShim): string;
}
class ScriptSnapshotShimAdapter implements IScriptSnapshot {
private lineStartPositions: number[] = null;
constructor(private scriptSnapshotShim: ScriptSnapshotShim) {
}
public getText(start: number, end: number): string {
return this.scriptSnapshotShim.getText(start, end);
}
public getLength(): number {
return this.scriptSnapshotShim.getLength();
}
public getLineStartPositions(): number[] {
if (this.lineStartPositions == null) {
this.lineStartPositions = JSON.parse(this.scriptSnapshotShim.getLineStartPositions());
}
return this.lineStartPositions;
}
public getChangeRange(scriptSnapshot: IScriptSnapshot): TextChangeRange {
function createTextRange(start: number, length: number) {
function createSpan(start: number, length: number) {
return {
start: () => start,
end: () => start + length,
lenth: () => length,
isEmpty: () => length === 0
};
}
return {
span: () => createSpan(start, length),
newLength: () => length,
newSpan: () => createSpan(start, length),
isUnchanged: () => length === 0
};
}
var encoded = this.scriptSnapshotShim.getChangeRange((<ScriptSnapshotShimAdapter>scriptSnapshot).scriptSnapshotShim);
if (encoded == null) {
return null;
}
var decoded: { span: { start: number; length: number; }; newLength: number; } = JSON.parse(encoded);
return createTextRange(decoded.span.start, decoded.span.length);
}
}
export class LanguageServiceShimHostAdapter implements LanguageServiceHost {
constructor(private shimHost: LanguageServiceShimHost) {
}
public log(s: string): void {
this.shimHost.log(s);
}
public getCompilationSettings(): CompilerOptions {
var settingsJson = this.shimHost.getCompilationSettings();
if (settingsJson == null || settingsJson == "") {
return {};
}
var settings: CompilerOptions = JSON.parse(<any>settingsJson);
return settings;
}
public getScriptFileNames(): string[] {
var encoded = this.shimHost.getScriptFileNames();
return JSON.parse(encoded);
}
public getScriptSnapshot(fileName: string): IScriptSnapshot {
return new ScriptSnapshotShimAdapter(this.shimHost.getScriptSnapshot(fileName));
}
public getScriptVersion(fileName: string): string {
return this.shimHost.getScriptVersion(fileName);
}
public getScriptIsOpen(fileName: string): boolean {
return this.shimHost.getScriptIsOpen(fileName);
}
public getScriptByteOrderMark(fileName: string): ByteOrderMark {
return this.shimHost.getScriptByteOrderMark(fileName);
}
public getLocalizedDiagnosticMessages(): any {
var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
if (diagnosticMessagesJson == null || diagnosticMessagesJson == "") {
return null;
}
try {
return JSON.parse(diagnosticMessagesJson);
}
catch (e) {
this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
return null;
}
}
//public getCancellationToken(): CancellationToken {
// return this.shimHost.getCancellationToken();
//}
}
}

View File

@ -0,0 +1,38 @@
//// [2dArrays.ts]
class Cell {
}
class Ship {
isSunk: boolean;
}
class Board {
ships: Ship[];
cells: Cell[];
private allShipsSunk() {
return this.ships.every(function (val) { return val.isSunk; });
}
}
//// [2dArrays.js]
var Cell = (function () {
function Cell() {
}
return Cell;
})();
var Ship = (function () {
function Ship() {
}
return Ship;
})();
var Board = (function () {
function Board() {
}
Board.prototype.allShipsSunk = function () {
return this.ships.every(function (val) {
return val.isSunk;
});
};
return Board;
})();

View File

@ -0,0 +1,19 @@
//// [tests/cases/conformance/internalModules/DeclarationMerging/AmbientModuleAndAmbientFunctionWithTheSameNameAndCommonRoot.ts] ////
//// [module.d.ts]
declare module Point {
export var Origin: { x: number; y: number; }
}
//// [function.d.ts]
declare function Point(): { x: number; y: number; }
//// [test.ts]
var cl: { x: number; y: number; }
var cl = Point();
var cl = Point.Origin;
//// [test.js]
var cl;
var cl = Point();
var cl = Point.Origin;

View File

@ -0,0 +1,31 @@
//// [tests/cases/conformance/internalModules/DeclarationMerging/AmbientModuleAndAmbientWithSameNameAndCommonRoot.ts] ////
//// [module.d.ts]
declare module A {
export module Point {
export var Origin: {
x: number;
y: number;
}
}
}
//// [class.d.ts]
declare module A {
export class Point {
constructor(x: number, y: number);
x: number;
y: number;
}
}
//// [test.ts]
var p: { x: number; y: number; }
var p = A.Point.Origin;
var p = new A.Point(0, 0); // unexpected error here, bug 840000
//// [test.js]
var p;
var p = A.Point.Origin;
var p = new A.Point(0, 0);

View File

@ -0,0 +1,40 @@
//// [tests/cases/conformance/internalModules/DeclarationMerging/AmbientModuleAndNonAmbientClassWithSameNameAndCommonRoot.ts] ////
//// [module.d.ts]
declare module A {
export module Point {
export var Origin: {
x: number;
y: number;
}
}
}
//// [classPoint.ts]
module A {
export class Point {
constructor(public x: number, public y: number) { }
}
}
//// [test.ts]
var p: { x: number; y: number; }
var p = A.Point.Origin;
var p = new A.Point(0, 0); // unexpected error here, bug 840000
//// [classPoint.js]
var A;
(function (A) {
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
return Point;
})();
A.Point = Point;
})(A || (A = {}));
//// [test.js]
var p;
var p = A.Point.Origin;
var p = new A.Point(0, 0);

View File

@ -0,0 +1,25 @@
//// [tests/cases/conformance/internalModules/DeclarationMerging/AmbientModuleAndNonAmbientFunctionWithTheSameNameAndCommonRoot.ts] ////
//// [module.d.ts]
declare module Point {
export var Origin: { x: number; y: number; }
}
//// [function.ts]
function Point() {
return { x: 0, y: 0 };
}
//// [test.ts]
var cl: { x: number; y: number; }
var cl = Point();
var cl = Point.Origin;
//// [function.js]
function Point() {
return { x: 0, y: 0 };
}
//// [test.js]
var cl;
var cl = Point();
var cl = Point.Origin;

View File

@ -0,0 +1,4 @@
==== tests/cases/compiler/ArrowFunctionExpression1.ts (1 errors) ====
var v = (public x: string) => { };
~~~~~~~~~~~~~~~~
!!! A parameter property is only allowed in a constructor implementation.

View File

@ -0,0 +1,6 @@
//// [ArrowFunctionExpression1.ts]
var v = (public x: string) => { };
//// [ArrowFunctionExpression1.js]
var v = function (x) {
};

View File

@ -0,0 +1,60 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleThatMergeWithModuleMemberThatUsesClassTypeParameter.ts (5 errors) ====
// all expected to be errors
class clodule1<T>{
id: string;
value: T;
}
module clodule1 {
function f(x: T) { }
~
!!! Cannot find name 'T'.
}
class clodule2<T>{
id: string;
value: T;
}
module clodule2 {
var x: T;
~
!!! Cannot find name 'T'.
class D<U extends T>{
~
!!! Cannot find name 'T'.
id: string;
value: U;
}
}
class clodule3<T>{
id: string;
value: T;
}
module clodule3 {
export var y = { id: T };
~
!!! Cannot find name 'T'.
}
class clodule4<T>{
id: string;
value: T;
}
module clodule4 {
class D {
name: T;
~
!!! Cannot find name 'T'.
}
}

View File

@ -0,0 +1,98 @@
//// [ClassAndModuleThatMergeWithModuleMemberThatUsesClassTypeParameter.ts]
// all expected to be errors
class clodule1<T>{
id: string;
value: T;
}
module clodule1 {
function f(x: T) { }
}
class clodule2<T>{
id: string;
value: T;
}
module clodule2 {
var x: T;
class D<U extends T>{
id: string;
value: U;
}
}
class clodule3<T>{
id: string;
value: T;
}
module clodule3 {
export var y = { id: T };
}
class clodule4<T>{
id: string;
value: T;
}
module clodule4 {
class D {
name: T;
}
}
//// [ClassAndModuleThatMergeWithModuleMemberThatUsesClassTypeParameter.js]
var clodule1 = (function () {
function clodule1() {
}
return clodule1;
})();
var clodule1;
(function (clodule1) {
function f(x) {
}
})(clodule1 || (clodule1 = {}));
var clodule2 = (function () {
function clodule2() {
}
return clodule2;
})();
var clodule2;
(function (clodule2) {
var x;
var D = (function () {
function D() {
}
return D;
})();
})(clodule2 || (clodule2 = {}));
var clodule3 = (function () {
function clodule3() {
}
return clodule3;
})();
var clodule3;
(function (clodule3) {
clodule3.y = { id: T };
})(clodule3 || (clodule3 = {}));
var clodule4 = (function () {
function clodule4() {
}
return clodule4;
})();
var clodule4;
(function (clodule4) {
var D = (function () {
function D() {
}
return D;
})();
})(clodule4 || (clodule4 = {}));

View File

@ -0,0 +1,18 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleThatMergeWithModulesExportedGenericFunctionAndGenericClassStaticFunctionOfTheSameName.ts (1 errors) ====
class clodule<T> {
id: string;
value: T;
static fn<U>(id: U) { }
}
module clodule {
// error: duplicate identifier expected
export function fn<T>(x: T, y: T): T {
~~
!!! Duplicate identifier 'fn'.
return x;
}
}

View File

@ -0,0 +1,32 @@
//// [ClassAndModuleThatMergeWithModulesExportedGenericFunctionAndGenericClassStaticFunctionOfTheSameName.ts]
class clodule<T> {
id: string;
value: T;
static fn<U>(id: U) { }
}
module clodule {
// error: duplicate identifier expected
export function fn<T>(x: T, y: T): T {
return x;
}
}
//// [ClassAndModuleThatMergeWithModulesExportedGenericFunctionAndGenericClassStaticFunctionOfTheSameName.js]
var clodule = (function () {
function clodule() {
}
clodule.fn = function (id) {
};
return clodule;
})();
var clodule;
(function (clodule) {
function fn(x, y) {
return x;
}
clodule.fn = fn;
})(clodule || (clodule = {}));

View File

@ -0,0 +1,18 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleThatMergeWithModulesExportedGenericFunctionAndNonGenericClassStaticFunctionOfTheSameName.ts (1 errors) ====
class clodule<T> {
id: string;
value: T;
static fn(id: string) { }
}
module clodule {
// error: duplicate identifier expected
export function fn<T>(x: T, y: T): T {
~~
!!! Duplicate identifier 'fn'.
return x;
}
}

View File

@ -0,0 +1,32 @@
//// [ClassAndModuleThatMergeWithModulesExportedGenericFunctionAndNonGenericClassStaticFunctionOfTheSameName.ts]
class clodule<T> {
id: string;
value: T;
static fn(id: string) { }
}
module clodule {
// error: duplicate identifier expected
export function fn<T>(x: T, y: T): T {
return x;
}
}
//// [ClassAndModuleThatMergeWithModulesExportedGenericFunctionAndNonGenericClassStaticFunctionOfTheSameName.js]
var clodule = (function () {
function clodule() {
}
clodule.fn = function (id) {
};
return clodule;
})();
var clodule;
(function (clodule) {
function fn(x, y) {
return x;
}
clodule.fn = fn;
})(clodule || (clodule = {}));

View File

@ -0,0 +1,18 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleThatMergeWithModulesExportedStaticFunctionUsingClassPrivateStatics.ts (1 errors) ====
class clodule<T> {
id: string;
value: T;
private static sfn(id: string) { return 42; }
}
module clodule {
// error: duplicate identifier expected
export function fn<T>(x: T, y: T): number {
return clodule.sfn('a');
~~~~~~~~~~~
!!! Property 'clodule.sfn' is inaccessible.
}
}

View File

@ -0,0 +1,33 @@
//// [ClassAndModuleThatMergeWithModulesExportedStaticFunctionUsingClassPrivateStatics.ts]
class clodule<T> {
id: string;
value: T;
private static sfn(id: string) { return 42; }
}
module clodule {
// error: duplicate identifier expected
export function fn<T>(x: T, y: T): number {
return clodule.sfn('a');
}
}
//// [ClassAndModuleThatMergeWithModulesExportedStaticFunctionUsingClassPrivateStatics.js]
var clodule = (function () {
function clodule() {
}
clodule.sfn = function (id) {
return 42;
};
return clodule;
})();
var clodule;
(function (clodule) {
function fn(x, y) {
return clodule.sfn('a');
}
clodule.fn = fn;
})(clodule || (clodule = {}));

View File

@ -0,0 +1,27 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleThatMergeWithStaticFunctionAndExportedFunctionThatShareAName.ts (2 errors) ====
class Point {
constructor(public x: number, public y: number) { }
static Origin(): Point { return { x: 0, y: 0 }; } // unexpected error here bug 840246
}
module Point {
export function Origin() { return null; } //expected duplicate identifier error
~~~~~~
!!! Duplicate identifier 'Origin'.
}
module A {
export class Point {
constructor(public x: number, public y: number) { }
static Origin(): Point { return { x: 0, y: 0 }; } // unexpected error here bug 840246
}
export module Point {
export function Origin() { return ""; }//expected duplicate identifier error
~~~~~~
!!! Duplicate identifier 'Origin'.
}
}

View File

@ -0,0 +1,63 @@
//// [ClassAndModuleThatMergeWithStaticFunctionAndExportedFunctionThatShareAName.ts]
class Point {
constructor(public x: number, public y: number) { }
static Origin(): Point { return { x: 0, y: 0 }; } // unexpected error here bug 840246
}
module Point {
export function Origin() { return null; } //expected duplicate identifier error
}
module A {
export class Point {
constructor(public x: number, public y: number) { }
static Origin(): Point { return { x: 0, y: 0 }; } // unexpected error here bug 840246
}
export module Point {
export function Origin() { return ""; }//expected duplicate identifier error
}
}
//// [ClassAndModuleThatMergeWithStaticFunctionAndExportedFunctionThatShareAName.js]
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = function () {
return { x: 0, y: 0 };
};
return Point;
})();
var Point;
(function (Point) {
function Origin() {
return null;
}
Point.Origin = Origin;
})(Point || (Point = {}));
var A;
(function (A) {
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = function () {
return { x: 0, y: 0 };
};
return Point;
})();
A.Point = Point;
(function (Point) {
function Origin() {
return "";
}
Point.Origin = Origin;
})(A.Point || (A.Point = {}));
var Point = A.Point;
})(A || (A = {}));

View File

@ -0,0 +1,61 @@
//// [ClassAndModuleThatMergeWithStaticFunctionAndNonExportedFunctionThatShareAName.ts]
class Point {
constructor(public x: number, public y: number) { }
static Origin(): Point { return { x: 0, y: 0 }; }
}
module Point {
function Origin() { return ""; }// not an error, since not exported
}
module A {
export class Point {
constructor(public x: number, public y: number) { }
static Origin(): Point { return { x: 0, y: 0 }; }
}
export module Point {
function Origin() { return ""; }// not an error since not exported
}
}
//// [ClassAndModuleThatMergeWithStaticFunctionAndNonExportedFunctionThatShareAName.js]
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = function () {
return { x: 0, y: 0 };
};
return Point;
})();
var Point;
(function (Point) {
function Origin() {
return "";
}
})(Point || (Point = {}));
var A;
(function (A) {
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = function () {
return { x: 0, y: 0 };
};
return Point;
})();
A.Point = Point;
(function (Point) {
function Origin() {
return "";
}
})(A.Point || (A.Point = {}));
var Point = A.Point;
})(A || (A = {}));

View File

@ -0,0 +1,27 @@
==== tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleThatMergeWithStaticVariableAndExportedVarThatShareAName.ts (2 errors) ====
class Point {
constructor(public x: number, public y: number) { }
static Origin: Point = { x: 0, y: 0 };
}
module Point {
export var Origin = ""; //expected duplicate identifier error
~~~~~~
!!! Duplicate identifier 'Origin'.
}
module A {
export class Point {
constructor(public x: number, public y: number) { }
static Origin: Point = { x: 0, y: 0 };
}
export module Point {
export var Origin = ""; //expected duplicate identifier error
~~~~~~
!!! Duplicate identifier 'Origin'.
}
}

View File

@ -0,0 +1,53 @@
//// [ClassAndModuleThatMergeWithStaticVariableAndExportedVarThatShareAName.ts]
class Point {
constructor(public x: number, public y: number) { }
static Origin: Point = { x: 0, y: 0 };
}
module Point {
export var Origin = ""; //expected duplicate identifier error
}
module A {
export class Point {
constructor(public x: number, public y: number) { }
static Origin: Point = { x: 0, y: 0 };
}
export module Point {
export var Origin = ""; //expected duplicate identifier error
}
}
//// [ClassAndModuleThatMergeWithStaticVariableAndExportedVarThatShareAName.js]
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
})();
var Point;
(function (Point) {
Point.Origin = "";
})(Point || (Point = {}));
var A;
(function (A) {
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
})();
A.Point = Point;
(function (Point) {
Point.Origin = "";
})(A.Point || (A.Point = {}));
var Point = A.Point;
})(A || (A = {}));

View File

@ -0,0 +1,53 @@
//// [ClassAndModuleThatMergeWithStaticVariableAndNonExportedVarThatShareAName.ts]
class Point {
constructor(public x: number, public y: number) { }
static Origin: Point = { x: 0, y: 0 };
}
module Point {
var Origin = ""; // not an error, since not exported
}
module A {
export class Point {
constructor(public x: number, public y: number) { }
static Origin: Point = { x: 0, y: 0 };
}
export module Point {
var Origin = ""; // not an error since not exported
}
}
//// [ClassAndModuleThatMergeWithStaticVariableAndNonExportedVarThatShareAName.js]
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
})();
var Point;
(function (Point) {
var Origin = "";
})(Point || (Point = {}));
var A;
(function (A) {
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
})();
A.Point = Point;
(function (Point) {
var Origin = "";
})(A.Point || (A.Point = {}));
var Point = A.Point;
})(A || (A = {}));

View File

@ -0,0 +1,4 @@
//// [ClassAndModuleThatMergeWithStringIndexerAndExportedFunctionWithTypeIncompatibleWithIndexer.ts]
//// [ClassAndModuleThatMergeWithStringIndexerAndExportedFunctionWithTypeIncompatibleWithIndexer.js]

View File

@ -0,0 +1,84 @@
//// [tests/cases/conformance/internalModules/DeclarationMerging/ClassAndModuleWithSameNameAndCommonRoot.ts] ////
//// [class.ts]
module X.Y {
export class Point {
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
x: number;
y: number;
}
}
//// [module.ts]
module X.Y {
export module Point {
export var Origin = new Point(0, 0);
}
}
//// [test.ts]
//var cl: { x: number; y: number; }
var cl = new X.Y.Point(1,1);
var cl = X.Y.Point.Origin; // error not expected here same as bug 83996 ?
//// [simple.ts]
class A {
id: string;
}
module A {
export var Instance = new A();
}
// ensure merging works as expected
var a = A.Instance;
var a = new A();
var a: { id: string };
//// [class.js]
var X;
(function (X) {
(function (Y) {
var Point = (function () {
function Point(x, y) {
this.x = x;
this.y = y;
}
return Point;
})();
Y.Point = Point;
})(X.Y || (X.Y = {}));
var Y = X.Y;
})(X || (X = {}));
//// [module.js]
var X;
(function (X) {
(function (Y) {
(function (Point) {
Point.Origin = new Point(0, 0);
})(Y.Point || (Y.Point = {}));
var Point = Y.Point;
})(X.Y || (X.Y = {}));
var Y = X.Y;
})(X || (X = {}));
//// [test.js]
var cl = new X.Y.Point(1, 1);
var cl = X.Y.Point.Origin;
//// [simple.js]
var A = (function () {
function A() {
}
return A;
})();
var A;
(function (A) {
A.Instance = new A();
})(A || (A = {}));
var a = A.Instance;
var a = new A();
var a;

View File

@ -0,0 +1,9 @@
==== tests/cases/compiler/ClassDeclaration10.ts (2 errors) ====
class C {
constructor();
~~~~~~~~~~~~~~
!!! Constructor implementation expected.
foo();
~~~~~~
!!! Function implementation expected.
}

View File

@ -0,0 +1,12 @@
//// [ClassDeclaration10.ts]
class C {
constructor();
foo();
}
//// [ClassDeclaration10.js]
var C = (function () {
function C() {
}
return C;
})();

View File

@ -0,0 +1,7 @@
==== tests/cases/compiler/ClassDeclaration11.ts (1 errors) ====
class C {
constructor();
~~~~~~~~~~~~~~
!!! Constructor implementation expected.
foo() { }
}

View File

@ -0,0 +1,14 @@
//// [ClassDeclaration11.ts]
class C {
constructor();
foo() { }
}
//// [ClassDeclaration11.js]
var C = (function () {
function C() {
}
C.prototype.foo = function () {
};
return C;
})();

View File

@ -0,0 +1,7 @@
==== tests/cases/compiler/ClassDeclaration13.ts (1 errors) ====
class C {
foo();
~~~~~~
!!! Function implementation expected.
bar() { }
}

View File

@ -0,0 +1,14 @@
//// [ClassDeclaration13.ts]
class C {
foo();
bar() { }
}
//// [ClassDeclaration13.js]
var C = (function () {
function C() {
}
C.prototype.bar = function () {
};
return C;
})();

View File

@ -0,0 +1,9 @@
==== tests/cases/compiler/ClassDeclaration14.ts (2 errors) ====
class C {
foo();
~~~~~~
!!! Function implementation expected.
constructor();
~~~~~~~~~~~~~~
!!! Constructor implementation expected.
}

View File

@ -0,0 +1,12 @@
//// [ClassDeclaration14.ts]
class C {
foo();
constructor();
}
//// [ClassDeclaration14.js]
var C = (function () {
function C() {
}
return C;
})();

View File

@ -0,0 +1,7 @@
==== tests/cases/compiler/ClassDeclaration15.ts (1 errors) ====
class C {
foo();
~~~~~~
!!! Function implementation expected.
constructor() { }
}

View File

@ -0,0 +1,12 @@
//// [ClassDeclaration15.ts]
class C {
foo();
constructor() { }
}
//// [ClassDeclaration15.js]
var C = (function () {
function C() {
}
return C;
})();

View File

@ -0,0 +1,7 @@
==== tests/cases/compiler/ClassDeclaration21.ts (1 errors) ====
class C {
0();
~~~~
!!! Function implementation expected.
1() { }
}

View File

@ -0,0 +1,14 @@
//// [ClassDeclaration21.ts]
class C {
0();
1() { }
}
//// [ClassDeclaration21.js]
var C = (function () {
function C() {
}
C.prototype[1] = function () {
};
return C;
})();

View File

@ -0,0 +1,7 @@
==== tests/cases/compiler/ClassDeclaration22.ts (1 errors) ====
class C {
"foo"();
~~~~~~~~
!!! Function implementation expected.
"bar"() { }
}

View File

@ -0,0 +1,14 @@
//// [ClassDeclaration22.ts]
class C {
"foo"();
"bar"() { }
}
//// [ClassDeclaration22.js]
var C = (function () {
function C() {
}
C.prototype["bar"] = function () {
};
return C;
})();

Some files were not shown because too many files have changed in this diff Show More